From 3803bde098f881b46199a7d78545c46faa6df37b Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Wed, 24 Sep 2025 18:51:20 +0800 Subject: [PATCH 01/14] Support render texture for vulkan + impeller --- flutter/shell/platform/embedder/embedder.h | 39 ++- flutter/shell/platform/tizen/BUILD.gn | 4 + .../shell/platform/tizen/external_texture.h | 47 ++-- .../tizen/external_texture_pixel_egl.cc | 4 +- .../tizen/external_texture_pixel_egl.h | 8 +- .../external_texture_pixel_egl_impeller.cc | 4 +- .../external_texture_pixel_egl_impeller.h | 8 +- .../tizen/external_texture_pixel_vulkan.cc | 253 ++++++++++++++++++ .../tizen/external_texture_pixel_vulkan.h | 53 ++++ .../tizen/external_texture_surface_egl.cc | 4 +- .../tizen/external_texture_surface_egl.h | 8 +- .../external_texture_surface_egl_impeller.cc | 4 +- .../external_texture_surface_egl_impeller.h | 8 +- .../tizen/external_texture_surface_vulkan.cc | 121 +++++++++ .../tizen/external_texture_surface_vulkan.h | 47 ++++ .../external_texture_surface_vulkan_buffer.cc | 62 +++++ .../external_texture_surface_vulkan_buffer.h | 44 +++ ...ernal_texture_surface_vulkan_buffer_dma.cc | 167 ++++++++++++ ...ternal_texture_surface_vulkan_buffer_dma.h | 37 +++ .../tizen/flutter_tizen_texture_registrar.cc | 23 +- .../tizen/flutter_tizen_texture_registrar.h | 13 +- ...utter_tizen_texture_registrar_unittests.cc | 2 +- .../shell/platform/tizen/tizen_renderer_gl.cc | 4 +- .../platform/tizen/tizen_renderer_vulkan.cc | 23 +- 24 files changed, 936 insertions(+), 51 deletions(-) create mode 100644 flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc create mode 100644 flutter/shell/platform/tizen/external_texture_pixel_vulkan.h create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan.cc create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan.h create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc create mode 100644 flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h diff --git a/flutter/shell/platform/embedder/embedder.h b/flutter/shell/platform/embedder/embedder.h index dfb0896b..505f78f2 100644 --- a/flutter/shell/platform/embedder/embedder.h +++ b/flutter/shell/platform/embedder/embedder.h @@ -924,6 +924,9 @@ typedef void* FlutterVulkanQueueHandle; /// Alias for VkImage. typedef uint64_t FlutterVulkanImageHandle; +/// Alias for VkDeviceMemory. +typedef uint64_t FlutterVulkanDeviceMemoryHandle; + typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanImage). size_t struct_size; @@ -952,6 +955,36 @@ typedef bool (*FlutterVulkanPresentCallback)( void* /* user data */, const FlutterVulkanImage* /* image */); +typedef struct { + /// Handle to the VkImage that is owned by the embedder. The engine will + /// bind this image for writing the frame. + FlutterVulkanImageHandle image; + /// The VkDeviceMemory that backs the iamge. + FlutterVulkanDeviceMemoryHandle image_memory; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; + /// 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 + /// collect the texture. + VoidCallback destruction_callback; + /// Optional parameters for texture height/width, default is 0, non-zero means + /// the texture has the specified width/height. + /// Width of the texture. + size_t width; + /// Height of the texture. + size_t height; +} FlutterVulkanTexture; + +/// Callback to provide an external texture for a given texture_id. +/// See: external_texture_frame_callback. +typedef bool (*FlutterVulkanTextureFrameCallback)( + void* /* user data */, + int64_t /* texture identifier */, + size_t /* width */, + size_t /* height */, + FlutterVulkanTexture* /* texture out */); + typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). size_t struct_size; @@ -1015,7 +1048,11 @@ typedef struct { /// without any additional synchronization. /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterVulkanPresentCallback present_image_callback; - + /// When the embedder specifies that a texture has a frame available, the + /// engine will call this method (on an internal engine managed thread) so + /// that external texture details can be supplied to the engine for subsequent + /// composition. + FlutterVulkanTextureFrameCallback external_texture_frame_callback; } FlutterVulkanRendererConfig; typedef struct { diff --git a/flutter/shell/platform/tizen/BUILD.gn b/flutter/shell/platform/tizen/BUILD.gn index 2cc7ec43..f280025c 100644 --- a/flutter/shell/platform/tizen/BUILD.gn +++ b/flutter/shell/platform/tizen/BUILD.gn @@ -90,8 +90,12 @@ template("embedder") { "channels/window_channel.cc", "external_texture_pixel_egl.cc", "external_texture_pixel_egl_impeller.cc", + "external_texture_pixel_vulkan.cc", "external_texture_surface_egl.cc", "external_texture_surface_egl_impeller.cc", + "external_texture_surface_vulkan.cc", + "external_texture_surface_vulkan_buffer.cc", + "external_texture_surface_vulkan_buffer_dma.cc", "flutter_platform_node_delegate_tizen.cc", "flutter_project_bundle.cc", "flutter_tizen.cc", diff --git a/flutter/shell/platform/tizen/external_texture.h b/flutter/shell/platform/tizen/external_texture.h index a3b9866f..37e046e5 100644 --- a/flutter/shell/platform/tizen/external_texture.h +++ b/flutter/shell/platform/tizen/external_texture.h @@ -13,6 +13,21 @@ namespace flutter { +static std::atomic next_texture_id = {1}; + +class ExternalTexture { + public: + ExternalTexture() : texture_id_(next_texture_id++) {} + + virtual ~ExternalTexture() = default; + + // Returns the unique id for the ExternalTextureGL instance. + int64_t TextureId() { return texture_id_; } + + protected: + const int64_t texture_id_ = 0; +}; + enum class ExternalTextureExtensionType { kNone, kNativeSurface, kDmaBuffer }; struct ExternalTextureGLState { @@ -20,29 +35,29 @@ struct ExternalTextureGLState { ExternalTextureExtensionType gl_extension; }; -static std::atomic next_texture_id = {1}; - -class ExternalTexture { +class ExternalGLTexture : public ExternalTexture { public: - ExternalTexture(ExternalTextureExtensionType gl_extension = - ExternalTextureExtensionType::kNone) - : state_(std::make_unique()), - texture_id_(next_texture_id++) { + ExternalGLTexture(ExternalTextureExtensionType gl_extension = + ExternalTextureExtensionType::kNone) + : ExternalTexture(), state_(std::make_unique()) { state_->gl_extension = gl_extension; } - virtual ~ExternalTexture() = default; - - // Returns the unique id for the ExternalTextureGL instance. - int64_t TextureId() { return texture_id_; } - - virtual bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) = 0; + virtual bool PopulateOpenGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) = 0; protected: std::unique_ptr state_; - const int64_t texture_id_ = 0; +}; + +class ExternalVulkanTexture : public ExternalTexture { + public: + ExternalVulkanTexture() : ExternalTexture() {} + + virtual bool PopulateVulkanTexture(size_t width, + size_t height, + FlutterVulkanTexture* vulkan_texture) = 0; }; } // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl.cc b/flutter/shell/platform/tizen/external_texture_pixel_egl.cc index 018755c1..3e150699 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl.cc @@ -11,7 +11,7 @@ namespace flutter { -bool ExternalTexturePixelEGL::PopulateTexture( +bool ExternalTexturePixelEGL::PopulateOpenGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { @@ -33,7 +33,7 @@ bool ExternalTexturePixelEGL::PopulateTexture( ExternalTexturePixelEGL::ExternalTexturePixelEGL( FlutterDesktopPixelBufferTextureCallback texture_callback, void* user_data) - : ExternalTexture(), + : ExternalGLTexture(), texture_callback_(texture_callback), user_data_(user_data) {} diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl.h b/flutter/shell/platform/tizen/external_texture_pixel_egl.h index 16260b41..fa9fe2b8 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl.h @@ -11,7 +11,7 @@ namespace flutter { -class ExternalTexturePixelEGL : public ExternalTexture { +class ExternalTexturePixelEGL : public ExternalGLTexture { public: ExternalTexturePixelEGL( FlutterDesktopPixelBufferTextureCallback texture_callback, @@ -19,9 +19,9 @@ class ExternalTexturePixelEGL : public ExternalTexture { ~ExternalTexturePixelEGL() = default; - bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateOpenGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; bool CopyPixelBuffer(size_t& width, size_t& height); diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc index 7cf7899a..148bdb51 100755 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc @@ -11,7 +11,7 @@ namespace flutter { -bool ExternalTexturePixelEGLImpeller::PopulateTexture( +bool ExternalTexturePixelEGLImpeller::PopulateOpenGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { @@ -43,7 +43,7 @@ bool ExternalTexturePixelEGLImpeller::PopulateTexture( ExternalTexturePixelEGLImpeller::ExternalTexturePixelEGLImpeller( FlutterDesktopPixelBufferTextureCallback texture_callback, void* user_data) - : ExternalTexture(), + : ExternalGLTexture(), texture_callback_(texture_callback), user_data_(user_data) {} diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h index ebaad4e4..8dd48678 100755 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h @@ -11,7 +11,7 @@ namespace flutter { -class ExternalTexturePixelEGLImpeller : public ExternalTexture { +class ExternalTexturePixelEGLImpeller : public ExternalGLTexture { public: ExternalTexturePixelEGLImpeller( FlutterDesktopPixelBufferTextureCallback texture_callback, @@ -19,9 +19,9 @@ class ExternalTexturePixelEGLImpeller : public ExternalTexture { ~ExternalTexturePixelEGLImpeller() = default; - bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateOpenGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc new file mode 100644 index 00000000..cc27836c --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -0,0 +1,253 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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/tizen/external_texture_pixel_vulkan.h" +#include "flutter/shell/platform/tizen/logger.h" + +namespace flutter { +ExternalTexturePixelVulkan::ExternalTexturePixelVulkan( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data, + TizenRendererVulkan* vulkan_renderer) + : ExternalVulkanTexture(), + texture_callback_(texture_callback), + user_data_(user_data), + vulkan_renderer_(vulkan_renderer) {} + +ExternalTexturePixelVulkan::~ExternalTexturePixelVulkan() { + ReleaseImage(); +} + +bool ExternalTexturePixelVulkan::PopulateVulkanTexture( + size_t width, + size_t height, + FlutterVulkanTexture* flutter_texture) { + if (!texture_callback_) { + FT_LOG(Error) << "texture_callback_ is nullptr"; + return false; + } + + const FlutterDesktopPixelBuffer* pixel_buffer = + texture_callback_(width, height, user_data_); + + if (!pixel_buffer) { + FT_LOG(Error) << "pixel_buffer is nullptr"; + return false; + } + + if (!CreateOrUpdateImage(pixel_buffer)) { + FT_LOG(Error) << "Fail to create image"; + ReleaseImage(); + return false; + } + width_ = pixel_buffer->width; + height_ = pixel_buffer->height; + + if (!CreateBuffer(width, height)) { + return false; + } + + CopyBufferToImage(staging_buffer_, vk_image_, width_, height_, + pixel_buffer->buffer); + + ReleaseBuffer(); + FlutterVulkanTexture* vulkan_texture = + static_cast(flutter_texture); + vulkan_texture->image = reinterpret_cast(vk_image_); + vulkan_texture->format = VK_FORMAT_R8G8B8A8_UNORM; + vulkan_texture->width = width; + vulkan_texture->height = height; + return true; +} + +bool ExternalTexturePixelVulkan::CreateOrUpdateImage( + const FlutterDesktopPixelBuffer* pixel_buffer) { + if (vk_image_ == VK_NULL_HANDLE) { + return CreateImage(pixel_buffer->width, pixel_buffer->height); + } + + if (pixel_buffer->width != width_ || pixel_buffer->height != height_) { + ReleaseImage(); + return CreateImage(pixel_buffer->width, pixel_buffer->height); + } + return true; +} + +bool ExternalTexturePixelVulkan::CreateImage(size_t width, size_t height) { + VkImageCreateInfo image_info{}; + image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.extent.width = width; + image_info.extent.height = height; + image_info.extent.depth = 1; + image_info.mipLevels = 1; + image_info.arrayLayers = 1; + image_info.format = VK_FORMAT_R8G8B8A8_UNORM; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.usage = + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + if (vkCreateImage(static_cast(vulkan_renderer_->GetDeviceHandle()), + &image_info, nullptr, &vk_image_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to create VkImage"; + return false; + } + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements( + static_cast(vulkan_renderer_->GetDeviceHandle()), vk_image_, + &memory_requirements); + uint32_t memory_type_index; + if (!FindMemoryType(memory_requirements.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_type_index)) { + return false; + } + VkMemoryAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = memory_requirements.size; + alloc_info.memoryTypeIndex = memory_type_index; + + if (vkAllocateMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + &alloc_info, nullptr, &vk_image_memory_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + + if (vkBindImageMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), vk_image_, + vk_image_memory_, 0) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to bind image memory"; + return false; + } + return true; +} + +bool ExternalTexturePixelVulkan::FindMemoryType( + uint32_t type_filter, + VkMemoryPropertyFlags properties, + uint32_t& index_out) { + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties( + static_cast( + vulkan_renderer_->GetPhysicalDeviceHandle()), + &memory_properties); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { + if ((type_filter & (1 << i)) && + (memory_properties.memoryTypes[i].propertyFlags & properties) == + properties) { + index_out = i; + return true; + } + } + return false; +} + +bool ExternalTexturePixelVulkan::CreateBuffer(size_t width, size_t height) { + VkBufferCreateInfo buffer_info{}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = width * height * 4; + buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + if (vkCreateBuffer(static_cast(vulkan_renderer_->GetDeviceHandle()), + &buffer_info, nullptr, &staging_buffer_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to create vkBuffer"; + return false; + } + + VkMemoryRequirements memory_requirements; + vkGetBufferMemoryRequirements( + static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_, &memory_requirements); + uint32_t memory_type_index; + if (!FindMemoryType(memory_requirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + memory_type_index)) { + FT_LOG(Error) << "Fail to find memory type"; + return false; + } + VkMemoryAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = memory_requirements.size; + alloc_info.memoryTypeIndex = memory_type_index; + + if (vkAllocateMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + &alloc_info, nullptr, &staging_buffer_memory_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + + if (vkBindBufferMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_, staging_buffer_memory_, 0) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to bind buffer memory"; + return false; + } + return true; +} + +void ExternalTexturePixelVulkan::ReleaseBuffer() { + if (staging_buffer_ != VK_NULL_HANDLE) { + vkDestroyBuffer(static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_, nullptr); + staging_buffer_ = VK_NULL_HANDLE; + } + if (staging_buffer_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_memory_, nullptr); + + staging_buffer_memory_ = VK_NULL_HANDLE; + } +} + +void ExternalTexturePixelVulkan::CopyBufferToImage(VkBuffer dst_buffer, + VkImage image, + uint32_t width, + uint32_t height, + const uint8_t* src_buffer) { + void* data; + vkMapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_memory_, 0, width * height * 4, 0, &data); + memcpy(data, src_buffer, static_cast(width * height * 4)); + vkUnmapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), + staging_buffer_memory_); + VkCommandBuffer command_buffer = vulkan_renderer_->BeginSingleTimeCommands(); + + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageOffset = {0, 0, 0}; + region.imageExtent = {width, height, 1}; + + vkCmdCopyBufferToImage(command_buffer, dst_buffer, image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + vulkan_renderer_->EndSingleTimeCommands(command_buffer); +} + +void ExternalTexturePixelVulkan::ReleaseImage() { + if (vk_image_ != VK_NULL_HANDLE) { + vkDestroyImage(static_cast(vulkan_renderer_->GetDeviceHandle()), + vk_image_, nullptr); + vk_image_ = VK_NULL_HANDLE; + } + + if (vk_image_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), + vk_image_memory_, nullptr); + vk_image_memory_ = VK_NULL_HANDLE; + } +} + +} // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h new file mode 100644 index 00000000..b2699fe6 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h @@ -0,0 +1,53 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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_TIZEN_EXTERNAL_TEXTURE_PIXEL_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_PIXEL_VULKAN_H_ + +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/external_texture.h" +#include "flutter/shell/platform/tizen/tizen_renderer_vulkan.h" + +namespace flutter { +class ExternalTexturePixelVulkan : public ExternalVulkanTexture { + public: + ExternalTexturePixelVulkan( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data, + TizenRendererVulkan* vulkan_renderer); + + virtual ~ExternalTexturePixelVulkan(); + + bool PopulateVulkanTexture(size_t width, + size_t height, + FlutterVulkanTexture* flutter_texture) override; + + private: + bool CreateBuffer(size_t width, size_t height); + bool CreateImage(size_t width, size_t height); + bool CreateOrUpdateImage(const FlutterDesktopPixelBuffer* pixel_buffer); + void CopyBufferToImage(VkBuffer dst_buffer, + VkImage image, + uint32_t width, + uint32_t height, + const uint8_t* src_buffer); + void ReleaseBuffer(); + void ReleaseImage(); + bool FindMemoryType(uint32_t typeFilter, + VkMemoryPropertyFlags properties, + uint32_t& index_out); + FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; + size_t width_ = 0; + size_t height_ = 0; + void* user_data_ = nullptr; + TizenRendererVulkan* vulkan_renderer_ = nullptr; + VkImage vk_image_ = VK_NULL_HANDLE; + VkDeviceMemory vk_image_memory_ = VK_NULL_HANDLE; + VkBuffer staging_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory staging_buffer_memory_ = VK_NULL_HANDLE; +}; +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_PIXEL_VULKAN_H_ diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl.cc b/flutter/shell/platform/tizen/external_texture_surface_egl.cc index f89d5156..5d4fbe99 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_egl.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_egl.cc @@ -29,7 +29,7 @@ ExternalTextureSurfaceEGL::ExternalTextureSurfaceEGL( ExternalTextureExtensionType gl_extension, FlutterDesktopGpuSurfaceTextureCallback texture_callback, void* user_data) - : ExternalTexture(gl_extension), + : ExternalGLTexture(gl_extension), texture_callback_(texture_callback), user_data_(user_data) {} @@ -39,7 +39,7 @@ ExternalTextureSurfaceEGL::~ExternalTextureSurfaceEGL() { } } -bool ExternalTextureSurfaceEGL::PopulateTexture( +bool ExternalTextureSurfaceEGL::PopulateOpenGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl.h b/flutter/shell/platform/tizen/external_texture_surface_egl.h index 621fbe44..34d99104 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_egl.h +++ b/flutter/shell/platform/tizen/external_texture_surface_egl.h @@ -11,7 +11,7 @@ namespace flutter { -class ExternalTextureSurfaceEGL : public ExternalTexture { +class ExternalTextureSurfaceEGL : public ExternalGLTexture { public: ExternalTextureSurfaceEGL( ExternalTextureExtensionType gl_extension, @@ -27,9 +27,9 @@ class ExternalTextureSurfaceEGL : public ExternalTexture { // texture object. // // Returns true on success, false on failure. - bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateOpenGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: FlutterDesktopGpuSurfaceTextureCallback texture_callback_ = nullptr; diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc index e3de9c85..86820aac 100755 --- a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc @@ -30,7 +30,7 @@ ExternalTextureSurfaceEGLImpeller::ExternalTextureSurfaceEGLImpeller( ExternalTextureExtensionType gl_extension, FlutterDesktopGpuSurfaceTextureCallback texture_callback, void* user_data) - : ExternalTexture(gl_extension), + : ExternalGLTexture(gl_extension), texture_callback_(texture_callback), user_data_(user_data) {} @@ -38,7 +38,7 @@ ExternalTextureSurfaceEGLImpeller::~ExternalTextureSurfaceEGLImpeller() { ReleaseImage(); } -bool ExternalTextureSurfaceEGLImpeller::PopulateTexture( +bool ExternalTextureSurfaceEGLImpeller::PopulateOpenGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h index d957000b..0a834532 100755 --- a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h +++ b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h @@ -14,7 +14,7 @@ namespace flutter { -class ExternalTextureSurfaceEGLImpeller : public ExternalTexture { +class ExternalTextureSurfaceEGLImpeller : public ExternalGLTexture { public: ExternalTextureSurfaceEGLImpeller( ExternalTextureExtensionType gl_extension, @@ -30,9 +30,9 @@ class ExternalTextureSurfaceEGLImpeller : public ExternalTexture { // texture object. // // Returns true on success, false on failure. - bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateOpenGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: static bool OnBindCallback(void* user_data); diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc new file mode 100644 index 00000000..1dca30c3 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -0,0 +1,121 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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/tizen/external_texture_surface_vulkan.h" +#include "flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h" +#include "flutter/shell/platform/tizen/logger.h" + +namespace flutter { + +ExternalTextureSurfaceVulkan::ExternalTextureSurfaceVulkan( + FlutterDesktopGpuSurfaceTextureCallback texture_callback, + void* user_data, + TizenRendererVulkan* vulkan_renderer) + : ExternalVulkanTexture(), + texture_callback_(texture_callback), + user_data_(user_data), + vulkan_renderer_(vulkan_renderer) {} + +ExternalTextureSurfaceVulkan::~ExternalTextureSurfaceVulkan() {} + +bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( + const FlutterDesktopGpuSurfaceDescriptor* descriptor) { + if (descriptor == nullptr || descriptor->handle == nullptr) { + if (vulkan_buffer_) { + vulkan_buffer_->ReleaseImage(); + } + return false; + } + const tbm_surface_h tbm_surface = + reinterpret_cast(descriptor->handle); + if (!vulkan_buffer_) { + if (IsSupportDisjoint(tbm_surface)) { + /** + vulkan_buffer_ = std::make_unique( + vulkan_renderer_); + */ + } else { + vulkan_buffer_ = std::make_unique( + vulkan_renderer_); + } + } + void* handle = descriptor->handle; + if (handle != last_surface_handle_) { + vulkan_buffer_->ReleaseImage(); + tbm_surface_info_s tbm_surface_info; + if (tbm_surface_get_info(tbm_surface, &tbm_surface_info) != + TBM_SURFACE_ERROR_NONE) { + if (descriptor->release_callback) { + descriptor->release_callback(descriptor->release_context); + } + return false; + } + if (!vulkan_buffer_->CreateImage(tbm_surface)) { + FT_LOG(Error) << "Fail to create image"; + vulkan_buffer_->ReleaseImage(); + return false; + } + if (!vulkan_buffer_->AllocateMemory(tbm_surface)) { + FT_LOG(Error) << "Fail to allocate memory"; + vulkan_buffer_->ReleaseImage(); + return false; + } + if (!vulkan_buffer_->BindImageMemory(tbm_surface)) { + FT_LOG(Error) << "Fail to bind image memory"; + vulkan_buffer_->ReleaseImage(); + return false; + } + last_surface_handle_ = handle; + } + if (descriptor->release_callback) { + descriptor->release_callback(descriptor->release_context); + } + return true; +} + +bool ExternalTextureSurfaceVulkan::IsSupportDisjoint( + tbm_surface_h tbm_surface) { + int num_bos = tbm_surface_internal_get_num_bos(tbm_surface); + bool is_disjoint = false; + uint32_t tfd[num_bos]; + for (int i = 0; i < num_bos; i++) { + tbm_bo bo = tbm_surface_internal_get_bo(tbm_surface, i); + tfd[i] = tbm_bo_get_handle(bo, TBM_DEVICE_3D).u32; + if (tfd[i] != tfd[0]) + is_disjoint = true; + } + return is_disjoint; +} + +bool ExternalTextureSurfaceVulkan::PopulateVulkanTexture( + size_t width, + size_t height, + FlutterVulkanTexture* vulkan_texture) { + if (!texture_callback_) { + return false; + } + const FlutterDesktopGpuSurfaceDescriptor* gpu_surface = + texture_callback_(width, height, user_data_); + if (!gpu_surface) { + FT_LOG(Info) << "gpu_surface is null for texture ID: " << texture_id_; + return false; + } + + if (!CreateOrUpdateImage(gpu_surface)) { + FT_LOG(Info) << "CreateOrUpdateEglImage fail for texture ID: " + << texture_id_; + return false; + } + + vulkan_texture->image = + reinterpret_cast(vulkan_buffer_->GetImage()); + vulkan_texture->format = vulkan_buffer_->GetFormat(); + vulkan_texture->image_memory = + reinterpret_cast(vulkan_buffer_->GetMemory()); + vulkan_texture->width = width; + vulkan_texture->height = height; + return true; +} + +} // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan.h new file mode 100644 index 00000000..2306bb48 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.h @@ -0,0 +1,47 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_H_ + +#include +#include +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/external_texture.h" +#include "flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h" +#include "flutter/shell/platform/tizen/tizen_renderer_vulkan.h" + +#include +#include +#include +#include + +namespace flutter { +class ExternalTextureSurfaceVulkan : public ExternalVulkanTexture { + public: + ExternalTextureSurfaceVulkan( + FlutterDesktopGpuSurfaceTextureCallback texture_callback, + void* user_data, + TizenRendererVulkan* vulkan_renderer); + + virtual ~ExternalTextureSurfaceVulkan(); + + bool PopulateVulkanTexture(size_t width, + size_t height, + FlutterVulkanTexture* vulkan_texture) override; + + private: + bool CreateOrUpdateImage( + const FlutterDesktopGpuSurfaceDescriptor* descriptor); + bool IsSupportDisjoint(tbm_surface_h tbm_surface); + FlutterDesktopGpuSurfaceTextureCallback texture_callback_ = nullptr; + void* user_data_ = nullptr; + TizenRendererVulkan* vulkan_renderer_ = nullptr; + void* last_surface_handle_ = nullptr; + std::unique_ptr vulkan_buffer_; +}; +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_H_ diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc new file mode 100644 index 00000000..8d09b007 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc @@ -0,0 +1,62 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. 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/tizen/external_texture_surface_vulkan_buffer.h" +#include + +namespace flutter { + +ExternalTextureSurfaceVulkanBuffer::ExternalTextureSurfaceVulkanBuffer( + TizenRendererVulkan* vulkan_renderer) + : vulkan_renderer_(vulkan_renderer) {} + +VkFormat ExternalTextureSurfaceVulkanBuffer::ConvertFormat(tbm_format& format) { + switch (format) { + case TBM_FORMAT_NV12: + case TBM_FORMAT_NV21: + return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; + case TBM_FORMAT_RGBA8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_RGB888: + return VK_FORMAT_R8G8B8A8_UNORM; + case TBM_FORMAT_BGR888: + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_BGRA8888: + return VK_FORMAT_B8G8R8A8_UNORM; + default: + return VK_FORMAT_UNDEFINED; + } +} + +bool ExternalTextureSurfaceVulkanBuffer::FindProperties( + uint32_t memory_type_bits_requirement, + VkMemoryPropertyFlags required_properties, + uint32_t& index_out) { + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties( + static_cast( + vulkan_renderer_->GetPhysicalDeviceHandle()), + &memory_properties); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { + const uint32_t memory_type_bits = (1 << i); + const bool isRequiredMemoryType = + memory_type_bits_requirement & memory_type_bits; + const VkMemoryPropertyFlags properties = + memory_properties.memoryTypes[i].propertyFlags; + const bool has_required_properties = + (properties & required_properties) == required_properties; + if (isRequiredMemoryType && has_required_properties) { + index_out = i; + return true; + } + } + return false; +} + +} // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h new file mode 100644 index 00000000..119a7ffd --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -0,0 +1,44 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_H_ +#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_H_ + +#include +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/external_texture.h" +#include "flutter/shell/platform/tizen/tizen_renderer_vulkan.h" + +#include +#include +#include +#include + +namespace flutter { +class ExternalTextureSurfaceVulkanBuffer { + public: + ExternalTextureSurfaceVulkanBuffer(TizenRendererVulkan* vulkan_renderer); + + virtual ~ExternalTextureSurfaceVulkanBuffer() = default; + virtual bool CreateImage(tbm_surface_h tbm_surface) = 0; + virtual void ReleaseImage() = 0; + virtual bool AllocateMemory(tbm_surface_h tbm_surface) = 0; + virtual bool BindImageMemory(tbm_surface_h tbm_surface) = 0; + virtual VkFormat GetFormat() = 0; + virtual VkImage GetImage() = 0; + virtual VkDeviceMemory GetMemory() = 0; + + protected: + VkFormat ConvertFormat(tbm_format& format); + bool FindProperties(uint32_t memory_type_bits_requirement, + VkMemoryPropertyFlags required_properties, + uint32_t& index_out); + + private: + TizenRendererVulkan* vulkan_renderer_ = nullptr; +}; +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_H_ diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc new file mode 100644 index 00000000..35698e40 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -0,0 +1,167 @@ +// Copyright 2025 Samsung Electronics Co., Ltd. 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/tizen/external_texture_surface_vulkan_buffer_dma.h" +#include "flutter/shell/platform/tizen/logger.h" + +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR 0 +#endif + +namespace flutter { + +ExternalTextureSurfaceVulkanBufferDma::ExternalTextureSurfaceVulkanBufferDma( + TizenRendererVulkan* vulkan_renderer) + : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer), + vulkan_renderer_(vulkan_renderer) {} + +ExternalTextureSurfaceVulkanBufferDma:: + ~ExternalTextureSurfaceVulkanBufferDma() { + ReleaseImage(); +} + +VkFormat ExternalTextureSurfaceVulkanBufferDma::GetFormat() { + return texture_format_; +} + +VkImage ExternalTextureSurfaceVulkanBufferDma::GetImage() { + return texture_image_; +} + +VkDeviceMemory ExternalTextureSurfaceVulkanBufferDma::GetMemory() { + return texture_device_memory_; +} + +VkResult GetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR* pMemoryFdProperties) { + auto func = (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( + device, "vkGetMemoryFdPropertiesKHR"); + if (func != nullptr) { + return func(device, handleType, fd, pMemoryFdProperties); + } else { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } +} + +bool ExternalTextureSurfaceVulkanBufferDma::CreateImage( + tbm_surface_h tbm_surface) { + tbm_surface_info_s tbm_surface_info; + tbm_surface_get_info(tbm_surface, &tbm_surface_info); + texture_format_ = ConvertFormat(tbm_surface_info.format); + + VkExternalMemoryImageCreateInfoKHR external_image_create_info = {}; + external_image_create_info.sType = + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR; + external_image_create_info.pNext = nullptr; + external_image_create_info.handleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + + VkImageCreateInfo image_create_info = {}; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.format = texture_format_; + image_create_info.extent = {tbm_surface_info.width, tbm_surface_info.height, + 1}; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.tiling = VK_IMAGE_TILING_LINEAR; + image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + image_create_info.pNext = &external_image_create_info; + if (vkCreateImage(static_cast(vulkan_renderer_->GetDeviceHandle()), + &image_create_info, nullptr, + &texture_image_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to create VkImage"; + return false; + } + return true; +} + +bool ExternalTextureSurfaceVulkanBufferDma::GetFdMemoryTypeIndex( + int fd, + uint32_t& index_out) { + VkMemoryFdPropertiesKHR memory_fd_properties = {}; + memory_fd_properties.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR; + + if (GetMemoryFdPropertiesKHR( + static_cast(vulkan_renderer_->GetDeviceHandle()), + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, fd, + &memory_fd_properties) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to get memory fd properties"; + return false; + } + + for (uint32_t mem_idx = 0; mem_idx < VK_MAX_MEMORY_TYPES; mem_idx++) { + if (memory_fd_properties.memoryTypeBits & (1 << mem_idx)) { + index_out = mem_idx; + return true; + } + } + return false; +} + +bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( + tbm_surface_h tbm_surface) { + tbm_bo bo = tbm_surface_internal_get_bo(tbm_surface, 0); + int bo_fd = tbm_bo_export_fd(bo); + int bo_size = tbm_bo_size(bo); + + uint32_t memory_type_index = -1; + if (!GetFdMemoryTypeIndex(bo_fd, memory_type_index)) { + FT_LOG(Error) << "Fail to get memory type index"; + return false; + } + + VkImportMemoryFdInfoKHR import_memory_fd_info = {}; + import_memory_fd_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR; + import_memory_fd_info.handleType = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + import_memory_fd_info.fd = bo_fd; + import_memory_fd_info.pNext = nullptr; + + VkMemoryAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.pNext = &import_memory_fd_info; + alloc_info.allocationSize = static_cast(bo_size); + alloc_info.memoryTypeIndex = memory_type_index; + if (vkAllocateMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + &alloc_info, nullptr, &texture_device_memory_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + return true; +} + +bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( + tbm_surface_h tbm_surface) { + if (vkBindImageMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + texture_image_, texture_device_memory_, 0u) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to bind image memory"; + return false; + } + return true; +} + +void ExternalTextureSurfaceVulkanBufferDma::ReleaseImage() { + if (texture_image_ != VK_NULL_HANDLE) { + vkDestroyImage(static_cast(vulkan_renderer_->GetDeviceHandle()), + texture_image_, nullptr); + texture_image_ = VK_NULL_HANDLE; + } + if (texture_device_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), + texture_device_memory_, nullptr); + texture_device_memory_ = VK_NULL_HANDLE; + } +} +} // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h new file mode 100644 index 00000000..24a7962d --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h @@ -0,0 +1,37 @@ +// Copyright 2024 Samsung Electronics Co., Ltd. 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_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_DMA_H_ +#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_DMA_H_ + +#include +#include "flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h" +#include "flutter/shell/platform/tizen/tizen_renderer_vulkan.h" + +#include + +namespace flutter { +class ExternalTextureSurfaceVulkanBufferDma + : public ExternalTextureSurfaceVulkanBuffer { + public: + ExternalTextureSurfaceVulkanBufferDma(TizenRendererVulkan* vulkan_renderer); + virtual ~ExternalTextureSurfaceVulkanBufferDma(); + bool CreateImage(tbm_surface_h tbm_surface) override; + void ReleaseImage() override; + bool AllocateMemory(tbm_surface_h tbm_surface) override; + bool BindImageMemory(tbm_surface_h tbm_surface) override; + VkFormat GetFormat() override; + VkImage GetImage() override; + VkDeviceMemory GetMemory() override; + + private: + bool GetFdMemoryTypeIndex(int fd, uint32_t& index_out); + TizenRendererVulkan* vulkan_renderer_ = nullptr; + VkFormat texture_format_ = VK_FORMAT_UNDEFINED; + VkImage texture_image_ = VK_NULL_HANDLE; + VkDeviceMemory texture_device_memory_ = VK_NULL_HANDLE; +}; +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_DMA_H_ diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc index 4003d8aa..e21eed97 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -86,7 +86,7 @@ bool FlutterTizenTextureRegistrar::MarkTextureFrameAvailable( return engine_->MarkExternalTextureFrameAvailable(texture_id); } -bool FlutterTizenTextureRegistrar::PopulateTexture( +bool FlutterTizenTextureRegistrar::PopulateOpenGLTexture( int64_t texture_id, size_t width, size_t height, @@ -100,7 +100,26 @@ bool FlutterTizenTextureRegistrar::PopulateTexture( } texture = iter->second.get(); } - return texture->PopulateTexture(width, height, opengl_texture); + return dynamic_cast(texture)->PopulateOpenGLTexture( + width, height, opengl_texture); +} + +bool FlutterTizenTextureRegistrar::PopulateVulkanTexture( + int64_t texture_id, + size_t width, + size_t height, + FlutterVulkanTexture* vulkan_texture) { + ExternalTexture* texture; + { + std::lock_guard lock(map_mutex_); + auto iter = textures_.find(texture_id); + if (iter == textures_.end()) { + return false; + } + texture = iter->second.get(); + } + return dynamic_cast(texture)->PopulateVulkanTexture( + width, height, vulkan_texture); } } // namespace flutter diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h index cc2482cf..76c73a9a 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h @@ -41,10 +41,15 @@ class FlutterTizenTextureRegistrar { // contents of the texture identified by |texture_id|. // // Returns true on success. - bool PopulateTexture(int64_t texture_id, - size_t width, - size_t height, - FlutterOpenGLTexture* texture); + bool PopulateOpenGLTexture(int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* texture); + + bool PopulateVulkanTexture(int64_t texture_id, + size_t width, + size_t height, + FlutterVulkanTexture* texture); private: FlutterTizenEngine* engine_ = nullptr; diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc index f757c4c1..eeb4ff72 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc @@ -118,7 +118,7 @@ TEST_F(FlutterTizenTextureRegistrarTest, RegisterUnknownTextureType) { TEST_F(FlutterTizenTextureRegistrarTest, PopulateInvalidTexture) { FlutterTizenTextureRegistrar registrar(engine_); - bool result = registrar.PopulateTexture(1, 640, 480, nullptr); + bool result = registrar.PopulateOpenGLTexture(1, 640, 480, nullptr); EXPECT_FALSE(result); } diff --git a/flutter/shell/platform/tizen/tizen_renderer_gl.cc b/flutter/shell/platform/tizen/tizen_renderer_gl.cc index febc73c4..40afc75c 100644 --- a/flutter/shell/platform/tizen/tizen_renderer_gl.cc +++ b/flutter/shell/platform/tizen/tizen_renderer_gl.cc @@ -77,8 +77,8 @@ FlutterRendererConfig TizenRendererGL::GetRendererConfig() { if (!engine->texture_registrar()) { return false; } - return engine->texture_registrar()->PopulateTexture(texture_id, width, - height, texture); + return engine->texture_registrar()->PopulateOpenGLTexture(texture_id, width, + height, texture); }; return config; } diff --git a/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc b/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc index 764ac5c7..86bd9d73 100644 --- a/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc +++ b/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc @@ -7,7 +7,8 @@ #include #include #include - +#include "flutter/shell/platform/tizen/external_texture_pixel_vulkan.h" +#include "flutter/shell/platform/tizen/external_texture_surface_vulkan.h" #include "flutter/shell/platform/tizen/flutter_tizen_engine.h" #include "flutter/shell/platform/tizen/logger.h" @@ -120,6 +121,16 @@ void TizenRendererVulkan::Cleanup() { std::unique_ptr TizenRendererVulkan::CreateExternalTexture( const FlutterDesktopTextureInfo* texture_info) { + switch (texture_info->type) { + case kFlutterDesktopPixelBufferTexture: + return std::make_unique( + texture_info->pixel_buffer_config.callback, + texture_info->pixel_buffer_config.user_data, this); + case kFlutterDesktopGpuSurfaceTexture: + return std::make_unique( + texture_info->gpu_surface_config.callback, + texture_info->gpu_surface_config.user_data, this); + } return nullptr; } @@ -168,6 +179,16 @@ FlutterRendererConfig TizenRendererVulkan::GetRendererConfig() { return dynamic_cast(engine->renderer()) ->Present(image); }; + config.vulkan.external_texture_frame_callback = + [](void* user_data, int64_t texture_identifier, size_t width, + size_t height, FlutterVulkanTexture* texture) -> bool { + auto* engine = reinterpret_cast(user_data); + if (!engine->view()) { + return false; + } + return engine->texture_registrar()->PopulateVulkanTexture( + texture_identifier, width, height, texture); + }; return config; } From daf3dcdfa69739f1222c31f90c50fe90b448c682 Mon Sep 17 00:00:00 2001 From: gin7773 <94502163+gin7773@users.noreply.github.com> Date: Sun, 28 Sep 2025 14:18:24 +0800 Subject: [PATCH 02/14] modify external_texture_pixel_vulkan (#6) --- .../tizen/external_texture_pixel_vulkan.cc | 125 ++++++++++-------- .../tizen/external_texture_pixel_vulkan.h | 13 +- 2 files changed, 77 insertions(+), 61 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc index cc27836c..b7aef553 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -16,6 +16,7 @@ ExternalTexturePixelVulkan::ExternalTexturePixelVulkan( vulkan_renderer_(vulkan_renderer) {} ExternalTexturePixelVulkan::~ExternalTexturePixelVulkan() { + ReleaseBuffer(); ReleaseImage(); } @@ -36,40 +37,56 @@ bool ExternalTexturePixelVulkan::PopulateVulkanTexture( return false; } - if (!CreateOrUpdateImage(pixel_buffer)) { + if (!CreateOrUpdateImage(pixel_buffer->width, pixel_buffer->height)) { FT_LOG(Error) << "Fail to create image"; ReleaseImage(); return false; } - width_ = pixel_buffer->width; - height_ = pixel_buffer->height; - if (!CreateBuffer(width, height)) { + VkDeviceSize required_staging_size = + pixel_buffer->width * pixel_buffer->height * 4; + if (!CreateOrUpdateBuffer(required_staging_size)) { + FT_LOG(Error) << "Fail to create buffer"; + ReleaseBuffer(); return false; } - CopyBufferToImage(staging_buffer_, vk_image_, width_, height_, - pixel_buffer->buffer); + width_ = pixel_buffer->width; + height_ = pixel_buffer->height; + + CopyBufferToImage(pixel_buffer->buffer, required_staging_size); - ReleaseBuffer(); FlutterVulkanTexture* vulkan_texture = static_cast(flutter_texture); vulkan_texture->image = reinterpret_cast(vk_image_); vulkan_texture->format = VK_FORMAT_R8G8B8A8_UNORM; - vulkan_texture->width = width; - vulkan_texture->height = height; + vulkan_texture->width = width_; + vulkan_texture->height = height_; return true; } -bool ExternalTexturePixelVulkan::CreateOrUpdateImage( - const FlutterDesktopPixelBuffer* pixel_buffer) { +bool ExternalTexturePixelVulkan::CreateOrUpdateBuffer( + VkDeviceSize required_size) { + if (staging_buffer_ == VK_NULL_HANDLE) { + return CreateBuffer(required_size); + } + + if (required_size > staging_buffer_size_) { + ReleaseBuffer(); + return CreateBuffer(required_size); + } + return true; +} + +bool ExternalTexturePixelVulkan::CreateOrUpdateImage(size_t width, + size_t height) { if (vk_image_ == VK_NULL_HANDLE) { - return CreateImage(pixel_buffer->width, pixel_buffer->height); + return CreateImage(width, height); } - if (pixel_buffer->width != width_ || pixel_buffer->height != height_) { + if (width != width_ || height != height_) { ReleaseImage(); - return CreateImage(pixel_buffer->width, pixel_buffer->height); + return CreateImage(width, height); } return true; } @@ -99,20 +116,10 @@ bool ExternalTexturePixelVulkan::CreateImage(size_t width, size_t height) { vkGetImageMemoryRequirements( static_cast(vulkan_renderer_->GetDeviceHandle()), vk_image_, &memory_requirements); - uint32_t memory_type_index; - if (!FindMemoryType(memory_requirements.memoryTypeBits, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_type_index)) { - return false; - } - VkMemoryAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = memory_type_index; - if (vkAllocateMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - &alloc_info, nullptr, &vk_image_memory_) != VK_SUCCESS) { - FT_LOG(Error) << "Fail to allocate memory"; + if (!AllocateMemory(memory_requirements, vk_image_memory_, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { + FT_LOG(Error) << "Fail to allocate image memory"; return false; } @@ -146,10 +153,10 @@ bool ExternalTexturePixelVulkan::FindMemoryType( return false; } -bool ExternalTexturePixelVulkan::CreateBuffer(size_t width, size_t height) { +bool ExternalTexturePixelVulkan::CreateBuffer(VkDeviceSize required_size) { VkBufferCreateInfo buffer_info{}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buffer_info.size = width * height * 4; + buffer_info.size = required_size; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -163,23 +170,11 @@ bool ExternalTexturePixelVulkan::CreateBuffer(size_t width, size_t height) { vkGetBufferMemoryRequirements( static_cast(vulkan_renderer_->GetDeviceHandle()), staging_buffer_, &memory_requirements); - uint32_t memory_type_index; - if (!FindMemoryType(memory_requirements.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - memory_type_index)) { - FT_LOG(Error) << "Fail to find memory type"; - return false; - } - VkMemoryAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = memory_type_index; - if (vkAllocateMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - &alloc_info, nullptr, &staging_buffer_memory_) != VK_SUCCESS) { - FT_LOG(Error) << "Fail to allocate memory"; + if (!AllocateMemory(memory_requirements, staging_buffer_memory_, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { + FT_LOG(Error) << "Fail to allocate buffer memory"; return false; } @@ -189,6 +184,7 @@ bool ExternalTexturePixelVulkan::CreateBuffer(size_t width, size_t height) { FT_LOG(Error) << "Fail to bind buffer memory"; return false; } + staging_buffer_size_ = required_size; return true; } @@ -204,17 +200,14 @@ void ExternalTexturePixelVulkan::ReleaseBuffer() { staging_buffer_memory_ = VK_NULL_HANDLE; } + staging_buffer_size_ = 0; } -void ExternalTexturePixelVulkan::CopyBufferToImage(VkBuffer dst_buffer, - VkImage image, - uint32_t width, - uint32_t height, - const uint8_t* src_buffer) { +void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, VkDeviceSize size) { void* data; vkMapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_memory_, 0, width * height * 4, 0, &data); - memcpy(data, src_buffer, static_cast(width * height * 4)); + staging_buffer_memory_, 0, size, 0, &data); + memcpy(data, src_buffer, static_cast(size)); vkUnmapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), staging_buffer_memory_); VkCommandBuffer command_buffer = vulkan_renderer_->BeginSingleTimeCommands(); @@ -228,9 +221,9 @@ void ExternalTexturePixelVulkan::CopyBufferToImage(VkBuffer dst_buffer, region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; region.imageOffset = {0, 0, 0}; - region.imageExtent = {width, height, 1}; + region.imageExtent = {width_, height_, 1}; - vkCmdCopyBufferToImage(command_buffer, dst_buffer, image, + vkCmdCopyBufferToImage(command_buffer, staging_buffer_, vk_image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); vulkan_renderer_->EndSingleTimeCommands(command_buffer); @@ -250,4 +243,28 @@ void ExternalTexturePixelVulkan::ReleaseImage() { } } +bool ExternalTexturePixelVulkan::AllocateMemory( + const VkMemoryRequirements& memory_requirements, + VkDeviceMemory& memory, + VkMemoryPropertyFlags properties) { + uint32_t memory_type_index; + if (!FindMemoryType(memory_requirements.memoryTypeBits, properties, + memory_type_index)) { + FT_LOG(Error) << "Fail to find memory type"; + return false; + } + VkMemoryAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = memory_requirements.size; + alloc_info.memoryTypeIndex = memory_type_index; + + if (vkAllocateMemory( + static_cast(vulkan_renderer_->GetDeviceHandle()), + &alloc_info, nullptr, &memory) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + return true; +} + } // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h index b2699fe6..4a7ef49c 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h @@ -25,14 +25,12 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture { FlutterVulkanTexture* flutter_texture) override; private: - bool CreateBuffer(size_t width, size_t height); + bool AllocateMemory(const VkMemoryRequirements& memory_requirements, VkDeviceMemory& memory, VkMemoryPropertyFlags properties); + bool CreateBuffer(VkDeviceSize required_size); bool CreateImage(size_t width, size_t height); - bool CreateOrUpdateImage(const FlutterDesktopPixelBuffer* pixel_buffer); - void CopyBufferToImage(VkBuffer dst_buffer, - VkImage image, - uint32_t width, - uint32_t height, - const uint8_t* src_buffer); + bool CreateOrUpdateBuffer(VkDeviceSize required_size); + bool CreateOrUpdateImage(size_t width, size_t height); + void CopyBufferToImage(const uint8_t* src_buffer, VkDeviceSize size); void ReleaseBuffer(); void ReleaseImage(); bool FindMemoryType(uint32_t typeFilter, @@ -47,6 +45,7 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture { VkDeviceMemory vk_image_memory_ = VK_NULL_HANDLE; VkBuffer staging_buffer_ = VK_NULL_HANDLE; VkDeviceMemory staging_buffer_memory_ = VK_NULL_HANDLE; + VkDeviceSize staging_buffer_size_ = 0; }; } // namespace flutter From f4403ec8afbdcea7558c089ed2bb51f437ad4454 Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Sun, 28 Sep 2025 15:12:02 +0800 Subject: [PATCH 03/14] Fix format issue --- .../shell/platform/tizen/external_texture_pixel_vulkan.cc | 7 ++++--- .../shell/platform/tizen/external_texture_pixel_vulkan.h | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc index b7aef553..db8ac6cb 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -69,8 +69,8 @@ bool ExternalTexturePixelVulkan::CreateOrUpdateBuffer( VkDeviceSize required_size) { if (staging_buffer_ == VK_NULL_HANDLE) { return CreateBuffer(required_size); - } - + } + if (required_size > staging_buffer_size_) { ReleaseBuffer(); return CreateBuffer(required_size); @@ -203,7 +203,8 @@ void ExternalTexturePixelVulkan::ReleaseBuffer() { staging_buffer_size_ = 0; } -void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, VkDeviceSize size) { +void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, + VkDeviceSize size) { void* data; vkMapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), staging_buffer_memory_, 0, size, 0, &data); diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h index 4a7ef49c..606549a0 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h @@ -25,7 +25,9 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture { FlutterVulkanTexture* flutter_texture) override; private: - bool AllocateMemory(const VkMemoryRequirements& memory_requirements, VkDeviceMemory& memory, VkMemoryPropertyFlags properties); + bool AllocateMemory(const VkMemoryRequirements& memory_requirements, + VkDeviceMemory& memory, + VkMemoryPropertyFlags properties); bool CreateBuffer(VkDeviceSize required_size); bool CreateImage(size_t width, size_t height); bool CreateOrUpdateBuffer(VkDeviceSize required_size); From 8f206d37cb0fd913a752373c6a4c527ac3c5c99a Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Sun, 28 Sep 2025 17:31:25 +0800 Subject: [PATCH 04/14] Fix some code review issues --- .../platform/tizen/external_texture_surface_vulkan.cc | 9 +++++---- .../tizen/external_texture_surface_vulkan_buffer.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 1dca30c3..322be255 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -31,7 +31,8 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( reinterpret_cast(descriptor->handle); if (!vulkan_buffer_) { if (IsSupportDisjoint(tbm_surface)) { - /** + /** TODO as I konw, skia doesn't support disjoint,we need consider to + * implement buffer map solution. vulkan_buffer_ = std::make_unique( vulkan_renderer_); */ @@ -53,17 +54,17 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( } if (!vulkan_buffer_->CreateImage(tbm_surface)) { FT_LOG(Error) << "Fail to create image"; - vulkan_buffer_->ReleaseImage(); + vulkan_buffer_.reset(); return false; } if (!vulkan_buffer_->AllocateMemory(tbm_surface)) { FT_LOG(Error) << "Fail to allocate memory"; - vulkan_buffer_->ReleaseImage(); + vulkan_buffer_.reset(); return false; } if (!vulkan_buffer_->BindImageMemory(tbm_surface)) { FT_LOG(Error) << "Fail to bind image memory"; - vulkan_buffer_->ReleaseImage(); + vulkan_buffer_.reset(); return false; } last_surface_handle_ = handle; diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h index 119a7ffd..27899c17 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -41,4 +41,4 @@ class ExternalTextureSurfaceVulkanBuffer { }; } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_H_ +#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_H_ From f9f71efbebbbe29054a944f391de980f2d8f03c3 Mon Sep 17 00:00:00 2001 From: gin7773 <94502163+gin7773@users.noreply.github.com> Date: Wed, 12 Nov 2025 14:20:37 +0800 Subject: [PATCH 05/14] modify_code (#7) * modify_code * Type conversion * code format --- .../tizen/external_texture_pixel_vulkan.cc | 3 +- .../tizen/external_texture_surface_vulkan.cc | 11 +++- .../external_texture_surface_vulkan_buffer.cc | 17 ++---- .../external_texture_surface_vulkan_buffer.h | 2 +- ...ernal_texture_surface_vulkan_buffer_dma.cc | 57 ++++++++----------- ...ternal_texture_surface_vulkan_buffer_dma.h | 3 +- 6 files changed, 43 insertions(+), 50 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc index db8ac6cb..bba207c8 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -222,7 +222,8 @@ void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; region.imageOffset = {0, 0, 0}; - region.imageExtent = {width_, height_, 1}; + region.imageExtent = {static_cast(width_), + static_cast(height_), 1}; vkCmdCopyBufferToImage(command_buffer, staging_buffer_, vk_image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 322be255..452d08a0 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -27,8 +27,9 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( } return false; } - const tbm_surface_h tbm_surface = - reinterpret_cast(descriptor->handle); + + void* handle = descriptor->handle; + const tbm_surface_h tbm_surface = reinterpret_cast(handle); if (!vulkan_buffer_) { if (IsSupportDisjoint(tbm_surface)) { /** TODO as I konw, skia doesn't support disjoint,we need consider to @@ -41,7 +42,7 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( vulkan_renderer_); } } - void* handle = descriptor->handle; + if (handle != last_surface_handle_) { vulkan_buffer_->ReleaseImage(); tbm_surface_info_s tbm_surface_info; @@ -78,6 +79,10 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( bool ExternalTextureSurfaceVulkan::IsSupportDisjoint( tbm_surface_h tbm_surface) { int num_bos = tbm_surface_internal_get_num_bos(tbm_surface); + if (num_bos <= 1) { + return false; + } + bool is_disjoint = false; uint32_t tfd[num_bos]; for (int i = 0; i < num_bos; i++) { diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc index 8d09b007..d383e9de 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc @@ -33,9 +33,9 @@ VkFormat ExternalTextureSurfaceVulkanBuffer::ConvertFormat(tbm_format& format) { } } -bool ExternalTextureSurfaceVulkanBuffer::FindProperties( - uint32_t memory_type_bits_requirement, - VkMemoryPropertyFlags required_properties, +bool ExternalTextureSurfaceVulkanBuffer::FindMemoryType( + uint32_t type_filter, + VkMemoryPropertyFlags properties, uint32_t& index_out) { VkPhysicalDeviceMemoryProperties memory_properties; vkGetPhysicalDeviceMemoryProperties( @@ -44,14 +44,9 @@ bool ExternalTextureSurfaceVulkanBuffer::FindProperties( &memory_properties); for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { - const uint32_t memory_type_bits = (1 << i); - const bool isRequiredMemoryType = - memory_type_bits_requirement & memory_type_bits; - const VkMemoryPropertyFlags properties = - memory_properties.memoryTypes[i].propertyFlags; - const bool has_required_properties = - (properties & required_properties) == required_properties; - if (isRequiredMemoryType && has_required_properties) { + if ((type_filter & (1 << i)) && + (memory_properties.memoryTypes[i].propertyFlags & properties) == + properties) { index_out = i; return true; } diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h index 27899c17..2cb559db 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -32,7 +32,7 @@ class ExternalTextureSurfaceVulkanBuffer { protected: VkFormat ConvertFormat(tbm_format& format); - bool FindProperties(uint32_t memory_type_bits_requirement, + bool FindMemoryType(uint32_t memory_type_bits_requirement, VkMemoryPropertyFlags required_properties, uint32_t& index_out); diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc index 35698e40..8dcf2d1a 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -13,8 +13,15 @@ namespace flutter { ExternalTextureSurfaceVulkanBufferDma::ExternalTextureSurfaceVulkanBufferDma( TizenRendererVulkan* vulkan_renderer) - : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer), - vulkan_renderer_(vulkan_renderer) {} + : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer) { + device_ = static_cast(vulkan_renderer->GetDeviceHandle()); + getMemoryFdPropertiesKHR_ = + (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( + device_, "vkGetMemoryFdPropertiesKHR"); + if (!getMemoryFdPropertiesKHR_) { + FT_LOG(Error) << "Fail to get vkGetMemoryFdPropertiesKHR"; + } +} ExternalTextureSurfaceVulkanBufferDma:: ~ExternalTextureSurfaceVulkanBufferDma() { @@ -33,20 +40,6 @@ VkDeviceMemory ExternalTextureSurfaceVulkanBufferDma::GetMemory() { return texture_device_memory_; } -VkResult GetMemoryFdPropertiesKHR( - VkDevice device, - VkExternalMemoryHandleTypeFlagBits handleType, - int fd, - VkMemoryFdPropertiesKHR* pMemoryFdProperties) { - auto func = (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( - device, "vkGetMemoryFdPropertiesKHR"); - if (func != nullptr) { - return func(device, handleType, fd, pMemoryFdProperties); - } else { - return VK_ERROR_EXTENSION_NOT_PRESENT; - } -} - bool ExternalTextureSurfaceVulkanBufferDma::CreateImage( tbm_surface_h tbm_surface) { tbm_surface_info_s tbm_surface_info; @@ -76,9 +69,8 @@ bool ExternalTextureSurfaceVulkanBufferDma::CreateImage( image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; image_create_info.pNext = &external_image_create_info; - if (vkCreateImage(static_cast(vulkan_renderer_->GetDeviceHandle()), - &image_create_info, nullptr, - &texture_image_) != VK_SUCCESS) { + if (vkCreateImage(device_, &image_create_info, nullptr, &texture_image_) != + VK_SUCCESS) { FT_LOG(Error) << "Fail to create VkImage"; return false; } @@ -88,13 +80,16 @@ bool ExternalTextureSurfaceVulkanBufferDma::CreateImage( bool ExternalTextureSurfaceVulkanBufferDma::GetFdMemoryTypeIndex( int fd, uint32_t& index_out) { + if (!getMemoryFdPropertiesKHR_) { + return false; + } + VkMemoryFdPropertiesKHR memory_fd_properties = {}; memory_fd_properties.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR; - if (GetMemoryFdPropertiesKHR( - static_cast(vulkan_renderer_->GetDeviceHandle()), - VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, fd, - &memory_fd_properties) != VK_SUCCESS) { + if (getMemoryFdPropertiesKHR_(device_, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + fd, &memory_fd_properties) != VK_SUCCESS) { FT_LOG(Error) << "Fail to get memory fd properties"; return false; } @@ -132,9 +127,8 @@ bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( alloc_info.pNext = &import_memory_fd_info; alloc_info.allocationSize = static_cast(bo_size); alloc_info.memoryTypeIndex = memory_type_index; - if (vkAllocateMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - &alloc_info, nullptr, &texture_device_memory_) != VK_SUCCESS) { + if (vkAllocateMemory(device_, &alloc_info, nullptr, + &texture_device_memory_) != VK_SUCCESS) { FT_LOG(Error) << "Fail to allocate memory"; return false; } @@ -143,9 +137,8 @@ bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( tbm_surface_h tbm_surface) { - if (vkBindImageMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - texture_image_, texture_device_memory_, 0u) != VK_SUCCESS) { + if (vkBindImageMemory(device_, texture_image_, texture_device_memory_, 0u) != + VK_SUCCESS) { FT_LOG(Error) << "Fail to bind image memory"; return false; } @@ -154,13 +147,11 @@ bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( void ExternalTextureSurfaceVulkanBufferDma::ReleaseImage() { if (texture_image_ != VK_NULL_HANDLE) { - vkDestroyImage(static_cast(vulkan_renderer_->GetDeviceHandle()), - texture_image_, nullptr); + vkDestroyImage(device_, texture_image_, nullptr); texture_image_ = VK_NULL_HANDLE; } if (texture_device_memory_ != VK_NULL_HANDLE) { - vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - texture_device_memory_, nullptr); + vkFreeMemory(device_, texture_device_memory_, nullptr); texture_device_memory_ = VK_NULL_HANDLE; } } diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h index 24a7962d..e5f45b09 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h @@ -27,10 +27,11 @@ class ExternalTextureSurfaceVulkanBufferDma private: bool GetFdMemoryTypeIndex(int fd, uint32_t& index_out); - TizenRendererVulkan* vulkan_renderer_ = nullptr; VkFormat texture_format_ = VK_FORMAT_UNDEFINED; VkImage texture_image_ = VK_NULL_HANDLE; VkDeviceMemory texture_device_memory_ = VK_NULL_HANDLE; + PFN_vkGetMemoryFdPropertiesKHR getMemoryFdPropertiesKHR_ = nullptr; + VkDevice device_; }; } // namespace flutter From 78c122bae02438a83851fc83ebe0d0a0f40968f1 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Fri, 14 Nov 2025 10:30:35 +0800 Subject: [PATCH 06/14] Move render texture code to experimental --- flutter/shell/platform/tizen/BUILD.gn | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/flutter/shell/platform/tizen/BUILD.gn b/flutter/shell/platform/tizen/BUILD.gn index f280025c..c6352022 100644 --- a/flutter/shell/platform/tizen/BUILD.gn +++ b/flutter/shell/platform/tizen/BUILD.gn @@ -90,12 +90,8 @@ template("embedder") { "channels/window_channel.cc", "external_texture_pixel_egl.cc", "external_texture_pixel_egl_impeller.cc", - "external_texture_pixel_vulkan.cc", "external_texture_surface_egl.cc", "external_texture_surface_egl_impeller.cc", - "external_texture_surface_vulkan.cc", - "external_texture_surface_vulkan_buffer.cc", - "external_texture_surface_vulkan_buffer_dma.cc", "flutter_platform_node_delegate_tizen.cc", "flutter_project_bundle.cc", "flutter_tizen.cc", @@ -161,7 +157,13 @@ template("embedder") { target_name == "flutter_tizen_tv_experimental" || target_name == "flutter_tizen_common_experimental") { defines += [ "FLUTTER_TIZEN_EXPERIMENTAL" ] - sources += [ "tizen_renderer_vulkan.cc" ] + sources += [ + "external_texture_pixel_vulkan.cc", + "external_texture_surface_vulkan.cc", + "external_texture_surface_vulkan_buffer.cc", + "external_texture_surface_vulkan_buffer_dma.cc", + "tizen_renderer_vulkan.cc", + ] libs += [ "vulkan" ] } From 831538941137605a502c3cafee5cb4a24a93bf83 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Sat, 15 Nov 2025 08:53:01 +0800 Subject: [PATCH 07/14] Minor refactor 1.Add GetDevice method insted of device_ variable. 2.Refactor variable name for pixel buffer. 3.Add GetMemoryFDProperty method insted of variable. --- .../tizen/external_texture_pixel_vulkan.cc | 68 ++++++++----------- .../tizen/external_texture_pixel_vulkan.h | 7 +- .../external_texture_surface_vulkan_buffer.cc | 4 ++ .../external_texture_surface_vulkan_buffer.h | 3 +- ...ernal_texture_surface_vulkan_buffer_dma.cc | 54 +++++++-------- ...ternal_texture_surface_vulkan_buffer_dma.h | 9 ++- flutter/shell/platform/tizen/flutter_tizen.cc | 4 +- 7 files changed, 74 insertions(+), 75 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc index bba207c8..2cf0d12e 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -58,7 +58,7 @@ bool ExternalTexturePixelVulkan::PopulateVulkanTexture( FlutterVulkanTexture* vulkan_texture = static_cast(flutter_texture); - vulkan_texture->image = reinterpret_cast(vk_image_); + vulkan_texture->image = reinterpret_cast(image_); vulkan_texture->format = VK_FORMAT_R8G8B8A8_UNORM; vulkan_texture->width = width_; vulkan_texture->height = height_; @@ -80,7 +80,7 @@ bool ExternalTexturePixelVulkan::CreateOrUpdateBuffer( bool ExternalTexturePixelVulkan::CreateOrUpdateImage(size_t width, size_t height) { - if (vk_image_ == VK_NULL_HANDLE) { + if (image_ == VK_NULL_HANDLE) { return CreateImage(width, height); } @@ -107,25 +107,20 @@ bool ExternalTexturePixelVulkan::CreateImage(size_t width, size_t height) { VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - if (vkCreateImage(static_cast(vulkan_renderer_->GetDeviceHandle()), - &image_info, nullptr, &vk_image_) != VK_SUCCESS) { + if (vkCreateImage(GetDevice(), &image_info, nullptr, &image_) != VK_SUCCESS) { FT_LOG(Error) << "Fail to create VkImage"; return false; } VkMemoryRequirements memory_requirements; - vkGetImageMemoryRequirements( - static_cast(vulkan_renderer_->GetDeviceHandle()), vk_image_, - &memory_requirements); + vkGetImageMemoryRequirements(GetDevice(), image_, &memory_requirements); - if (!AllocateMemory(memory_requirements, vk_image_memory_, + if (!AllocateMemory(memory_requirements, image_memory_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { FT_LOG(Error) << "Fail to allocate image memory"; return false; } - if (vkBindImageMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), vk_image_, - vk_image_memory_, 0) != VK_SUCCESS) { + if (vkBindImageMemory(GetDevice(), image_, image_memory_, 0) != VK_SUCCESS) { FT_LOG(Error) << "Fail to bind image memory"; return false; } @@ -160,16 +155,15 @@ bool ExternalTexturePixelVulkan::CreateBuffer(VkDeviceSize required_size) { buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - if (vkCreateBuffer(static_cast(vulkan_renderer_->GetDeviceHandle()), - &buffer_info, nullptr, &staging_buffer_) != VK_SUCCESS) { + if (vkCreateBuffer(GetDevice(), &buffer_info, nullptr, &staging_buffer_) != + VK_SUCCESS) { FT_LOG(Error) << "Fail to create vkBuffer"; return false; } VkMemoryRequirements memory_requirements; - vkGetBufferMemoryRequirements( - static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_, &memory_requirements); + vkGetBufferMemoryRequirements(GetDevice(), staging_buffer_, + &memory_requirements); if (!AllocateMemory(memory_requirements, staging_buffer_memory_, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | @@ -178,9 +172,8 @@ bool ExternalTexturePixelVulkan::CreateBuffer(VkDeviceSize required_size) { return false; } - if (vkBindBufferMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_, staging_buffer_memory_, 0) != VK_SUCCESS) { + if (vkBindBufferMemory(GetDevice(), staging_buffer_, staging_buffer_memory_, + 0) != VK_SUCCESS) { FT_LOG(Error) << "Fail to bind buffer memory"; return false; } @@ -190,13 +183,11 @@ bool ExternalTexturePixelVulkan::CreateBuffer(VkDeviceSize required_size) { void ExternalTexturePixelVulkan::ReleaseBuffer() { if (staging_buffer_ != VK_NULL_HANDLE) { - vkDestroyBuffer(static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_, nullptr); + vkDestroyBuffer(GetDevice(), staging_buffer_, nullptr); staging_buffer_ = VK_NULL_HANDLE; } if (staging_buffer_memory_ != VK_NULL_HANDLE) { - vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_memory_, nullptr); + vkFreeMemory(GetDevice(), staging_buffer_memory_, nullptr); staging_buffer_memory_ = VK_NULL_HANDLE; } @@ -206,11 +197,9 @@ void ExternalTexturePixelVulkan::ReleaseBuffer() { void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, VkDeviceSize size) { void* data; - vkMapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_memory_, 0, size, 0, &data); + vkMapMemory(GetDevice(), staging_buffer_memory_, 0, size, 0, &data); memcpy(data, src_buffer, static_cast(size)); - vkUnmapMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - staging_buffer_memory_); + vkUnmapMemory(GetDevice(), staging_buffer_memory_); VkCommandBuffer command_buffer = vulkan_renderer_->BeginSingleTimeCommands(); VkBufferImageCopy region{}; @@ -225,23 +214,21 @@ void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, region.imageExtent = {static_cast(width_), static_cast(height_), 1}; - vkCmdCopyBufferToImage(command_buffer, staging_buffer_, vk_image_, + vkCmdCopyBufferToImage(command_buffer, staging_buffer_, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); vulkan_renderer_->EndSingleTimeCommands(command_buffer); } void ExternalTexturePixelVulkan::ReleaseImage() { - if (vk_image_ != VK_NULL_HANDLE) { - vkDestroyImage(static_cast(vulkan_renderer_->GetDeviceHandle()), - vk_image_, nullptr); - vk_image_ = VK_NULL_HANDLE; + if (image_ != VK_NULL_HANDLE) { + vkDestroyImage(GetDevice(), image_, nullptr); + image_ = VK_NULL_HANDLE; } - if (vk_image_memory_ != VK_NULL_HANDLE) { - vkFreeMemory(static_cast(vulkan_renderer_->GetDeviceHandle()), - vk_image_memory_, nullptr); - vk_image_memory_ = VK_NULL_HANDLE; + if (image_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(GetDevice(), image_memory_, nullptr); + image_memory_ = VK_NULL_HANDLE; } } @@ -260,13 +247,16 @@ bool ExternalTexturePixelVulkan::AllocateMemory( alloc_info.allocationSize = memory_requirements.size; alloc_info.memoryTypeIndex = memory_type_index; - if (vkAllocateMemory( - static_cast(vulkan_renderer_->GetDeviceHandle()), - &alloc_info, nullptr, &memory) != VK_SUCCESS) { + if (vkAllocateMemory(GetDevice(), &alloc_info, nullptr, &memory) != + VK_SUCCESS) { FT_LOG(Error) << "Fail to allocate memory"; return false; } return true; } +VkDevice ExternalTexturePixelVulkan::GetDevice() { + return static_cast(vulkan_renderer_->GetDeviceHandle()); +} + } // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h index 606549a0..ce10f0f0 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h @@ -1,4 +1,4 @@ -// Copyright 2024 Samsung Electronics Co., Ltd. All rights reserved. +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -33,6 +33,7 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture { bool CreateOrUpdateBuffer(VkDeviceSize required_size); bool CreateOrUpdateImage(size_t width, size_t height); void CopyBufferToImage(const uint8_t* src_buffer, VkDeviceSize size); + VkDevice GetDevice(); void ReleaseBuffer(); void ReleaseImage(); bool FindMemoryType(uint32_t typeFilter, @@ -43,8 +44,8 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture { size_t height_ = 0; void* user_data_ = nullptr; TizenRendererVulkan* vulkan_renderer_ = nullptr; - VkImage vk_image_ = VK_NULL_HANDLE; - VkDeviceMemory vk_image_memory_ = VK_NULL_HANDLE; + VkImage image_ = VK_NULL_HANDLE; + VkDeviceMemory image_memory_ = VK_NULL_HANDLE; VkBuffer staging_buffer_ = VK_NULL_HANDLE; VkDeviceMemory staging_buffer_memory_ = VK_NULL_HANDLE; VkDeviceSize staging_buffer_size_ = 0; diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc index d383e9de..40f4f38c 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc @@ -54,4 +54,8 @@ bool ExternalTextureSurfaceVulkanBuffer::FindMemoryType( return false; } +VkDevice ExternalTextureSurfaceVulkanBuffer::GetDevice() { + return static_cast(vulkan_renderer_->GetDeviceHandle()); +} + } // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h index 2cb559db..e941233e 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -1,4 +1,4 @@ -// Copyright 2024 Samsung Electronics Co., Ltd. All rights reserved. +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,6 +32,7 @@ class ExternalTextureSurfaceVulkanBuffer { protected: VkFormat ConvertFormat(tbm_format& format); + VkDevice GetDevice(); bool FindMemoryType(uint32_t memory_type_bits_requirement, VkMemoryPropertyFlags required_properties, uint32_t& index_out); diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc index 8dcf2d1a..49186fff 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -5,23 +5,11 @@ #include "flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h" #include "flutter/shell/platform/tizen/logger.h" -#ifndef DRM_FORMAT_MOD_LINEAR -#define DRM_FORMAT_MOD_LINEAR 0 -#endif - namespace flutter { ExternalTextureSurfaceVulkanBufferDma::ExternalTextureSurfaceVulkanBufferDma( TizenRendererVulkan* vulkan_renderer) - : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer) { - device_ = static_cast(vulkan_renderer->GetDeviceHandle()); - getMemoryFdPropertiesKHR_ = - (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( - device_, "vkGetMemoryFdPropertiesKHR"); - if (!getMemoryFdPropertiesKHR_) { - FT_LOG(Error) << "Fail to get vkGetMemoryFdPropertiesKHR"; - } -} + : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer) {} ExternalTextureSurfaceVulkanBufferDma:: ~ExternalTextureSurfaceVulkanBufferDma() { @@ -69,27 +57,38 @@ bool ExternalTextureSurfaceVulkanBufferDma::CreateImage( image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; image_create_info.pNext = &external_image_create_info; - if (vkCreateImage(device_, &image_create_info, nullptr, &texture_image_) != - VK_SUCCESS) { + if (vkCreateImage(GetDevice(), &image_create_info, nullptr, + &texture_image_) != VK_SUCCESS) { FT_LOG(Error) << "Fail to create VkImage"; return false; } return true; } -bool ExternalTextureSurfaceVulkanBufferDma::GetFdMemoryTypeIndex( +VkResult ExternalTextureSurfaceVulkanBufferDma::GetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, int fd, - uint32_t& index_out) { - if (!getMemoryFdPropertiesKHR_) { - return false; + VkMemoryFdPropertiesKHR* pMemoryFdProperties) { + PFN_vkGetMemoryFdPropertiesKHR pfn_memory_fd_properties = + (PFN_vkGetMemoryFdPropertiesKHR)vkGetDeviceProcAddr( + GetDevice(), "vkGetMemoryFdPropertiesKHR"); + if (!pfn_memory_fd_properties) { + FT_LOG(Error) << "Fail to get vkGetMemoryFdPropertiesKHR"; + return VK_ERROR_UNKNOWN; } + return pfn_memory_fd_properties(device, handleType, fd, pMemoryFdProperties); +} +bool ExternalTextureSurfaceVulkanBufferDma::GetFdMemoryTypeIndex( + int fd, + uint32_t& index_out) { VkMemoryFdPropertiesKHR memory_fd_properties = {}; memory_fd_properties.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR; - if (getMemoryFdPropertiesKHR_(device_, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - fd, &memory_fd_properties) != VK_SUCCESS) { + if (GetMemoryFdPropertiesKHR(GetDevice(), + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + fd, &memory_fd_properties) != VK_SUCCESS) { FT_LOG(Error) << "Fail to get memory fd properties"; return false; } @@ -127,7 +126,7 @@ bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( alloc_info.pNext = &import_memory_fd_info; alloc_info.allocationSize = static_cast(bo_size); alloc_info.memoryTypeIndex = memory_type_index; - if (vkAllocateMemory(device_, &alloc_info, nullptr, + if (vkAllocateMemory(GetDevice(), &alloc_info, nullptr, &texture_device_memory_) != VK_SUCCESS) { FT_LOG(Error) << "Fail to allocate memory"; return false; @@ -137,8 +136,8 @@ bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( tbm_surface_h tbm_surface) { - if (vkBindImageMemory(device_, texture_image_, texture_device_memory_, 0u) != - VK_SUCCESS) { + if (vkBindImageMemory(GetDevice(), texture_image_, texture_device_memory_, + 0u) != VK_SUCCESS) { FT_LOG(Error) << "Fail to bind image memory"; return false; } @@ -147,12 +146,13 @@ bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( void ExternalTextureSurfaceVulkanBufferDma::ReleaseImage() { if (texture_image_ != VK_NULL_HANDLE) { - vkDestroyImage(device_, texture_image_, nullptr); + vkDestroyImage(GetDevice(), texture_image_, nullptr); texture_image_ = VK_NULL_HANDLE; } if (texture_device_memory_ != VK_NULL_HANDLE) { - vkFreeMemory(device_, texture_device_memory_, nullptr); + vkFreeMemory(GetDevice(), texture_device_memory_, nullptr); texture_device_memory_ = VK_NULL_HANDLE; } } + } // namespace flutter diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h index e5f45b09..e6e12b5c 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h @@ -1,4 +1,4 @@ -// Copyright 2024 Samsung Electronics Co., Ltd. All rights reserved. +// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,11 +27,14 @@ class ExternalTextureSurfaceVulkanBufferDma private: bool GetFdMemoryTypeIndex(int fd, uint32_t& index_out); + VkResult GetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR* pMemoryFdProperties); VkFormat texture_format_ = VK_FORMAT_UNDEFINED; VkImage texture_image_ = VK_NULL_HANDLE; VkDeviceMemory texture_device_memory_ = VK_NULL_HANDLE; - PFN_vkGetMemoryFdPropertiesKHR getMemoryFdPropertiesKHR_ = nullptr; - VkDevice device_; }; } // namespace flutter diff --git a/flutter/shell/platform/tizen/flutter_tizen.cc b/flutter/shell/platform/tizen/flutter_tizen.cc index 9615b111..1278f73c 100644 --- a/flutter/shell/platform/tizen/flutter_tizen.cc +++ b/flutter/shell/platform/tizen/flutter_tizen.cc @@ -206,12 +206,12 @@ FlutterDesktopViewRef FlutterDesktopViewCreateFromNewWindow( window_properties.focusable, window_properties.top_level, window_properties.pointing_device_support, window_properties.floating_menu_support, window_properties.window_handle, - window_properties.renderer_type == kEVulkan); + true); auto view = std::make_unique( flutter::kImplicitViewId, std::move(window), std::unique_ptr(EngineFromHandle(engine)), - window_properties.renderer_type, window_properties.user_pixel_ratio); + kEVulkan, window_properties.user_pixel_ratio); if (!view->engine()->IsRunning()) { if (!view->engine()->RunEngine()) { From 3b096a8c12090602c72f87126df95cb8ee7a18c8 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Sat, 15 Nov 2025 09:17:35 +0800 Subject: [PATCH 08/14] Fix build error --- .../tizen/external_texture_surface_vulkan_buffer_dma.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc index 49186fff..d4e71777 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -75,7 +75,7 @@ VkResult ExternalTextureSurfaceVulkanBufferDma::GetMemoryFdPropertiesKHR( GetDevice(), "vkGetMemoryFdPropertiesKHR"); if (!pfn_memory_fd_properties) { FT_LOG(Error) << "Fail to get vkGetMemoryFdPropertiesKHR"; - return VK_ERROR_UNKNOWN; + return VK_ERROR_EXTENSION_NOT_PRESENT; } return pfn_memory_fd_properties(device, handleType, fd, pMemoryFdProperties); } From fc9db028fe15f84889a43a40191babce759eab88 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Tue, 9 Dec 2025 08:49:21 +0800 Subject: [PATCH 09/14] Fix code review issues 1.rename texture callback parameter name. 2.add null check for vulkan texture. 3.rename PopulateOpenGLTexture to PopulateGLTexture. 4.change DRM_FORMAT to vulkan format. --- flutter/shell/platform/tizen/external_texture.h | 6 +++--- .../shell/platform/tizen/external_texture_pixel_egl.cc | 2 +- flutter/shell/platform/tizen/external_texture_pixel_egl.h | 6 +++--- .../platform/tizen/external_texture_pixel_egl_impeller.cc | 2 +- .../platform/tizen/external_texture_pixel_egl_impeller.h | 6 +++--- .../shell/platform/tizen/external_texture_surface_egl.cc | 2 +- .../shell/platform/tizen/external_texture_surface_egl.h | 6 +++--- .../tizen/external_texture_surface_egl_impeller.cc | 2 +- .../tizen/external_texture_surface_egl_impeller.h | 6 +++--- .../platform/tizen/external_texture_surface_vulkan.cc | 5 +++-- .../tizen/external_texture_surface_vulkan_buffer.cc | 6 ++---- .../platform/tizen/flutter_tizen_texture_registrar.cc | 2 +- flutter/shell/platform/tizen/tizen_renderer_vulkan.cc | 8 ++++---- 13 files changed, 29 insertions(+), 30 deletions(-) mode change 100755 => 100644 flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h mode change 100755 => 100644 flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h diff --git a/flutter/shell/platform/tizen/external_texture.h b/flutter/shell/platform/tizen/external_texture.h index 37e046e5..fe697ce6 100644 --- a/flutter/shell/platform/tizen/external_texture.h +++ b/flutter/shell/platform/tizen/external_texture.h @@ -43,9 +43,9 @@ class ExternalGLTexture : public ExternalTexture { state_->gl_extension = gl_extension; } - virtual bool PopulateOpenGLTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) = 0; + virtual bool PopulateGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) = 0; protected: std::unique_ptr state_; diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl.cc b/flutter/shell/platform/tizen/external_texture_pixel_egl.cc index 3e150699..a847a452 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl.cc @@ -11,7 +11,7 @@ namespace flutter { -bool ExternalTexturePixelEGL::PopulateOpenGLTexture( +bool ExternalTexturePixelEGL::PopulateGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl.h b/flutter/shell/platform/tizen/external_texture_pixel_egl.h index fa9fe2b8..1a7c4360 100644 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl.h @@ -19,9 +19,9 @@ class ExternalTexturePixelEGL : public ExternalGLTexture { ~ExternalTexturePixelEGL() = default; - bool PopulateOpenGLTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; bool CopyPixelBuffer(size_t& width, size_t& height); diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc index 148bdb51..764bef8e 100755 --- a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.cc @@ -11,7 +11,7 @@ namespace flutter { -bool ExternalTexturePixelEGLImpeller::PopulateOpenGLTexture( +bool ExternalTexturePixelEGLImpeller::PopulateGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h old mode 100755 new mode 100644 index 8dd48678..b7116dfc --- a/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h +++ b/flutter/shell/platform/tizen/external_texture_pixel_egl_impeller.h @@ -19,9 +19,9 @@ class ExternalTexturePixelEGLImpeller : public ExternalGLTexture { ~ExternalTexturePixelEGLImpeller() = default; - bool PopulateOpenGLTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl.cc b/flutter/shell/platform/tizen/external_texture_surface_egl.cc index 5d4fbe99..280e9df7 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_egl.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_egl.cc @@ -39,7 +39,7 @@ ExternalTextureSurfaceEGL::~ExternalTextureSurfaceEGL() { } } -bool ExternalTextureSurfaceEGL::PopulateOpenGLTexture( +bool ExternalTextureSurfaceEGL::PopulateGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl.h b/flutter/shell/platform/tizen/external_texture_surface_egl.h index 34d99104..0bd8e9ab 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_egl.h +++ b/flutter/shell/platform/tizen/external_texture_surface_egl.h @@ -27,9 +27,9 @@ class ExternalTextureSurfaceEGL : public ExternalGLTexture { // texture object. // // Returns true on success, false on failure. - bool PopulateOpenGLTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: FlutterDesktopGpuSurfaceTextureCallback texture_callback_ = nullptr; diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc index 86820aac..3fcbfd4a 100755 --- a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.cc @@ -38,7 +38,7 @@ ExternalTextureSurfaceEGLImpeller::~ExternalTextureSurfaceEGLImpeller() { ReleaseImage(); } -bool ExternalTextureSurfaceEGLImpeller::PopulateOpenGLTexture( +bool ExternalTextureSurfaceEGLImpeller::PopulateGLTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { diff --git a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h old mode 100755 new mode 100644 index 0a834532..d03451ab --- a/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h +++ b/flutter/shell/platform/tizen/external_texture_surface_egl_impeller.h @@ -30,9 +30,9 @@ class ExternalTextureSurfaceEGLImpeller : public ExternalGLTexture { // texture object. // // Returns true on success, false on failure. - bool PopulateOpenGLTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) override; + bool PopulateGLTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; private: static bool OnBindCallback(void* user_data); diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 452d08a0..7f8094cf 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -88,8 +88,9 @@ bool ExternalTextureSurfaceVulkan::IsSupportDisjoint( for (int i = 0; i < num_bos; i++) { tbm_bo bo = tbm_surface_internal_get_bo(tbm_surface, i); tfd[i] = tbm_bo_get_handle(bo, TBM_DEVICE_3D).u32; - if (tfd[i] != tfd[0]) + if (tfd[i] != tfd[0]) { is_disjoint = true; + } } return is_disjoint; } @@ -98,7 +99,7 @@ bool ExternalTextureSurfaceVulkan::PopulateVulkanTexture( size_t width, size_t height, FlutterVulkanTexture* vulkan_texture) { - if (!texture_callback_) { + if (!texture_callback_ || !vulkan_texture) { return false; } const FlutterDesktopGpuSurfaceDescriptor* gpu_surface = diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc index 40f4f38c..75d22274 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc @@ -17,15 +17,13 @@ VkFormat ExternalTextureSurfaceVulkanBuffer::ConvertFormat(tbm_format& format) { case TBM_FORMAT_NV21: return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; case TBM_FORMAT_RGBA8888: - case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_ABGR8888: case TBM_FORMAT_RGBX8888: case TBM_FORMAT_XRGB8888: - case TBM_FORMAT_RGB888: return VK_FORMAT_R8G8B8A8_UNORM; - case TBM_FORMAT_BGR888: case TBM_FORMAT_XBGR8888: case TBM_FORMAT_BGRX8888: - case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_ARGB8888: case TBM_FORMAT_BGRA8888: return VK_FORMAT_B8G8R8A8_UNORM; default: diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc index e21eed97..8ae31bb6 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -100,7 +100,7 @@ bool FlutterTizenTextureRegistrar::PopulateOpenGLTexture( } texture = iter->second.get(); } - return dynamic_cast(texture)->PopulateOpenGLTexture( + return dynamic_cast(texture)->PopulateGLTexture( width, height, opengl_texture); } diff --git a/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc b/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc index 86bd9d73..80ac0070 100644 --- a/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc +++ b/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc @@ -180,14 +180,14 @@ FlutterRendererConfig TizenRendererVulkan::GetRendererConfig() { ->Present(image); }; config.vulkan.external_texture_frame_callback = - [](void* user_data, int64_t texture_identifier, size_t width, - size_t height, FlutterVulkanTexture* texture) -> bool { + [](void* user_data, int64_t texture_id, size_t width, size_t height, + FlutterVulkanTexture* texture) -> bool { auto* engine = reinterpret_cast(user_data); if (!engine->view()) { return false; } - return engine->texture_registrar()->PopulateVulkanTexture( - texture_identifier, width, height, texture); + return engine->texture_registrar()->PopulateVulkanTexture(texture_id, width, + height, texture); }; return config; } From 6c96ac6918fb7a5287f65ee34a73c650b96965a1 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Thu, 11 Dec 2025 08:33:18 +0800 Subject: [PATCH 10/14] Revert flutter-tizen code --- flutter/shell/platform/tizen/flutter_tizen.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter/shell/platform/tizen/flutter_tizen.cc b/flutter/shell/platform/tizen/flutter_tizen.cc index 1278f73c..9615b111 100644 --- a/flutter/shell/platform/tizen/flutter_tizen.cc +++ b/flutter/shell/platform/tizen/flutter_tizen.cc @@ -206,12 +206,12 @@ FlutterDesktopViewRef FlutterDesktopViewCreateFromNewWindow( window_properties.focusable, window_properties.top_level, window_properties.pointing_device_support, window_properties.floating_menu_support, window_properties.window_handle, - true); + window_properties.renderer_type == kEVulkan); auto view = std::make_unique( flutter::kImplicitViewId, std::move(window), std::unique_ptr(EngineFromHandle(engine)), - kEVulkan, window_properties.user_pixel_ratio); + window_properties.renderer_type, window_properties.user_pixel_ratio); if (!view->engine()->IsRunning()) { if (!view->engine()->RunEngine()) { From 00124464af342ebc3d80cc82e4ffa8bd29651ec5 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Thu, 11 Dec 2025 11:38:47 +0800 Subject: [PATCH 11/14] Change PopulateOpenGLTexture method name to PoplateGLTexture --- .../platform/tizen/flutter_tizen_texture_registrar.cc | 2 +- .../platform/tizen/flutter_tizen_texture_registrar.h | 8 ++++---- .../tizen/flutter_tizen_texture_registrar_unittests.cc | 2 +- flutter/shell/platform/tizen/tizen_renderer_gl.cc | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc index 8ae31bb6..25ce99b5 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -86,7 +86,7 @@ bool FlutterTizenTextureRegistrar::MarkTextureFrameAvailable( return engine_->MarkExternalTextureFrameAvailable(texture_id); } -bool FlutterTizenTextureRegistrar::PopulateOpenGLTexture( +bool FlutterTizenTextureRegistrar::PopulateGLTexture( int64_t texture_id, size_t width, size_t height, diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h index 76c73a9a..492f81d6 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h @@ -41,10 +41,10 @@ class FlutterTizenTextureRegistrar { // contents of the texture identified by |texture_id|. // // Returns true on success. - bool PopulateOpenGLTexture(int64_t texture_id, - size_t width, - size_t height, - FlutterOpenGLTexture* texture); + bool PopulateGLTexture(int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* texture); bool PopulateVulkanTexture(int64_t texture_id, size_t width, diff --git a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc index eeb4ff72..535bf476 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc @@ -118,7 +118,7 @@ TEST_F(FlutterTizenTextureRegistrarTest, RegisterUnknownTextureType) { TEST_F(FlutterTizenTextureRegistrarTest, PopulateInvalidTexture) { FlutterTizenTextureRegistrar registrar(engine_); - bool result = registrar.PopulateOpenGLTexture(1, 640, 480, nullptr); + bool result = registrar.PopulateGLTexture(1, 640, 480, nullptr); EXPECT_FALSE(result); } diff --git a/flutter/shell/platform/tizen/tizen_renderer_gl.cc b/flutter/shell/platform/tizen/tizen_renderer_gl.cc index 40afc75c..65cefdee 100644 --- a/flutter/shell/platform/tizen/tizen_renderer_gl.cc +++ b/flutter/shell/platform/tizen/tizen_renderer_gl.cc @@ -77,8 +77,8 @@ FlutterRendererConfig TizenRendererGL::GetRendererConfig() { if (!engine->texture_registrar()) { return false; } - return engine->texture_registrar()->PopulateOpenGLTexture(texture_id, width, - height, texture); + return engine->texture_registrar()->PopulateGLTexture(texture_id, width, + height, texture); }; return config; } From 7c263648ca7435f76b5c916cfb250dd713404e47 Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Fri, 12 Dec 2025 08:43:48 +0800 Subject: [PATCH 12/14] Merge CreateImage and BindImage method --- .../tizen/external_texture_surface_vulkan.cc | 84 ++++++++++--------- .../tizen/external_texture_surface_vulkan.h | 3 + .../external_texture_surface_vulkan_buffer.h | 3 +- ...ernal_texture_surface_vulkan_buffer_dma.cc | 7 +- ...ternal_texture_surface_vulkan_buffer_dma.h | 3 +- 5 files changed, 52 insertions(+), 48 deletions(-) diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 7f8094cf..5aa9464c 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -17,55 +17,61 @@ ExternalTextureSurfaceVulkan::ExternalTextureSurfaceVulkan( user_data_(user_data), vulkan_renderer_(vulkan_renderer) {} -ExternalTextureSurfaceVulkan::~ExternalTextureSurfaceVulkan() {} +ExternalTextureSurfaceVulkan::~ExternalTextureSurfaceVulkan() { + ReleaseBuffer(); +} + +bool ExternalTextureSurfaceVulkan::CreateBuffer( + const tbm_surface_h tbm_surface) { + if (IsSupportDisjoint(tbm_surface)) { + /** TODO as I konw, skia doesn't support disjoint,we need consider to + * implement buffer map solution. + vulkan_buffer_ = std::make_unique( + vulkan_renderer_); + */ + } else { + vulkan_buffer_ = std::make_unique( + vulkan_renderer_); + } + + if (!vulkan_buffer_) { + FT_LOG(Error) << "Fail to create ExternalTextureSurfaceVulkanBufferDma"; + return false; + } + + if (!vulkan_buffer_->CreateImage(tbm_surface)) { + FT_LOG(Error) << "Fail to create image"; + return false; + } + if (!vulkan_buffer_->AllocateAndBindMemory(tbm_surface)) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + + return true; +} + +void ExternalTextureSurfaceVulkan::ReleaseBuffer() { + if (vulkan_buffer_) { + vulkan_buffer_->ReleaseImage(); + vulkan_buffer_.reset(); + } +} bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( const FlutterDesktopGpuSurfaceDescriptor* descriptor) { if (descriptor == nullptr || descriptor->handle == nullptr) { - if (vulkan_buffer_) { - vulkan_buffer_->ReleaseImage(); - } + ReleaseBuffer(); return false; } void* handle = descriptor->handle; const tbm_surface_h tbm_surface = reinterpret_cast(handle); - if (!vulkan_buffer_) { - if (IsSupportDisjoint(tbm_surface)) { - /** TODO as I konw, skia doesn't support disjoint,we need consider to - * implement buffer map solution. - vulkan_buffer_ = std::make_unique( - vulkan_renderer_); - */ - } else { - vulkan_buffer_ = std::make_unique( - vulkan_renderer_); - } - } - if (handle != last_surface_handle_) { - vulkan_buffer_->ReleaseImage(); - tbm_surface_info_s tbm_surface_info; - if (tbm_surface_get_info(tbm_surface, &tbm_surface_info) != - TBM_SURFACE_ERROR_NONE) { - if (descriptor->release_callback) { - descriptor->release_callback(descriptor->release_context); - } - return false; - } - if (!vulkan_buffer_->CreateImage(tbm_surface)) { - FT_LOG(Error) << "Fail to create image"; - vulkan_buffer_.reset(); - return false; - } - if (!vulkan_buffer_->AllocateMemory(tbm_surface)) { - FT_LOG(Error) << "Fail to allocate memory"; - vulkan_buffer_.reset(); - return false; - } - if (!vulkan_buffer_->BindImageMemory(tbm_surface)) { - FT_LOG(Error) << "Fail to bind image memory"; - vulkan_buffer_.reset(); + ReleaseBuffer(); + if (!CreateBuffer(tbm_surface)) { + ReleaseBuffer(); + FT_LOG(Error) << "Fail to create buffer"; return false; } last_surface_handle_ = handle; diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan.h index 0d75cb34..f2fa0a6d 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.h @@ -35,6 +35,9 @@ class ExternalTextureSurfaceVulkan : public ExternalVulkanTexture { private: bool CreateOrUpdateImage( const FlutterDesktopGpuSurfaceDescriptor* descriptor); + + bool CreateBuffer(const tbm_surface_h tbm_surface); + void ReleaseBuffer(); bool IsSupportDisjoint(tbm_surface_h tbm_surface); FlutterDesktopGpuSurfaceTextureCallback texture_callback_ = nullptr; void* user_data_ = nullptr; diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h index aad580eb..6e01606b 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -24,8 +24,7 @@ class ExternalTextureSurfaceVulkanBuffer { virtual ~ExternalTextureSurfaceVulkanBuffer() = default; virtual bool CreateImage(tbm_surface_h tbm_surface) = 0; virtual void ReleaseImage() = 0; - virtual bool AllocateMemory(tbm_surface_h tbm_surface) = 0; - virtual bool BindImageMemory(tbm_surface_h tbm_surface) = 0; + virtual bool AllocateAndBindMemory(tbm_surface_h tbm_surface) = 0; virtual VkFormat GetFormat() = 0; virtual VkImage GetImage() = 0; virtual VkDeviceMemory GetMemory() = 0; diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc index d4e71777..d422d522 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -102,7 +102,7 @@ bool ExternalTextureSurfaceVulkanBufferDma::GetFdMemoryTypeIndex( return false; } -bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( +bool ExternalTextureSurfaceVulkanBufferDma::AllocateAndBindMemory( tbm_surface_h tbm_surface) { tbm_bo bo = tbm_surface_internal_get_bo(tbm_surface, 0); int bo_fd = tbm_bo_export_fd(bo); @@ -131,16 +131,13 @@ bool ExternalTextureSurfaceVulkanBufferDma::AllocateMemory( FT_LOG(Error) << "Fail to allocate memory"; return false; } - return true; -} -bool ExternalTextureSurfaceVulkanBufferDma::BindImageMemory( - tbm_surface_h tbm_surface) { if (vkBindImageMemory(GetDevice(), texture_image_, texture_device_memory_, 0u) != VK_SUCCESS) { FT_LOG(Error) << "Fail to bind image memory"; return false; } + close(bo_fd); return true; } diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h index 07837089..6119dc52 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h @@ -19,8 +19,7 @@ class ExternalTextureSurfaceVulkanBufferDma virtual ~ExternalTextureSurfaceVulkanBufferDma(); bool CreateImage(tbm_surface_h tbm_surface) override; void ReleaseImage() override; - bool AllocateMemory(tbm_surface_h tbm_surface) override; - bool BindImageMemory(tbm_surface_h tbm_surface) override; + bool AllocateAndBindMemory(tbm_surface_h tbm_surface) override; VkFormat GetFormat() override; VkImage GetImage() override; VkDeviceMemory GetMemory() override; From 8e0617c0d1c97f9a7dd02d33d3bbd483d69cea9e Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Tue, 16 Dec 2025 09:08:43 +0800 Subject: [PATCH 13/14] Release tbm surface if create vk image failed --- .../shell/platform/tizen/external_texture_surface_vulkan.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 5aa9464c..490eb5da 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -72,6 +72,9 @@ bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( if (!CreateBuffer(tbm_surface)) { ReleaseBuffer(); FT_LOG(Error) << "Fail to create buffer"; + if (descriptor->release_callback) { + descriptor->release_callback(descriptor->release_context); + } return false; } last_surface_handle_ = handle; From 63178152793267f45e99ae1244368c4a044c758a Mon Sep 17 00:00:00 2001 From: xiaowei-guan Date: Wed, 17 Dec 2025 07:32:13 +0800 Subject: [PATCH 14/14] Done not need release image before call reset method --- flutter/shell/platform/tizen/external_texture_surface_vulkan.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc index 490eb5da..0b01c8fa 100644 --- a/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -53,7 +53,6 @@ bool ExternalTextureSurfaceVulkan::CreateBuffer( void ExternalTextureSurfaceVulkan::ReleaseBuffer() { if (vulkan_buffer_) { - vulkan_buffer_->ReleaseImage(); vulkan_buffer_.reset(); } }