Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions flutter/shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -930,9 +930,6 @@ 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;
Expand Down Expand Up @@ -962,25 +959,27 @@ typedef bool (*FlutterVulkanPresentCallback)(
const FlutterVulkanImage* /* image */);

typedef struct {
/// The size of this struct. Must be sizeof(FlutterVulkanExternalTexture).
size_t struct_size;
/// Handle to the VkImage that is owned by the embedder. The engine will
/// bind this image for writing the frame.
/// sample from this image during composition. The VkImage must be in the
/// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL layout when provided to the
/// engine.
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.
/// collect the texture. This is optional and can be null.
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.
/// Physical width of the texture.
size_t width;
/// Height of the texture.
/// Physical height of the texture.
size_t height;
} FlutterVulkanTexture;
} FlutterVulkanExternalTexture;

/// Callback to provide an external texture for a given texture_id.
/// See: external_texture_frame_callback.
Expand All @@ -989,7 +988,7 @@ typedef bool (*FlutterVulkanTextureFrameCallback)(
int64_t /* texture identifier */,
size_t /* width */,
size_t /* height */,
FlutterVulkanTexture* /* texture out */);
FlutterVulkanExternalTexture* /* texture out */);

typedef struct {
/// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig).
Expand Down Expand Up @@ -1057,7 +1056,9 @@ typedef struct {
/// 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.
/// composition. Prior to returning from this callback, the embedder must
/// perform a host sync, and so the engine can sample the VkImage without any
/// additional synchronization.
FlutterVulkanTextureFrameCallback external_texture_frame_callback;
/// The path to the Vulkan pipeline cache data.
/// The string can be collected after the call to `FlutterEngineRun` returns.
Expand Down
7 changes: 4 additions & 3 deletions flutter/shell/platform/tizen/external_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ class ExternalVulkanTexture : public ExternalTexture {
public:
ExternalVulkanTexture() : ExternalTexture() {}

virtual bool PopulateVulkanTexture(size_t width,
size_t height,
FlutterVulkanTexture* vulkan_texture) = 0;
virtual bool PopulateVulkanTexture(
size_t width,
size_t height,
FlutterVulkanExternalTexture* vulkan_texture) = 0;
};

} // namespace flutter
Expand Down
55 changes: 48 additions & 7 deletions flutter/shell/platform/tizen/external_texture_pixel_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ExternalTexturePixelVulkan::~ExternalTexturePixelVulkan() {
bool ExternalTexturePixelVulkan::PopulateVulkanTexture(
size_t width,
size_t height,
FlutterVulkanTexture* flutter_texture) {
FlutterVulkanExternalTexture* flutter_texture) {
if (!texture_callback_) {
FT_LOG(Error) << "texture_callback_ is nullptr";
return false;
Expand Down Expand Up @@ -75,12 +75,13 @@ bool ExternalTexturePixelVulkan::PopulateVulkanTexture(
return false;
}

FlutterVulkanTexture* vulkan_texture =
static_cast<FlutterVulkanTexture*>(flutter_texture);
vulkan_texture->image = reinterpret_cast<uint64_t>(image_);
vulkan_texture->format = VK_FORMAT_R8G8B8A8_UNORM;
vulkan_texture->width = width_;
vulkan_texture->height = height_;
flutter_texture->struct_size = sizeof(FlutterVulkanExternalTexture);
flutter_texture->image = reinterpret_cast<uint64_t>(image_);
Comment thread
xiaowei-guan marked this conversation as resolved.
flutter_texture->format = VK_FORMAT_R8G8B8A8_UNORM;
flutter_texture->user_data = nullptr;
flutter_texture->destruction_callback = nullptr;
flutter_texture->width = width_;
flutter_texture->height = height_;
return true;
}

Expand Down Expand Up @@ -225,9 +226,49 @@ bool ExternalTexturePixelVulkan::CopyBufferToImage(const uint8_t* src_buffer,
region.imageExtent = {static_cast<uint32_t>(width_),
static_cast<uint32_t>(height_), 1};

{
VkImageMemoryBarrier pre_copy_barrier = {};
pre_copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
pre_copy_barrier.srcAccessMask = 0;
pre_copy_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
pre_copy_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
pre_copy_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
pre_copy_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_copy_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_copy_barrier.image = image_;
pre_copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
pre_copy_barrier.subresourceRange.baseMipLevel = 0;
pre_copy_barrier.subresourceRange.levelCount = 1;
pre_copy_barrier.subresourceRange.baseArrayLayer = 0;
pre_copy_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
nullptr, 1, &pre_copy_barrier);
}

vkCmdCopyBufferToImage(command_buffer, staging_buffer_, image_,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);

{
VkImageMemoryBarrier post_copy_barrier = {};
post_copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
post_copy_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
post_copy_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
post_copy_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
post_copy_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
post_copy_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
post_copy_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
post_copy_barrier.image = image_;
post_copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
post_copy_barrier.subresourceRange.baseMipLevel = 0;
post_copy_barrier.subresourceRange.levelCount = 1;
post_copy_barrier.subresourceRange.baseArrayLayer = 0;
post_copy_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr,
0, nullptr, 1, &post_copy_barrier);
}

vulkan_renderer_->EndSingleTimeCommands(command_buffer);
return true;
}
Expand Down
7 changes: 4 additions & 3 deletions flutter/shell/platform/tizen/external_texture_pixel_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ class ExternalTexturePixelVulkan : public ExternalVulkanTexture {

virtual ~ExternalTexturePixelVulkan();

bool PopulateVulkanTexture(size_t width,
size_t height,
FlutterVulkanTexture* flutter_texture) override;
bool PopulateVulkanTexture(
size_t width,
size_t height,
FlutterVulkanExternalTexture* flutter_texture) override;

private:
bool AllocateMemory(const VkMemoryRequirements& memory_requirements,
Expand Down
13 changes: 10 additions & 3 deletions flutter/shell/platform/tizen/external_texture_surface_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ bool ExternalTextureSurfaceVulkan::CreateBuffer(
return false;
}

if (!vulkan_buffer_->TransitionToShaderReadLayout(
vulkan_buffer_->GetImage())) {
FT_LOG(Error) << "Fail to transition image layout";
vulkan_buffer_->ReleaseImage();
return false;
}
return true;
}

Expand Down Expand Up @@ -109,7 +115,7 @@ bool ExternalTextureSurfaceVulkan::IsSupportDisjoint(
bool ExternalTextureSurfaceVulkan::PopulateVulkanTexture(
size_t width,
size_t height,
FlutterVulkanTexture* vulkan_texture) {
FlutterVulkanExternalTexture* vulkan_texture) {
if (!texture_callback_ || !vulkan_texture) {
return false;
}
Expand All @@ -126,11 +132,12 @@ bool ExternalTextureSurfaceVulkan::PopulateVulkanTexture(
return false;
}

vulkan_texture->struct_size = sizeof(FlutterVulkanExternalTexture);
vulkan_texture->image =
reinterpret_cast<uint64_t>(vulkan_buffer_->GetImage());
Comment thread
xiaowei-guan marked this conversation as resolved.
vulkan_texture->format = vulkan_buffer_->GetFormat();
vulkan_texture->image_memory =
reinterpret_cast<uint64_t>(vulkan_buffer_->GetMemory());
vulkan_texture->user_data = nullptr;
vulkan_texture->destruction_callback = nullptr;
vulkan_texture->width = width;
vulkan_texture->height = height;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ class ExternalTextureSurfaceVulkan : public ExternalVulkanTexture {

virtual ~ExternalTextureSurfaceVulkan();

bool PopulateVulkanTexture(size_t width,
size_t height,
FlutterVulkanTexture* vulkan_texture) override;
bool PopulateVulkanTexture(
size_t width,
size_t height,
FlutterVulkanExternalTexture* vulkan_texture) override;

private:
bool CreateOrUpdateImage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,38 @@ VkDevice ExternalTextureSurfaceVulkanBuffer::GetDevice() const {
return static_cast<VkDevice>(vulkan_renderer_->GetDeviceHandle());
}

bool ExternalTextureSurfaceVulkanBuffer::TransitionToShaderReadLayout(
VkImage image) {
if (image == VK_NULL_HANDLE) {
FT_LOG(Error) << "Cannot transition layout of a null VkImage";
return false;
}

VkCommandBuffer command_buffer = vulkan_renderer_->BeginSingleTimeCommands();
if (command_buffer == VK_NULL_HANDLE) {
FT_LOG(Error) << "Failed to begin single time commands";
return false;
}

VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0,
nullptr, 1, &barrier);
vulkan_renderer_->EndSingleTimeCommands(command_buffer);
return true;
}

} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class ExternalTextureSurfaceVulkanBuffer {
virtual VkImage GetImage() = 0;
virtual VkDeviceMemory GetMemory() = 0;

bool TransitionToShaderReadLayout(VkImage image);

protected:
VkFormat ConvertFormat(tbm_format format);
VkDevice GetDevice() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ bool FlutterTizenTextureRegistrar::PopulateVulkanTexture(
int64_t texture_id,
size_t width,
size_t height,
FlutterVulkanTexture* vulkan_texture) {
FlutterVulkanExternalTexture* vulkan_texture) {
ExternalTexture* texture;
{
std::lock_guard<std::mutex> lock(map_mutex_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class FlutterTizenTextureRegistrar {
bool PopulateVulkanTexture(int64_t texture_id,
size_t width,
size_t height,
FlutterVulkanTexture* texture);
FlutterVulkanExternalTexture* texture);

private:
FlutterTizenEngine* engine_ = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion flutter/shell/platform/tizen/tizen_renderer_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ FlutterRendererConfig TizenRendererVulkan::GetRendererConfig() {
};
config.vulkan.external_texture_frame_callback =
[](void* user_data, int64_t texture_id, size_t width, size_t height,
FlutterVulkanTexture* texture) -> bool {
FlutterVulkanExternalTexture* texture) -> bool {
auto* engine = reinterpret_cast<FlutterTizenEngine*>(user_data);
if (!engine->view()) {
return false;
Expand Down
Loading