-
Notifications
You must be signed in to change notification settings - Fork 2
[Tizen] Re-implemented render external texture gl for impeller to avoid change FlutterOpenGLTexture and use deprecated api #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
46afa78
56bc83d
4f27663
c24f208
76c8de2
c2cb797
35e36be
e3ef7ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,107 +129,122 @@ sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureSkia( | |
| return DlImage::Make(std::move(image)); | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller( | ||
| int64_t texture_id, | ||
| bool EmbedderExternalTextureGL::IsExternalTextureChanged( | ||
| FlutterOpenGLTexture* texture) { | ||
| if (static_cast<int64_t>(texture->width) != desc_.size.width || | ||
| static_cast<int64_t>(texture->height) != desc_.size.height) { | ||
| return true; | ||
| } | ||
| auto handle = texture_image_->GetGLHandle(); | ||
| if (!handle.has_value()) { | ||
| return true; | ||
| } | ||
|
|
||
| if (handle.value() != texture->name) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
Comment on lines
+132
to
+153
|
||
|
|
||
| std::shared_ptr<impeller::TextureGLES> | ||
| EmbedderExternalTextureGL::CreateImpellerTexture( | ||
| impeller::AiksContext* aiks_context, | ||
| const SkISize& size) { | ||
| std::unique_ptr<FlutterOpenGLTexture> texture = | ||
| external_texture_callback_(texture_id, size.width(), size.height()); | ||
| 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; | ||
|
xiaowei-guan marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| if (!texture) { | ||
| if (texture->name == 0) { | ||
| FML_LOG(ERROR) << "Invalid texture name (0)"; | ||
| return nullptr; | ||
| } | ||
|
xiaowei-guan marked this conversation as resolved.
Outdated
|
||
|
|
||
| if (texture->bind_callback != nullptr) { | ||
| return ResolveTextureImpellerSurface(aiks_context, std::move(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; | ||
| } else { | ||
| return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture)); | ||
| desc_.type = impeller::TextureType::kTexture2D; | ||
| } | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( | ||
| impeller::AiksContext* aiks_context, | ||
| std::unique_ptr<FlutterOpenGLTexture> 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<impeller::TextureGLES> image = | ||
| std::make_shared<impeller::TextureGLES>(context.GetReactor(), desc); | ||
| impeller::HandleGLES handle = context.GetReactor()->CreateHandle( | ||
| impeller::HandleType::kTexture, texture->name); | ||
|
|
||
| image->MarkContentsInitialized(); | ||
| if (!image->SetContents(texture->buffer, texture->buffer_size)) { | ||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| } | ||
| return nullptr; | ||
| } | ||
| std::shared_ptr<impeller::TextureGLES> texture_image = | ||
| impeller::TextureGLES::WrapTexture(context.GetReactor(), desc_, handle); | ||
|
|
||
| if (!image) { | ||
| 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); | ||
| } | ||
| 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; | ||
| } | ||
|
|
||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| 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; | ||
| } | ||
|
||
|
|
||
| return impeller::DlImageImpeller::Make(image); | ||
| return texture_image; | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerSurface( | ||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller( | ||
| int64_t texture_id, | ||
| impeller::AiksContext* aiks_context, | ||
| std::unique_ptr<FlutterOpenGLTexture> 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()); | ||
| std::shared_ptr<impeller::TextureGLES> image = | ||
| std::make_shared<impeller::TextureGLES>(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"; | ||
| const SkISize& size) { | ||
| std::unique_ptr<FlutterOpenGLTexture> texture = | ||
| 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; | ||
| } | ||
|
|
||
| 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"; | ||
| // Validate texture parameters | ||
| if (size.width() <= 0 || size.height() <= 0) { | ||
| FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x" | ||
| << size.height(); | ||
| return nullptr; | ||
| } | ||
|
||
|
|
||
| if (!texture->bind_callback(texture->user_data)) { | ||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| 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()); | ||
| } | ||
| return nullptr; | ||
| } | ||
|
||
|
|
||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| if (texture_image_ == nullptr) { | ||
| FML_LOG(ERROR) << "Failed to create Impeller texture for texture_id: " | ||
| << texture_id; | ||
| return nullptr; | ||
| } | ||
|
|
||
| return impeller::DlImageImpeller::Make(image); | ||
| return impeller::DlImageImpeller::Make(texture_image_); | ||
| } | ||
|
Comment on lines
+229
to
262
|
||
|
|
||
| // |flutter::Texture| | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The member variable desc_ is being used to store texture state for comparison in IsExternalTextureChanged, but it's not properly initialized before the first call. On the first invocation where texture_image_ is nullptr (line 232), CreateImpellerTexture is called which sets desc_ at line 165. However, if IsExternalTextureChanged is called when texture_image_ is non-null but desc_ hasn't been initialized from a previous successful CreateImpellerTexture call, the comparison will use uninitialized values.
While this may work in practice because desc_ is initialized during CreateImpellerTexture, the logic is fragile and relies on implicit ordering assumptions.