mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
139a9a799c
Uses the same technique used during OpenGL composition to elide root surface access. The refactoring of this approach is tracked in https://github.com/flutter/flutter/issues/38466 Fixes https://github.com/flutter/flutter/issues/39009.
163 lines
4.4 KiB
C++
163 lines
4.4 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/shell/platform/android/android_surface_software.h"
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "flutter/fml/logging.h"
|
|
#include "flutter/fml/platform/android/jni_weak_ref.h"
|
|
#include "flutter/fml/platform/android/scoped_java_ref.h"
|
|
#include "flutter/fml/trace_event.h"
|
|
#include "flutter/shell/platform/android/platform_view_android_jni.h"
|
|
|
|
namespace flutter {
|
|
|
|
namespace {
|
|
|
|
bool GetSkColorType(int32_t buffer_format,
|
|
SkColorType* color_type,
|
|
SkAlphaType* alpha_type) {
|
|
switch (buffer_format) {
|
|
case WINDOW_FORMAT_RGB_565:
|
|
*color_type = kRGB_565_SkColorType;
|
|
*alpha_type = kOpaque_SkAlphaType;
|
|
return true;
|
|
case WINDOW_FORMAT_RGBA_8888:
|
|
*color_type = kRGBA_8888_SkColorType;
|
|
*alpha_type = kPremul_SkAlphaType;
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
AndroidSurfaceSoftware::AndroidSurfaceSoftware() {
|
|
GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_,
|
|
&target_alpha_type_);
|
|
}
|
|
|
|
AndroidSurfaceSoftware::~AndroidSurfaceSoftware() = default;
|
|
|
|
bool AndroidSurfaceSoftware::IsValid() const {
|
|
return true;
|
|
}
|
|
|
|
bool AndroidSurfaceSoftware::ResourceContextMakeCurrent() {
|
|
// Resource Context always not available on software backend.
|
|
return false;
|
|
}
|
|
|
|
bool AndroidSurfaceSoftware::ResourceContextClearCurrent() {
|
|
return false;
|
|
}
|
|
|
|
std::unique_ptr<Surface> AndroidSurfaceSoftware::CreateGPUSurface() {
|
|
if (!IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
auto surface =
|
|
std::make_unique<GPUSurfaceSoftware>(this, true /* render to surface */);
|
|
|
|
if (!surface->IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return surface;
|
|
}
|
|
|
|
sk_sp<SkSurface> AndroidSurfaceSoftware::AcquireBackingStore(
|
|
const SkISize& size) {
|
|
TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::AcquireBackingStore");
|
|
if (!IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (sk_surface_ != nullptr &&
|
|
SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
|
|
// The old and new surface sizes are the same. Nothing to do here.
|
|
return sk_surface_;
|
|
}
|
|
|
|
SkImageInfo image_info =
|
|
SkImageInfo::Make(size.fWidth, size.fHeight, target_color_type_,
|
|
target_alpha_type_, SkColorSpace::MakeSRGB());
|
|
|
|
sk_surface_ = SkSurface::MakeRaster(image_info);
|
|
|
|
return sk_surface_;
|
|
}
|
|
|
|
bool AndroidSurfaceSoftware::PresentBackingStore(
|
|
sk_sp<SkSurface> backing_store) {
|
|
TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::PresentBackingStore");
|
|
if (!IsValid() || backing_store == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
SkPixmap pixmap;
|
|
if (!backing_store->peekPixels(&pixmap)) {
|
|
return false;
|
|
}
|
|
|
|
ANativeWindow_Buffer native_buffer;
|
|
if (ANativeWindow_lock(native_window_->handle(), &native_buffer, nullptr)) {
|
|
return false;
|
|
}
|
|
|
|
SkColorType color_type;
|
|
SkAlphaType alpha_type;
|
|
if (GetSkColorType(native_buffer.format, &color_type, &alpha_type)) {
|
|
SkImageInfo native_image_info = SkImageInfo::Make(
|
|
native_buffer.width, native_buffer.height, color_type, alpha_type);
|
|
|
|
std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(
|
|
native_image_info, native_buffer.bits,
|
|
native_buffer.stride * SkColorTypeBytesPerPixel(color_type));
|
|
|
|
if (canvas) {
|
|
SkBitmap bitmap;
|
|
if (bitmap.installPixels(pixmap)) {
|
|
canvas->drawBitmapRect(
|
|
bitmap, SkRect::MakeIWH(native_buffer.width, native_buffer.height),
|
|
nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
ANativeWindow_unlockAndPost(native_window_->handle());
|
|
|
|
return true;
|
|
}
|
|
|
|
// |GPUSurfaceSoftwareDelegate|
|
|
ExternalViewEmbedder* AndroidSurfaceSoftware::GetExternalViewEmbedder() {
|
|
return nullptr;
|
|
}
|
|
|
|
void AndroidSurfaceSoftware::TeardownOnScreenContext() {}
|
|
|
|
bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const {
|
|
return true;
|
|
}
|
|
|
|
bool AndroidSurfaceSoftware::SetNativeWindow(
|
|
fml::RefPtr<AndroidNativeWindow> window) {
|
|
native_window_ = std::move(window);
|
|
if (!(native_window_ && native_window_->IsValid()))
|
|
return false;
|
|
int32_t window_format = ANativeWindow_getFormat(native_window_->handle());
|
|
if (window_format < 0)
|
|
return false;
|
|
if (!GetSkColorType(window_format, &target_color_type_, &target_alpha_type_))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
} // namespace flutter
|