From 2d70966f2df551ec1ebd53a6cc5769268d74dc42 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Fri, 14 Jun 2024 10:42:48 +0800 Subject: [PATCH 1/4] [Tizen] Support embedder texture for impeller --- shell/platform/embedder/BUILD.gn | 2 + shell/platform/embedder/embedder.cc | 4 +- shell/platform/embedder/embedder.h | 15 +- .../embedder_external_texture_gl_impeller.cc | 166 ++++++++++++++++++ .../embedder_external_texture_gl_impeller.h | 62 +++++++ .../embedder_external_texture_resolver.cc | 18 +- .../embedder_external_texture_resolver.h | 4 +- 7 files changed, 263 insertions(+), 8 deletions(-) create mode 100755 shell/platform/embedder/embedder_external_texture_gl_impeller.cc create mode 100755 shell/platform/embedder/embedder_external_texture_gl_impeller.h diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index ba7d1276f54a7..c097e3a587d19 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -118,6 +118,8 @@ template("embedder_source_set") { sources += [ "embedder_external_texture_gl.cc", "embedder_external_texture_gl.h", + "embedder_external_texture_gl_impeller.cc", + "embedder_external_texture_gl_impeller.h", "embedder_surface_gl.cc", "embedder_surface_gl.h", ] diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 52e49646c009a..5acf151c9bb02 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2029,8 +2029,8 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, } return texture; }; - external_texture_resolver = - std::make_unique(external_texture_callback); + external_texture_resolver = std::make_unique( + external_texture_callback, settings.enable_impeller); } } #endif diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index d26e2215adf3a..72d07b8571578 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -294,6 +294,7 @@ typedef struct { } FlutterTransformation; typedef void (*VoidCallback)(void* /* user data */); +typedef bool (*BoolCallback)(void* /* user data */); typedef enum { /// Specifies an OpenGL texture target type. Textures are specified using @@ -361,6 +362,11 @@ typedef enum { kFlutterSoftwarePixelFormatNative32, } FlutterSoftwarePixelFormat; +typedef enum { + kFlutterGLImpellerTexturePixelBuffer, + kFlutterGLImpellerTextureGpuSuface, +} FlutterGLImpellerTextureType; + typedef struct { /// Target texture of the active texture unit (example GL_TEXTURE_2D or /// GL_TEXTURE_RECTANGLE). @@ -369,6 +375,14 @@ typedef struct { uint32_t name; /// The texture format (example GL_RGBA8). uint32_t format; + /// The pixel data buffer. + const uint8_t* buffer; + /// The size of buffer. + size_t buffer_size; + /// Callback invoked that texture start binding. + BoolCallback bind_callback; + /// the type of the texture. + FlutterGLImpellerTextureType impeller_texture_type; /// User data to be returned on the invocation of the destruction callback. void* user_data; /// Callback invoked (on an engine managed thread) that asks the embedder to @@ -401,7 +415,6 @@ typedef struct { VoidCallback destruction_callback; } FlutterOpenGLFramebuffer; -typedef bool (*BoolCallback)(void* /* user data */); typedef FlutterTransformation (*TransformationCallback)(void* /* user data */); typedef uint32_t (*UIntCallback)(void* /* user data */); typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */, diff --git a/shell/platform/embedder/embedder_external_texture_gl_impeller.cc b/shell/platform/embedder/embedder_external_texture_gl_impeller.cc new file mode 100755 index 0000000000000..adbc8cc895706 --- /dev/null +++ b/shell/platform/embedder/embedder_external_texture_gl_impeller.cc @@ -0,0 +1,166 @@ +// 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/embedder/embedder_external_texture_gl_impeller.h" + +#include "flutter/fml/logging.h" +#include "flutter/impeller/display_list/dl_image_impeller.h" +#include "flutter/impeller/renderer/backend/gles/context_gles.h" +#include "flutter/impeller/renderer/backend/gles/texture_gles.h" +#include "impeller/aiks/aiks_context.h" +#include "impeller/renderer/backend/gles/gles.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkPaint.h" + +namespace flutter { + +EmbedderExternalTextureGLImpeller::EmbedderExternalTextureGLImpeller( + int64_t texture_identifier, + const ExternalTextureCallback& callback) + : Texture(texture_identifier), external_texture_callback_(callback) { + FML_DCHECK(external_texture_callback_); +} + +EmbedderExternalTextureGLImpeller::~EmbedderExternalTextureGLImpeller() = + default; + +// |flutter::Texture| +void EmbedderExternalTextureGLImpeller::Paint(PaintContext& context, + const SkRect& bounds, + bool freeze, + const DlImageSampling sampling) { + if (last_image_ == nullptr) { + last_image_ = + ResolveTexture(Id(), // + context, // + SkISize::Make(bounds.width(), bounds.height()) // + ); + } + + DlCanvas* canvas = context.canvas; + const DlPaint* paint = context.paint; + + if (last_image_) { + SkRect image_bounds = SkRect::Make(last_image_->bounds()); + if (bounds != image_bounds) { + canvas->DrawImageRect(last_image_, image_bounds, bounds, sampling, paint); + } else { + canvas->DrawImage(last_image_, {bounds.x(), bounds.y()}, sampling, paint); + } + } +} + +// |flutter::Texture| +void EmbedderExternalTextureGLImpeller::OnGrContextCreated() {} + +// |flutter::Texture| +void EmbedderExternalTextureGLImpeller::OnGrContextDestroyed() {} + +// |flutter::Texture| +void EmbedderExternalTextureGLImpeller::MarkNewFrameAvailable() { + last_image_ = nullptr; +} + +// |flutter::Texture| +void EmbedderExternalTextureGLImpeller::OnTextureUnregistered() {} + +sk_sp EmbedderExternalTextureGLImpeller::ResolveTexture( + int64_t texture_id, + PaintContext& context, + const SkISize& size) { + std::unique_ptr texture = + external_texture_callback_(texture_id, size.width(), size.height()); + if (!texture) { + return nullptr; + } + if (texture->impeller_texture_type == + FlutterGLImpellerTextureType::kFlutterGLImpellerTexturePixelBuffer) { + return ResolvePixelBufferTexture(texture.get(), context, size); + } else { + return ResolveGpuSurfaceTexture(texture.get(), context, size); + } +} + +sk_sp EmbedderExternalTextureGLImpeller::ResolvePixelBufferTexture( + FlutterOpenGLTexture* texture, + PaintContext& context, + const SkISize& size) { + size_t width = size.width(); + size_t height = size.height(); + if (texture->width != 0 && texture->height != 0) { + width = texture->width; + height = texture->height; + } + impeller::TextureDescriptor desc; + desc.type = impeller::TextureType::kTexture2D; + + impeller::AiksContext* aiks_context = context.aiks_context; + const auto& gl_context = + impeller::ContextGLES::Cast(*aiks_context->GetContext()); + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + desc.size = {static_cast(width), static_cast(height)}; + desc.mip_count = 1; + + auto textureGLES = + std::make_shared(gl_context.GetReactor(), desc); + if (!textureGLES->SetContents(texture->buffer, texture->buffer_size)) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return nullptr; + } + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return impeller::DlImageImpeller::Make(textureGLES); +} + +sk_sp EmbedderExternalTextureGLImpeller::ResolveGpuSurfaceTexture( + FlutterOpenGLTexture* texture, + PaintContext& context, + const SkISize& size) { + size_t width = size.width(); + size_t height = size.height(); + if (texture->width != 0 && texture->height != 0) { + width = texture->width; + height = texture->height; + } + impeller::TextureDescriptor desc; + desc.type = impeller::TextureType::kTextureExternalOES; + impeller::AiksContext* aiks_context = context.aiks_context; + const auto& gl_context = + impeller::ContextGLES::Cast(*aiks_context->GetContext()); + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + desc.size = {static_cast(texture->width), + static_cast(texture->height)}; + desc.mip_count = 1; + auto textureGLES = std::make_shared( + gl_context.GetReactor(), desc, + impeller::TextureGLES::IsWrapped::kWrapped); + textureGLES->SetCoordinateSystem( + impeller::TextureCoordinateSystem::kUploadFromHost); + if (!textureGLES->Bind()) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return nullptr; + } + + if (!texture->bind_callback(texture->user_data)) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return nullptr; + } + + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + + return impeller::DlImageImpeller::Make(textureGLES); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_external_texture_gl_impeller.h b/shell/platform/embedder/embedder_external_texture_gl_impeller.h new file mode 100755 index 0000000000000..c80028513e9e2 --- /dev/null +++ b/shell/platform/embedder/embedder_external_texture_gl_impeller.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_ + +#include "flutter/common/graphics/texture.h" +#include "flutter/fml/macros.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { + +class EmbedderExternalTextureGLImpeller : public flutter::Texture { + public: + using ExternalTextureCallback = std::function< + std::unique_ptr(int64_t, size_t, size_t)>; + + EmbedderExternalTextureGLImpeller(int64_t texture_identifier, + const ExternalTextureCallback& callback); + + ~EmbedderExternalTextureGLImpeller(); + + private: + const ExternalTextureCallback& external_texture_callback_; + sk_sp last_image_; + + sk_sp ResolveTexture(int64_t texture_id, + PaintContext& context, + const SkISize& size); + sk_sp ResolveGpuSurfaceTexture(FlutterOpenGLTexture* texture, + PaintContext& context, + const SkISize& size); + sk_sp ResolvePixelBufferTexture(FlutterOpenGLTexture* texture, + PaintContext& context, + const SkISize& size); + + // |flutter::Texture| + void Paint(PaintContext& context, + const SkRect& bounds, + bool freeze, + const DlImageSampling sampling) override; + + // |flutter::Texture| + void OnGrContextCreated() override; + + // |flutter::Texture| + void OnGrContextDestroyed() override; + + // |flutter::Texture| + void MarkNewFrameAvailable() override; + + // |flutter::Texture| + void OnTextureUnregistered() override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureGLImpeller); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_ diff --git a/shell/platform/embedder/embedder_external_texture_resolver.cc b/shell/platform/embedder/embedder_external_texture_resolver.cc index 4e4b41b8d4ad2..dca494c9ed0c0 100644 --- a/shell/platform/embedder/embedder_external_texture_resolver.cc +++ b/shell/platform/embedder/embedder_external_texture_resolver.cc @@ -4,6 +4,10 @@ #include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h" +#ifdef SHELL_ENABLE_GL +#include "flutter/shell/platform/embedder/embedder_external_texture_gl_impeller.h" +#endif + #include #include @@ -11,8 +15,9 @@ namespace flutter { #ifdef SHELL_ENABLE_GL EmbedderExternalTextureResolver::EmbedderExternalTextureResolver( - EmbedderExternalTextureGL::ExternalTextureCallback gl_callback) - : gl_callback_(std::move(gl_callback)) {} + EmbedderExternalTextureGL::ExternalTextureCallback gl_callback, + bool enable_impeller) + : gl_callback_(std::move(gl_callback)), enable_impeller_(enable_impeller) {} #endif #ifdef SHELL_ENABLE_METAL @@ -25,8 +30,13 @@ std::unique_ptr EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { #ifdef SHELL_ENABLE_GL if (gl_callback_) { - return std::make_unique(texture_id, - gl_callback_); + if (enable_impeller_) { + return std::make_unique(texture_id, + gl_callback_); + } else { + return std::make_unique(texture_id, + gl_callback_); + } } #endif diff --git a/shell/platform/embedder/embedder_external_texture_resolver.h b/shell/platform/embedder/embedder_external_texture_resolver.h index 412301736e566..da421e2b837a1 100644 --- a/shell/platform/embedder/embedder_external_texture_resolver.h +++ b/shell/platform/embedder/embedder_external_texture_resolver.h @@ -26,7 +26,8 @@ class EmbedderExternalTextureResolver { #ifdef SHELL_ENABLE_GL explicit EmbedderExternalTextureResolver( - EmbedderExternalTextureGL::ExternalTextureCallback gl_callback); + EmbedderExternalTextureGL::ExternalTextureCallback gl_callback, + bool enable_impeller); #endif #ifdef SHELL_ENABLE_METAL @@ -46,6 +47,7 @@ class EmbedderExternalTextureResolver { #ifdef SHELL_ENABLE_METAL EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback_; #endif + bool enable_impeller_ = false; FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureResolver); }; From a8d3cad5ac4e0de2bf8a8245e837d3ba3a234218 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Mon, 17 Jun 2024 21:41:08 +0800 Subject: [PATCH 2/4] Move update size code to ResolveTexture method --- .../embedder_external_texture_gl_impeller.cc | 32 ++++++++----------- .../embedder_external_texture_gl_impeller.h | 12 +++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/shell/platform/embedder/embedder_external_texture_gl_impeller.cc b/shell/platform/embedder/embedder_external_texture_gl_impeller.cc index adbc8cc895706..d5c4a5a677b26 100755 --- a/shell/platform/embedder/embedder_external_texture_gl_impeller.cc +++ b/shell/platform/embedder/embedder_external_texture_gl_impeller.cc @@ -17,7 +17,7 @@ namespace flutter { EmbedderExternalTextureGLImpeller::EmbedderExternalTextureGLImpeller( int64_t texture_identifier, - const ExternalTextureCallback& callback) + const EmbedderExternalTextureGL::ExternalTextureCallback& callback) : Texture(texture_identifier), external_texture_callback_(callback) { FML_DCHECK(external_texture_callback_); } @@ -74,11 +74,19 @@ sk_sp EmbedderExternalTextureGLImpeller::ResolveTexture( if (!texture) { return nullptr; } + size_t width = size.width(); + size_t height = size.height(); + if (texture->width != 0 && texture->height != 0) { + width = texture->width; + height = texture->height; + } if (texture->impeller_texture_type == FlutterGLImpellerTextureType::kFlutterGLImpellerTexturePixelBuffer) { - return ResolvePixelBufferTexture(texture.get(), context, size); + return ResolvePixelBufferTexture(texture.get(), context, + SkISize::Make(width, height)); } else { - return ResolveGpuSurfaceTexture(texture.get(), context, size); + return ResolveGpuSurfaceTexture(texture.get(), context, + SkISize::Make(width, height)); } } @@ -86,21 +94,14 @@ sk_sp EmbedderExternalTextureGLImpeller::ResolvePixelBufferTexture( FlutterOpenGLTexture* texture, PaintContext& context, const SkISize& size) { - size_t width = size.width(); - size_t height = size.height(); - if (texture->width != 0 && texture->height != 0) { - width = texture->width; - height = texture->height; - } impeller::TextureDescriptor desc; desc.type = impeller::TextureType::kTexture2D; - impeller::AiksContext* aiks_context = context.aiks_context; const auto& gl_context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); desc.storage_mode = impeller::StorageMode::kDevicePrivate; desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - desc.size = {static_cast(width), static_cast(height)}; + desc.size = {static_cast(size.width()), static_cast(size.height())}; desc.mip_count = 1; auto textureGLES = @@ -121,12 +122,6 @@ sk_sp EmbedderExternalTextureGLImpeller::ResolveGpuSurfaceTexture( FlutterOpenGLTexture* texture, PaintContext& context, const SkISize& size) { - size_t width = size.width(); - size_t height = size.height(); - if (texture->width != 0 && texture->height != 0) { - width = texture->width; - height = texture->height; - } impeller::TextureDescriptor desc; desc.type = impeller::TextureType::kTextureExternalOES; impeller::AiksContext* aiks_context = context.aiks_context; @@ -134,8 +129,7 @@ sk_sp EmbedderExternalTextureGLImpeller::ResolveGpuSurfaceTexture( impeller::ContextGLES::Cast(*aiks_context->GetContext()); desc.storage_mode = impeller::StorageMode::kDevicePrivate; desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - desc.size = {static_cast(texture->width), - static_cast(texture->height)}; + desc.size = {static_cast(size.width()), static_cast(size.height())}; desc.mip_count = 1; auto textureGLES = std::make_shared( gl_context.GetReactor(), desc, diff --git a/shell/platform/embedder/embedder_external_texture_gl_impeller.h b/shell/platform/embedder/embedder_external_texture_gl_impeller.h index c80028513e9e2..2b2e12d3bc6f6 100755 --- a/shell/platform/embedder/embedder_external_texture_gl_impeller.h +++ b/shell/platform/embedder/embedder_external_texture_gl_impeller.h @@ -8,22 +8,22 @@ #include "flutter/common/graphics/texture.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { class EmbedderExternalTextureGLImpeller : public flutter::Texture { public: - using ExternalTextureCallback = std::function< - std::unique_ptr(int64_t, size_t, size_t)>; - - EmbedderExternalTextureGLImpeller(int64_t texture_identifier, - const ExternalTextureCallback& callback); + EmbedderExternalTextureGLImpeller( + int64_t texture_identifier, + const EmbedderExternalTextureGL::ExternalTextureCallback& callback); ~EmbedderExternalTextureGLImpeller(); private: - const ExternalTextureCallback& external_texture_callback_; + const EmbedderExternalTextureGL::ExternalTextureCallback& + external_texture_callback_; sk_sp last_image_; sk_sp ResolveTexture(int64_t texture_id, From ea8373f4cb5209b65a74f748c71a3ee437e757f0 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Wed, 19 Jun 2024 16:05:03 +0800 Subject: [PATCH 3/4] Fix spelling errors --- shell/platform/embedder/embedder.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 72d07b8571578..117aa714c6f82 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -364,7 +364,7 @@ typedef enum { typedef enum { kFlutterGLImpellerTexturePixelBuffer, - kFlutterGLImpellerTextureGpuSuface, + kFlutterGLImpellerTextureGpuSurface, } FlutterGLImpellerTextureType; typedef struct { @@ -377,11 +377,11 @@ typedef struct { uint32_t format; /// The pixel data buffer. const uint8_t* buffer; - /// The size of buffer. + /// The size of pixel buffer. size_t buffer_size; - /// Callback invoked that texture start binding. + /// Callback invoked that the gpu surface texture start binding. BoolCallback bind_callback; - /// the type of the texture. + /// The type of the texture. FlutterGLImpellerTextureType impeller_texture_type; /// User data to be returned on the invocation of the destruction callback. void* user_data; From f5ed1e012d46c1b4ccffc5eb2c7d4c878eed7488 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Mon, 8 Jul 2024 11:14:51 +0800 Subject: [PATCH 4/4] Add macro definition when creating EmbedderExternalTextureGLImpeller --- shell/platform/embedder/BUILD.gn | 4 ++-- .../embedder/embedder_external_texture_resolver.cc | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index c097e3a587d19..bd6ae97ff8b6f 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -118,14 +118,14 @@ template("embedder_source_set") { sources += [ "embedder_external_texture_gl.cc", "embedder_external_texture_gl.h", - "embedder_external_texture_gl_impeller.cc", - "embedder_external_texture_gl_impeller.h", "embedder_surface_gl.cc", "embedder_surface_gl.h", ] if (impeller_supports_rendering) { sources += [ + "embedder_external_texture_gl_impeller.cc", + "embedder_external_texture_gl_impeller.h", "embedder_surface_gl_impeller.cc", "embedder_surface_gl_impeller.h", ] diff --git a/shell/platform/embedder/embedder_external_texture_resolver.cc b/shell/platform/embedder/embedder_external_texture_resolver.cc index dca494c9ed0c0..bbe83b875d5fd 100644 --- a/shell/platform/embedder/embedder_external_texture_resolver.cc +++ b/shell/platform/embedder/embedder_external_texture_resolver.cc @@ -4,7 +4,7 @@ #include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h" -#ifdef SHELL_ENABLE_GL +#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING) #include "flutter/shell/platform/embedder/embedder_external_texture_gl_impeller.h" #endif @@ -30,13 +30,14 @@ std::unique_ptr EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { #ifdef SHELL_ENABLE_GL if (gl_callback_) { +#ifdef IMPELLER_SUPPORTS_RENDERING if (enable_impeller_) { return std::make_unique(texture_id, gl_callback_); - } else { - return std::make_unique(texture_id, - gl_callback_); } +#endif + return std::make_unique(texture_id, + gl_callback_); } #endif