From 46afa781e13fffd388f14c023bc9fc6948fed680 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Wed, 7 Jan 2026 19:02:57 +0800 Subject: [PATCH 1/8] Revert flutter offical PR and fix wrong parameter issue --- .../embedder/embedder_external_texture_gl.cc | 82 ++++--------------- .../embedder/embedder_external_texture_gl.h | 8 -- 2 files changed, 15 insertions(+), 75 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index e8d2ad8bd12a3..451770ed8cfec 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -140,73 +140,22 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( return nullptr; } - if (texture->bind_callback != nullptr) { - return ResolveTextureImpellerSurface(aiks_context, std::move(texture)); - } else { - return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture)); - } -} - -sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( - impeller::AiksContext* aiks_context, - std::unique_ptr texture) { impeller::TextureDescriptor desc; desc.size = impeller::ISize(texture->width, texture->height); - desc.type = impeller::TextureType::kTexture2D; desc.storage_mode = impeller::StorageMode::kDevicePrivate; desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - impeller::ContextGLES& context = - impeller::ContextGLES::Cast(*aiks_context->GetContext()); - std::shared_ptr image = - std::make_shared(context.GetReactor(), desc); - - image->MarkContentsInitialized(); - if (!image->SetContents(texture->buffer, texture->buffer_size)) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - return nullptr; - } - - if (!image) { - // In case Skia rejects the image, call the release proc so that - // embedders can perform collection of intermediates. - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - FML_LOG(ERROR) << "Could not create external texture"; - return nullptr; - } - - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); + if (texture->target == GL_TEXTURE_EXTERNAL_OES) { + desc.type = impeller::TextureType::kTextureExternalOES; + } else { + desc.type = impeller::TextureType::kTexture2D; } - return impeller::DlImageImpeller::Make(image); -} - -sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerSurface( - impeller::AiksContext* aiks_context, - std::unique_ptr texture) { - impeller::TextureDescriptor desc; - desc.size = impeller::ISize(texture->width, texture->height); - desc.storage_mode = impeller::StorageMode::kDevicePrivate; - desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - desc.type = impeller::TextureType::kTextureExternalOES; impeller::ContextGLES& context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); + impeller::HandleGLES handle = context.GetReactor()->CreateHandle( + impeller::HandleType::kTexture, texture->name); std::shared_ptr image = - std::make_shared(context.GetReactor(), desc); - image->MarkContentsInitialized(); - image->SetCoordinateSystem( - impeller::TextureCoordinateSystem::kUploadFromHost); - if (!image->Bind()) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - FML_LOG(ERROR) << "Could not bind texture"; - return nullptr; - } + impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle); if (!image) { // In case Skia rejects the image, call the release proc so that @@ -217,18 +166,17 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerSurface( FML_LOG(ERROR) << "Could not create external texture"; return nullptr; } - - if (!texture->bind_callback(texture->user_data)) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } + image->SetCoordinateSystem( + impeller::TextureCoordinateSystem::kUploadFromHost); + if (texture->destruction_callback && + !context.GetReactor()->RegisterCleanupCallback( + handle, + [callback = texture->destruction_callback, + user_data = texture->user_data]() { callback(user_data); })) { + FML_LOG(ERROR) << "Could not register destruction callback"; return nullptr; } - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - return impeller::DlImageImpeller::Make(image); } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index 6ecb6843208d1..7dbc631d56ad1 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -39,14 +39,6 @@ class EmbedderExternalTextureGL : public flutter::Texture { impeller::AiksContext* aiks_context, const SkISize& size); - sk_sp ResolveTextureImpellerPixelbuffer( - impeller::AiksContext* aiks_context, - std::unique_ptr texture); - - sk_sp ResolveTextureImpellerSurface( - impeller::AiksContext* aiks_context, - std::unique_ptr texture); - // |flutter::Texture| void Paint(PaintContext& context, const DlRect& bounds, From 56bc83d7fb9cc30986c9e5fbe610f6b3f7dd7bff Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Thu, 8 Jan 2026 03:28:36 +0800 Subject: [PATCH 2/8] Re-implement resolve texture for impeller The offical PR doesn't work --- .../embedder/embedder_external_texture_gl.cc | 77 ++++++++++++++----- .../embedder/embedder_external_texture_gl.h | 9 ++- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 451770ed8cfec..f85d345c08e38 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -129,35 +129,45 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureSkia( return DlImage::Make(std::move(image)); } -sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( - int64_t texture_id, - impeller::AiksContext* aiks_context, - const SkISize& size) { - std::unique_ptr texture = - external_texture_callback_(texture_id, size.width(), size.height()); +bool EmbedderExternalTextureGL::IsExternalTextureChanged( + FlutterOpenGLTexture* texture) { + if (static_cast(texture->width) != desc_.size.width || + static_cast(texture->height) != desc_.size.height) { + return true; + } + auto handle = texture_image_->GetGLHandle(); + if (!handle.has_value()) { + return true; + } - if (!texture) { - return nullptr; + if (handle.value() != texture->name) { + return true; } + return false; +} - impeller::TextureDescriptor desc; - desc.size = impeller::ISize(texture->width, texture->height); - desc.storage_mode = impeller::StorageMode::kDevicePrivate; - desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; +std::shared_ptr +EmbedderExternalTextureGL::CreateImpellerTexture( + impeller::AiksContext* aiks_context, + FlutterOpenGLTexture* texture) { + desc_.size = impeller::ISize(texture->width, texture->height); + desc_.storage_mode = impeller::StorageMode::kDevicePrivate; + desc_.format = impeller::PixelFormat::kR8G8B8A8UNormInt; if (texture->target == GL_TEXTURE_EXTERNAL_OES) { - desc.type = impeller::TextureType::kTextureExternalOES; + desc_.type = impeller::TextureType::kTextureExternalOES; } else { - desc.type = impeller::TextureType::kTexture2D; + desc_.type = impeller::TextureType::kTexture2D; } impeller::ContextGLES& context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); impeller::HandleGLES handle = context.GetReactor()->CreateHandle( impeller::HandleType::kTexture, texture->name); - std::shared_ptr image = - impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle); - if (!image) { + std::shared_ptr texture_image = + impeller::TextureGLES::WrapTexture(context.GetReactor(), desc_, handle); + + if (!texture_image) { // In case Skia rejects the image, call the release proc so that // embedders can perform collection of intermediates. if (texture->destruction_callback) { @@ -166,8 +176,10 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( FML_LOG(ERROR) << "Could not create external texture"; return nullptr; } - image->SetCoordinateSystem( + + texture_image->SetCoordinateSystem( impeller::TextureCoordinateSystem::kUploadFromHost); + if (texture->destruction_callback && !context.GetReactor()->RegisterCleanupCallback( handle, @@ -177,7 +189,34 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( return nullptr; } - return impeller::DlImageImpeller::Make(image); + return texture_image; +} + +sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( + int64_t texture_id, + impeller::AiksContext* aiks_context, + const SkISize& size) { + std::unique_ptr texture = + external_texture_callback_(texture_id, size.width(), size.height()); + + if (!texture) { + return nullptr; + } + + if (texture_image_ == nullptr) { + texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); + } else { + if (IsExternalTextureChanged(texture.get())) { + texture_image_.reset(); + texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); + } + } + + if (texture_image_ == nullptr) { + return nullptr; + } + + return impeller::DlImageImpeller::Make(texture_image_); } // |flutter::Texture| diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index 7dbc631d56ad1..ccf0d2cdbf00a 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -8,6 +8,7 @@ #include "flutter/common/graphics/texture.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "impeller/renderer/backend/gles/texture_gles.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { @@ -25,7 +26,8 @@ class EmbedderExternalTextureGL : public flutter::Texture { private: const ExternalTextureCallback& external_texture_callback_; sk_sp last_image_; - + std::shared_ptr texture_image_ = nullptr; + impeller::TextureDescriptor desc_; sk_sp ResolveTexture(int64_t texture_id, GrDirectContext* context, impeller::AiksContext* aiks_context, @@ -39,6 +41,11 @@ class EmbedderExternalTextureGL : public flutter::Texture { impeller::AiksContext* aiks_context, const SkISize& size); + bool IsExternalTextureChanged(FlutterOpenGLTexture* texture); + std::shared_ptr CreateImpellerTexture( + impeller::AiksContext* aiks_context, + FlutterOpenGLTexture* texture); + // |flutter::Texture| void Paint(PaintContext& context, const DlRect& bounds, From 4f27663f84f7df102ad29216ed89319640dd9288 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Thu, 8 Jan 2026 17:13:10 +0800 Subject: [PATCH 3/8] Minior refactor 1.Add validation for texture dimensions(width/height > 0) 2.Add validation for texture name. 3.Add datailed error logging. --- .../embedder/embedder_external_texture_gl.cc | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index f85d345c08e38..40bb222627833 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -150,6 +150,18 @@ std::shared_ptr EmbedderExternalTextureGL::CreateImpellerTexture( impeller::AiksContext* aiks_context, FlutterOpenGLTexture* texture) { + // Validate input parameters + if (texture->width <= 0 || texture->height <= 0) { + FML_LOG(ERROR) << "Invalid texture dimensions: " << texture->width << "x" + << texture->height; + return nullptr; + } + + if (texture->name == 0) { + FML_LOG(ERROR) << "Invalid texture name (0)"; + return nullptr; + } + desc_.size = impeller::ISize(texture->width, texture->height); desc_.storage_mode = impeller::StorageMode::kDevicePrivate; desc_.format = impeller::PixelFormat::kR8G8B8A8UNormInt; @@ -173,7 +185,9 @@ EmbedderExternalTextureGL::CreateImpellerTexture( if (texture->destruction_callback) { texture->destruction_callback(texture->user_data); } - FML_LOG(ERROR) << "Could not create external texture"; + FML_LOG(ERROR) << "Could not create external texture with name: " + << texture->name << ", size: " << texture->width << "x" + << texture->height; return nullptr; } @@ -185,7 +199,10 @@ EmbedderExternalTextureGL::CreateImpellerTexture( handle, [callback = texture->destruction_callback, user_data = texture->user_data]() { callback(user_data); })) { - FML_LOG(ERROR) << "Could not register destruction callback"; + FML_LOG(ERROR) << "Could not register destruction callback for texture: " + << texture->name; + // Clean up the texture since we couldn't register the callback + texture_image.reset(); return nullptr; } @@ -200,6 +217,15 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( external_texture_callback_(texture_id, size.width(), size.height()); if (!texture) { + FML_LOG(ERROR) << "External texture callback returned null for texture_id: " + << texture_id; + return nullptr; + } + + // Validate texture parameters + if (size.width() <= 0 || size.height() <= 0) { + FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x" + << size.height(); return nullptr; } @@ -213,6 +239,8 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( } if (texture_image_ == nullptr) { + FML_LOG(ERROR) << "Failed to create Impeller texture for texture_id: " + << texture_id; return nullptr; } From c24f208d5a33a1359c928d4ceb171043a40dd29f Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Thu, 8 Jan 2026 17:32:06 +0800 Subject: [PATCH 4/8] Revert FlutterOpenGLTexture --- engine/src/flutter/shell/platform/embedder/embedder.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 6f5b50ec17fbd..9249f082d30af 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -405,7 +405,6 @@ 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 @@ -513,13 +512,6 @@ 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 pixel buffer. - size_t buffer_size; - /// Callback invoked that the gpu surface texture start binding. - BoolCallback bind_callback; - /// 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 @@ -613,6 +605,7 @@ typedef struct { uint32_t format; } FlutterOpenGLSurface; +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 */, From 76c8de25f05b268a51f53b434d41d21b73f40101 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Fri, 9 Jan 2026 23:29:02 +0800 Subject: [PATCH 5/8] Invoked desturction callback when the texture size not right --- .../shell/platform/embedder/embedder_external_texture_gl.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 40bb222627833..59f37bbee4a04 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -226,6 +226,9 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( if (size.width() <= 0 || size.height() <= 0) { FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x" << size.height(); + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } return nullptr; } From c2cb7975dc4c49e0ac860621951fdd6b3e69113f Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Sat, 10 Jan 2026 03:52:11 +0800 Subject: [PATCH 6/8] Minor refactor 1.Add validateTextureParmeters help method to reduce code dulication. --- .../embedder/embedder_external_texture_gl.cc | 92 ++++++++++--------- .../embedder/embedder_external_texture_gl.h | 7 +- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 59f37bbee4a04..028d4ac4e2749 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -130,11 +130,13 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureSkia( } bool EmbedderExternalTextureGL::IsExternalTextureChanged( - FlutterOpenGLTexture* texture) { - if (static_cast(texture->width) != desc_.size.width || - static_cast(texture->height) != desc_.size.height) { + FlutterOpenGLTexture* texture, + impeller::TextureDescriptor& desc) { + if (static_cast(texture->width) != desc.size.width || + static_cast(texture->height) != desc.size.height) { return true; } + auto handle = texture_image_->GetGLHandle(); if (!handle.has_value()) { return true; @@ -143,6 +145,7 @@ bool EmbedderExternalTextureGL::IsExternalTextureChanged( if (handle.value() != texture->name) { return true; } + return false; } @@ -150,25 +153,14 @@ std::shared_ptr EmbedderExternalTextureGL::CreateImpellerTexture( impeller::AiksContext* aiks_context, FlutterOpenGLTexture* texture) { - // Validate input parameters - if (texture->width <= 0 || texture->height <= 0) { - FML_LOG(ERROR) << "Invalid texture dimensions: " << texture->width << "x" - << texture->height; - return nullptr; - } - - if (texture->name == 0) { - FML_LOG(ERROR) << "Invalid texture name (0)"; - return nullptr; - } - - desc_.size = impeller::ISize(texture->width, texture->height); - desc_.storage_mode = impeller::StorageMode::kDevicePrivate; - desc_.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + impeller::TextureDescriptor desc; + desc.size = impeller::ISize(texture->width, texture->height); + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; if (texture->target == GL_TEXTURE_EXTERNAL_OES) { - desc_.type = impeller::TextureType::kTextureExternalOES; + desc.type = impeller::TextureType::kTextureExternalOES; } else { - desc_.type = impeller::TextureType::kTexture2D; + desc.type = impeller::TextureType::kTexture2D; } impeller::ContextGLES& context = @@ -177,11 +169,9 @@ EmbedderExternalTextureGL::CreateImpellerTexture( impeller::HandleType::kTexture, texture->name); std::shared_ptr texture_image = - impeller::TextureGLES::WrapTexture(context.GetReactor(), desc_, handle); + impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle); if (!texture_image) { - // In case Skia rejects the image, call the release proc so that - // embedders can perform collection of intermediates. if (texture->destruction_callback) { texture->destruction_callback(texture->user_data); } @@ -194,21 +184,45 @@ EmbedderExternalTextureGL::CreateImpellerTexture( texture_image->SetCoordinateSystem( impeller::TextureCoordinateSystem::kUploadFromHost); - if (texture->destruction_callback && - !context.GetReactor()->RegisterCleanupCallback( - handle, - [callback = texture->destruction_callback, - user_data = texture->user_data]() { callback(user_data); })) { - FML_LOG(ERROR) << "Could not register destruction callback for texture: " - << texture->name; - // Clean up the texture since we couldn't register the callback - texture_image.reset(); - return nullptr; + if (texture->destruction_callback) { + if (!context.GetReactor()->RegisterCleanupCallback( + handle, + [callback = texture->destruction_callback, + user_data = texture->user_data]() { callback(user_data); })) { + FML_LOG(ERROR) << "Could not register destruction callback for texture: " + << texture->name; + texture_image.reset(); + return nullptr; + } } + desc_ = desc; return texture_image; } +bool EmbedderExternalTextureGL::ValidateTextureParameters( + FlutterOpenGLTexture* texture, + const SkISize& size) { + if (size.width() <= 0 || size.height() <= 0) { + FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x" + << size.height(); + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return false; + } + + if (texture->name == 0) { + FML_LOG(ERROR) << "Invalid texture name (0)"; + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return false; + } + + return true; +} + sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( int64_t texture_id, impeller::AiksContext* aiks_context, @@ -222,20 +236,14 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( return nullptr; } - // Validate texture parameters - if (size.width() <= 0 || size.height() <= 0) { - FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x" - << size.height(); - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } + if (!ValidateTextureParameters(texture.get(), size)) { return nullptr; } - if (texture_image_ == nullptr) { + if (!texture_image_) { texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); } else { - if (IsExternalTextureChanged(texture.get())) { + if (IsExternalTextureChanged(texture.get(), desc_)) { texture_image_.reset(); texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index ccf0d2cdbf00a..32d347dbf670b 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -41,7 +41,12 @@ class EmbedderExternalTextureGL : public flutter::Texture { impeller::AiksContext* aiks_context, const SkISize& size); - bool IsExternalTextureChanged(FlutterOpenGLTexture* texture); + bool ValidateTextureParameters(FlutterOpenGLTexture* texture, + const SkISize& size); + + bool IsExternalTextureChanged(FlutterOpenGLTexture* texture, + impeller::TextureDescriptor& desc); + std::shared_ptr CreateImpellerTexture( impeller::AiksContext* aiks_context, FlutterOpenGLTexture* texture); From 35e36be20223bc6fb3e65bd00f3eefdc8a3d83d1 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Sat, 10 Jan 2026 04:04:47 +0800 Subject: [PATCH 7/8] Remove desc parameter --- .../platform/embedder/embedder_external_texture_gl.cc | 9 ++++----- .../platform/embedder/embedder_external_texture_gl.h | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 028d4ac4e2749..9f8ef4790e9ef 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -130,10 +130,9 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureSkia( } bool EmbedderExternalTextureGL::IsExternalTextureChanged( - FlutterOpenGLTexture* texture, - impeller::TextureDescriptor& desc) { - if (static_cast(texture->width) != desc.size.width || - static_cast(texture->height) != desc.size.height) { + FlutterOpenGLTexture* texture) { + if (static_cast(texture->width) != desc_.size.width || + static_cast(texture->height) != desc_.size.height) { return true; } @@ -243,7 +242,7 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( if (!texture_image_) { texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); } else { - if (IsExternalTextureChanged(texture.get(), desc_)) { + if (IsExternalTextureChanged(texture.get())) { texture_image_.reset(); texture_image_ = CreateImpellerTexture(aiks_context, texture.get()); } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index 32d347dbf670b..2d50c55755d32 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -44,8 +44,7 @@ class EmbedderExternalTextureGL : public flutter::Texture { bool ValidateTextureParameters(FlutterOpenGLTexture* texture, const SkISize& size); - bool IsExternalTextureChanged(FlutterOpenGLTexture* texture, - impeller::TextureDescriptor& desc); + bool IsExternalTextureChanged(FlutterOpenGLTexture* texture); std::shared_ptr CreateImpellerTexture( impeller::AiksContext* aiks_context, From e3ef7ce56f4c1bb8fe1c94ce40817397e117c39a Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Sat, 10 Jan 2026 04:07:52 +0800 Subject: [PATCH 8/8] Add null check for texture_image_ --- .../shell/platform/embedder/embedder_external_texture_gl.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 9f8ef4790e9ef..e7373063766f9 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -136,6 +136,10 @@ bool EmbedderExternalTextureGL::IsExternalTextureChanged( return true; } + if (!texture_image_) { + return true; + } + auto handle = texture_image_->GetGLHandle(); if (!handle.has_value()) { return true;