-
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 all 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,136 @@ sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureSkia( | |
| return DlImage::Make(std::move(image)); | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller( | ||
| int64_t texture_id, | ||
| impeller::AiksContext* aiks_context, | ||
| const SkISize& size) { | ||
| std::unique_ptr<FlutterOpenGLTexture> texture = | ||
| external_texture_callback_(texture_id, size.width(), size.height()); | ||
| 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; | ||
| } | ||
|
|
||
| if (!texture) { | ||
| return nullptr; | ||
| if (!texture_image_) { | ||
| return true; | ||
| } | ||
|
|
||
| if (texture->bind_callback != nullptr) { | ||
| return ResolveTextureImpellerSurface(aiks_context, std::move(texture)); | ||
| } else { | ||
| return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture)); | ||
| auto handle = texture_image_->GetGLHandle(); | ||
| if (!handle.has_value()) { | ||
| return true; | ||
| } | ||
|
|
||
| if (handle.value() != texture->name) { | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( | ||
| std::shared_ptr<impeller::TextureGLES> | ||
| EmbedderExternalTextureGL::CreateImpellerTexture( | ||
| impeller::AiksContext* aiks_context, | ||
| std::unique_ptr<FlutterOpenGLTexture> texture) { | ||
| 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; | ||
| if (texture->target == GL_TEXTURE_EXTERNAL_OES) { | ||
| desc.type = impeller::TextureType::kTextureExternalOES; | ||
| } else { | ||
| desc.type = impeller::TextureType::kTexture2D; | ||
| } | ||
|
|
||
| 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) { | ||
| // In case Skia rejects the image, call the release proc so that | ||
| // embedders can perform collection of intermediates. | ||
| if (!texture_image) { | ||
| 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; | ||
| } | ||
|
|
||
| texture_image->SetCoordinateSystem( | ||
| impeller::TextureCoordinateSystem::kUploadFromHost); | ||
|
|
||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| 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; | ||
| } | ||
| } | ||
|
|
||
| return impeller::DlImageImpeller::Make(image); | ||
| desc_ = desc; | ||
| return texture_image; | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerSurface( | ||
| 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()) { | ||
| 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); | ||
| } | ||
| FML_LOG(ERROR) << "Could not bind texture"; | ||
| return nullptr; | ||
| return false; | ||
| } | ||
|
|
||
| if (!image) { | ||
| // In case Skia rejects the image, call the release proc so that | ||
| // embedders can perform collection of intermediates. | ||
| if (texture->name == 0) { | ||
| FML_LOG(ERROR) << "Invalid texture name (0)"; | ||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| } | ||
| FML_LOG(ERROR) << "Could not create external texture"; | ||
| return false; | ||
| } | ||
|
|
||
xiaowei-guan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return true; | ||
| } | ||
|
|
||
| sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller( | ||
| int64_t texture_id, | ||
| impeller::AiksContext* aiks_context, | ||
| 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 (!texture->bind_callback(texture->user_data)) { | ||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| } | ||
| if (!ValidateTextureParameters(texture.get(), size)) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| if (texture->destruction_callback) { | ||
| texture->destruction_callback(texture->user_data); | ||
| if (!texture_image_) { | ||
| 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) { | ||
| 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 IsExternalTextureChanged function assumes texture_image_ is non-null, but it's called inside ResolveTextureImpeller after checking if texture_image_ is nullptr on line 232. However, this check could fail if texture_image_ is not null but GetGLHandle() returns no value. In such cases, line 138 accesses texture_image_->GetGLHandle() which could be called on a null or invalid texture_image_.
Additionally, this function is called at line 235 where texture_image_ is guaranteed to be non-null due to the else clause, but there's no guard against texture_image_ being in an invalid state.