mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This is part of a larger effort to expose the difference between GrDirectContext, which runs on the GPU thread and can directly perform operations like uploading textures, and GrRecordingContext, which can only queue up work to be delivered to the GrDirectContext later.
175 lines
4.9 KiB
C++
175 lines
4.9 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/android_shell_holder.h"
|
|
#include "flutter/shell/platform/android/jni/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(
|
|
std::shared_ptr<AndroidContext> android_context,
|
|
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
|
|
AndroidSurface::Factory surface_factory)
|
|
: external_view_embedder_(
|
|
std::make_unique<AndroidExternalViewEmbedder>(android_context,
|
|
jni_facade,
|
|
surface_factory)) {
|
|
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(
|
|
GrDirectContext* gr_context) {
|
|
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() {
|
|
if (!AndroidShellHolder::use_embedded_view) {
|
|
return nullptr;
|
|
}
|
|
return external_view_embedder_.get();
|
|
}
|
|
|
|
void AndroidSurfaceSoftware::TeardownOnScreenContext() {}
|
|
|
|
bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) {
|
|
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
|