diff --git a/flutter/shell/platform/tizen/BUILD.gn b/flutter/shell/platform/tizen/BUILD.gn index 0cf06fe3..8cce5a06 100644 --- a/flutter/shell/platform/tizen/BUILD.gn +++ b/flutter/shell/platform/tizen/BUILD.gn @@ -157,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", + ] deps += [ "//flutter/third_party/volk" ] } diff --git a/flutter/shell/platform/tizen/external_texture.h b/flutter/shell/platform/tizen/external_texture.h index a3b9866f..fe697ce6 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 PopulateGLTexture(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..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::PopulateTexture( +bool ExternalTexturePixelEGL::PopulateGLTexture( 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..1a7c4360 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 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 7cf7899a..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::PopulateTexture( +bool ExternalTexturePixelEGLImpeller::PopulateGLTexture( 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 old mode 100755 new mode 100644 index ebaad4e4..b7116dfc --- 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 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_pixel_vulkan.cc b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc new file mode 100644 index 00000000..2cf0d12e --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc @@ -0,0 +1,262 @@ +// 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() { + ReleaseBuffer(); + 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->width, pixel_buffer->height)) { + FT_LOG(Error) << "Fail to create image"; + ReleaseImage(); + return false; + } + + 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; + } + + width_ = pixel_buffer->width; + height_ = pixel_buffer->height; + + CopyBufferToImage(pixel_buffer->buffer, required_staging_size); + + FlutterVulkanTexture* vulkan_texture = + static_cast(flutter_texture); + vulkan_texture->image = reinterpret_cast(image_); + vulkan_texture->format = VK_FORMAT_R8G8B8A8_UNORM; + vulkan_texture->width = width_; + vulkan_texture->height = height_; + return true; +} + +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 (image_ == VK_NULL_HANDLE) { + return CreateImage(width, height); + } + + if (width != width_ || height != height_) { + ReleaseImage(); + return CreateImage(width, 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(GetDevice(), &image_info, nullptr, &image_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to create VkImage"; + return false; + } + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements(GetDevice(), image_, &memory_requirements); + + if (!AllocateMemory(memory_requirements, image_memory_, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { + FT_LOG(Error) << "Fail to allocate image memory"; + return false; + } + + if (vkBindImageMemory(GetDevice(), image_, 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(VkDeviceSize required_size) { + VkBufferCreateInfo buffer_info{}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = required_size; + buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + if (vkCreateBuffer(GetDevice(), &buffer_info, nullptr, &staging_buffer_) != + VK_SUCCESS) { + FT_LOG(Error) << "Fail to create vkBuffer"; + return false; + } + + VkMemoryRequirements memory_requirements; + vkGetBufferMemoryRequirements(GetDevice(), staging_buffer_, + &memory_requirements); + + 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; + } + + if (vkBindBufferMemory(GetDevice(), staging_buffer_, staging_buffer_memory_, + 0) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to bind buffer memory"; + return false; + } + staging_buffer_size_ = required_size; + return true; +} + +void ExternalTexturePixelVulkan::ReleaseBuffer() { + if (staging_buffer_ != VK_NULL_HANDLE) { + vkDestroyBuffer(GetDevice(), staging_buffer_, nullptr); + staging_buffer_ = VK_NULL_HANDLE; + } + if (staging_buffer_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(GetDevice(), staging_buffer_memory_, nullptr); + + staging_buffer_memory_ = VK_NULL_HANDLE; + } + staging_buffer_size_ = 0; +} + +void ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer, + VkDeviceSize size) { + void* data; + vkMapMemory(GetDevice(), staging_buffer_memory_, 0, size, 0, &data); + memcpy(data, src_buffer, static_cast(size)); + vkUnmapMemory(GetDevice(), 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 = {static_cast(width_), + static_cast(height_), 1}; + + vkCmdCopyBufferToImage(command_buffer, staging_buffer_, image_, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + vulkan_renderer_->EndSingleTimeCommands(command_buffer); +} + +void ExternalTexturePixelVulkan::ReleaseImage() { + if (image_ != VK_NULL_HANDLE) { + vkDestroyImage(GetDevice(), image_, nullptr); + image_ = VK_NULL_HANDLE; + } + + if (image_memory_ != VK_NULL_HANDLE) { + vkFreeMemory(GetDevice(), image_memory_, nullptr); + image_memory_ = VK_NULL_HANDLE; + } +} + +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(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 new file mode 100644 index 00000000..ce10f0f0 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_pixel_vulkan.h @@ -0,0 +1,55 @@ +// 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. + +#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 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); + 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, + 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 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; +}; +} // 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..280e9df7 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::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 621fbe44..0bd8e9ab 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 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 e3de9c85..3fcbfd4a 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::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 d957000b..d03451ab --- 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 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 new file mode 100644 index 00000000..0b01c8fa --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.cc @@ -0,0 +1,136 @@ +// 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() { + 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_.reset(); + } +} + +bool ExternalTextureSurfaceVulkan::CreateOrUpdateImage( + const FlutterDesktopGpuSurfaceDescriptor* descriptor) { + if (descriptor == nullptr || descriptor->handle == nullptr) { + ReleaseBuffer(); + return false; + } + + void* handle = descriptor->handle; + const tbm_surface_h tbm_surface = reinterpret_cast(handle); + if (handle != last_surface_handle_) { + ReleaseBuffer(); + 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; + } + 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); + if (num_bos <= 1) { + return false; + } + + 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_ || !vulkan_texture) { + 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..f2fa0a6d --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan.h @@ -0,0 +1,50 @@ +// 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 "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 "flutter/third_party/volk/volk.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 CreateBuffer(const tbm_surface_h tbm_surface); + void ReleaseBuffer(); + 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..75d22274 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.cc @@ -0,0 +1,59 @@ +// 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_ABGR8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_XRGB8888: + return VK_FORMAT_R8G8B8A8_UNORM; + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_BGRA8888: + return VK_FORMAT_B8G8R8A8_UNORM; + default: + return VK_FORMAT_UNDEFINED; + } +} + +bool ExternalTextureSurfaceVulkanBuffer::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; +} + +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 new file mode 100644 index 00000000..6e01606b --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h @@ -0,0 +1,44 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_H_ +#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_SURFACE_VULKAN_BUFFER_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" +#include "flutter/third_party/volk/volk.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 AllocateAndBindMemory(tbm_surface_h tbm_surface) = 0; + virtual VkFormat GetFormat() = 0; + virtual VkImage GetImage() = 0; + virtual VkDeviceMemory GetMemory() = 0; + + protected: + VkFormat ConvertFormat(tbm_format& format); + VkDevice GetDevice(); + bool FindMemoryType(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_BUFFER_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..d422d522 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.cc @@ -0,0 +1,155 @@ +// 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" + +namespace flutter { + +ExternalTextureSurfaceVulkanBufferDma::ExternalTextureSurfaceVulkanBufferDma( + TizenRendererVulkan* vulkan_renderer) + : ExternalTextureSurfaceVulkanBuffer(vulkan_renderer) {} + +ExternalTextureSurfaceVulkanBufferDma:: + ~ExternalTextureSurfaceVulkanBufferDma() { + ReleaseImage(); +} + +VkFormat ExternalTextureSurfaceVulkanBufferDma::GetFormat() { + return texture_format_; +} + +VkImage ExternalTextureSurfaceVulkanBufferDma::GetImage() { + return texture_image_; +} + +VkDeviceMemory ExternalTextureSurfaceVulkanBufferDma::GetMemory() { + return texture_device_memory_; +} + +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(GetDevice(), &image_create_info, nullptr, + &texture_image_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to create VkImage"; + return false; + } + return true; +} + +VkResult ExternalTextureSurfaceVulkanBufferDma::GetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + 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_EXTENSION_NOT_PRESENT; + } + 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(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; + } + + 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::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); + 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(GetDevice(), &alloc_info, nullptr, + &texture_device_memory_) != VK_SUCCESS) { + FT_LOG(Error) << "Fail to allocate memory"; + return false; + } + + 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; +} + +void ExternalTextureSurfaceVulkanBufferDma::ReleaseImage() { + if (texture_image_ != VK_NULL_HANDLE) { + vkDestroyImage(GetDevice(), texture_image_, nullptr); + texture_image_ = VK_NULL_HANDLE; + } + if (texture_device_memory_ != VK_NULL_HANDLE) { + 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 new file mode 100644 index 00000000..6119dc52 --- /dev/null +++ b/flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer_dma.h @@ -0,0 +1,40 @@ +// 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. + +#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 "flutter/shell/platform/tizen/external_texture_surface_vulkan_buffer.h" +#include "flutter/shell/platform/tizen/tizen_renderer_vulkan.h" +#include "flutter/third_party/volk/volk.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 AllocateAndBindMemory(tbm_surface_h tbm_surface) override; + VkFormat GetFormat() override; + VkImage GetImage() override; + VkDeviceMemory GetMemory() override; + + 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; +}; +} // 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..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::PopulateTexture( +bool FlutterTizenTextureRegistrar::PopulateGLTexture( 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)->PopulateGLTexture( + 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..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,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 PopulateGLTexture(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..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.PopulateTexture(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 febc73c4..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()->PopulateTexture(texture_id, width, - height, texture); + return engine->texture_registrar()->PopulateGLTexture(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 4e7ce2aa..3e5ed270 100644 --- a/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc +++ b/flutter/shell/platform/tizen/tizen_renderer_vulkan.cc @@ -6,7 +6,8 @@ #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" @@ -131,6 +132,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; } @@ -179,6 +190,16 @@ FlutterRendererConfig TizenRendererVulkan::GetRendererConfig() { return dynamic_cast(engine->renderer()) ->Present(image); }; + config.vulkan.external_texture_frame_callback = + [](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_id, width, + height, texture); + }; return config; }