Skip to content

Commit c0e806d

Browse files
authored
Add vulkan solution (#6)
* Merge texture vulkan code and implement texture source * [Tizen] Enable vulkan * Disable xll and fix vulkan build error
1 parent bc0d9bb commit c0e806d

12 files changed

+667
-4
lines changed

engine/src/build_overrides/vulkan_headers.gni

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
# set anything.
77

88
if (is_linux) {
9-
vulkan_use_x11 = true
9+
vulkan_use_x11 = false
1010
vulkan_use_wayland = true
1111
}

engine/src/flutter/impeller/tools/args.gni

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ declare_args() {
1717
enable_unittests) && target_os != "fuchsia"
1818

1919
# Whether the Vulkan backend is enabled.
20-
impeller_enable_vulkan = (is_win || is_android || is_mac ||
20+
impeller_enable_vulkan = (is_linux || is_win || is_android || is_mac ||
2121
enable_unittests) && target_os != "fuchsia"
2222
}
2323

engine/src/flutter/shell/platform/embedder/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ template("embedder_source_set") {
167167

168168
if (embedder_enable_vulkan) {
169169
sources += [
170+
"embedder_external_texture_vulkan.cc",
171+
"embedder_external_texture_vulkan.h",
170172
"embedder_surface_vulkan.cc",
171173
"embedder_surface_vulkan.h",
172174
]
@@ -175,6 +177,8 @@ template("embedder_source_set") {
175177
sources += [
176178
"embedder_surface_vulkan_impeller.cc",
177179
"embedder_surface_vulkan_impeller.h",
180+
"embedder_external_texture_source_vulkan.cc",
181+
"embedder_external_texture_source_vulkan.h",
178182
]
179183
}
180184

engine/src/flutter/shell/platform/embedder/embedder.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,28 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
23382338
external_texture_metal_callback);
23392339
}
23402340
}
2341+
#endif
2342+
#ifdef SHELL_ENABLE_VULKAN
2343+
flutter::EmbedderExternalTextureVulkan::ExternalTextureCallback
2344+
external_texture_vulkan_callback;
2345+
if (config->type == kVulkan) {
2346+
const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan;
2347+
if (SAFE_ACCESS(vulkan_config, external_texture_frame_callback, nullptr)) {
2348+
external_texture_vulkan_callback =
2349+
[ptr = vulkan_config->external_texture_frame_callback, user_data](
2350+
int64_t texture_identifier, size_t width,
2351+
size_t height) -> std::unique_ptr<FlutterVulkanTexture> {
2352+
std::unique_ptr<FlutterVulkanTexture> texture =
2353+
std::make_unique<FlutterVulkanTexture>();
2354+
if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
2355+
return nullptr;
2356+
}
2357+
return texture;
2358+
};
2359+
external_texture_resolver = std::make_unique<ExternalTextureResolver>(
2360+
external_texture_vulkan_callback);
2361+
}
2362+
}
23412363
#endif
23422364
auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr);
23432365
auto thread_config_callback = [&custom_task_runners](

engine/src/flutter/shell/platform/embedder/embedder.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,9 @@ typedef void* FlutterVulkanQueueHandle;
832832
/// Alias for VkImage.
833833
typedef uint64_t FlutterVulkanImageHandle;
834834

835+
/// Alias for VkDeviceMemory.
836+
typedef uint64_t FlutterVulkanDeviceMemoryHandle;
837+
835838
typedef struct {
836839
/// The size of this struct. Must be sizeof(FlutterVulkanImage).
837840
size_t struct_size;
@@ -860,6 +863,42 @@ typedef bool (*FlutterVulkanPresentCallback)(
860863
void* /* user data */,
861864
const FlutterVulkanImage* /* image */);
862865

866+
typedef struct {
867+
/// Handle to the VkImage that is owned by the embedder. The engine will
868+
/// bind this image for writing the frame.
869+
FlutterVulkanImageHandle image;
870+
/// The VkDeviceMemory that backs the iamge.
871+
FlutterVulkanDeviceMemoryHandle image_memory;
872+
/// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
873+
uint32_t format;
874+
/// The linear tiling features of the image (for example:
875+
/// VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT).
876+
uint32_t format_features;
877+
878+
uint64_t alloc_size;
879+
880+
/// User data to be returned on the invocation of the destruction callback.
881+
void* user_data;
882+
/// Callback invoked (on an engine managed thread) that asks the embedder to
883+
/// collect the texture.
884+
VoidCallback destruction_callback;
885+
/// Optional parameters for texture height/width, default is 0, non-zero means
886+
/// the texture has the specified width/height.
887+
/// Width of the texture.
888+
size_t width;
889+
/// Height of the texture.
890+
size_t height;
891+
} FlutterVulkanTexture;
892+
893+
/// Callback to provide an external texture for a given texture_id.
894+
/// See: external_texture_frame_callback.
895+
typedef bool (*FlutterVulkanTextureFrameCallback)(
896+
void* /* user data */,
897+
int64_t /* texture identifier */,
898+
size_t /* width */,
899+
size_t /* height */,
900+
FlutterVulkanTexture* /* texture out */);
901+
863902
typedef struct {
864903
/// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig).
865904
size_t struct_size;
@@ -923,7 +962,11 @@ typedef struct {
923962
/// without any additional synchronization.
924963
/// Not used if a FlutterCompositor is supplied in FlutterProjectArgs.
925964
FlutterVulkanPresentCallback present_image_callback;
926-
965+
/// When the embedder specifies that a texture has a frame available, the
966+
/// engine will call this method (on an internal engine managed thread) so
967+
/// that external texture details can be supplied to the engine for subsequent
968+
/// composition.
969+
FlutterVulkanTextureFrameCallback external_texture_frame_callback;
927970
} FlutterVulkanRendererConfig;
928971

929972
typedef struct {

engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ EmbedderExternalTextureResolver::EmbedderExternalTextureResolver(
2121
: metal_callback_(std::move(metal_callback)) {}
2222
#endif
2323

24+
#ifdef SHELL_ENABLE_VULKAN
25+
EmbedderExternalTextureResolver::EmbedderExternalTextureResolver(
26+
EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback)
27+
: vulkan_callback_(std::move(vulkan_callback)) {}
28+
#endif
29+
2430
std::unique_ptr<Texture>
2531
EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) {
2632
#ifdef SHELL_ENABLE_GL
@@ -37,6 +43,13 @@ EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) {
3743
}
3844
#endif
3945

46+
#ifdef SHELL_ENABLE_VULKAN
47+
if (vulkan_callback_) {
48+
return std::make_unique<EmbedderExternalTextureVulkan>(
49+
texture_id, vulkan_callback_);
50+
}
51+
#endif
52+
4053
return nullptr;
4154
}
4255

engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "flutter/shell/platform/embedder/embedder_external_texture_metal.h"
1818
#endif
1919

20+
#ifdef SHELL_ENABLE_VULKAN
21+
#include "flutter/shell/platform/embedder/embedder_external_texture_vulkan.h"
22+
#endif
23+
2024
namespace flutter {
2125
class EmbedderExternalTextureResolver {
2226
public:
@@ -34,6 +38,11 @@ class EmbedderExternalTextureResolver {
3438
EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback);
3539
#endif
3640

41+
#ifdef SHELL_ENABLE_VULKAN
42+
explicit EmbedderExternalTextureResolver(
43+
EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback);
44+
#endif
45+
3746
std::unique_ptr<Texture> ResolveExternalTexture(int64_t texture_id);
3847

3948
bool SupportsExternalTextures();
@@ -47,6 +56,9 @@ class EmbedderExternalTextureResolver {
4756
EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback_;
4857
#endif
4958

59+
#ifdef SHELL_ENABLE_VULKAN
60+
EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback_;
61+
#endif
5062
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureResolver);
5163
};
5264
} // namespace flutter
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h"
6+
7+
#include "impeller/renderer/backend/vulkan/allocator_vk.h"
8+
#include "impeller/renderer/backend/vulkan/context_vk.h"
9+
#include "impeller/renderer/backend/vulkan/texture_source_vk.h"
10+
#include "impeller/renderer/backend/vulkan/yuv_conversion_library_vk.h"
11+
#include "vulkan/vulkan.hpp"
12+
13+
namespace flutter {
14+
15+
EmbedderExternalTextureSourceVulkan::EmbedderExternalTextureSourceVulkan(
16+
const std::shared_ptr<impeller::Context>& p_context,
17+
FlutterVulkanTexture* embedder_desc)
18+
: TextureSourceVK(ToTextureDescriptor(embedder_desc)) {
19+
const auto& context = impeller::ContextVK::Cast(*p_context);
20+
const auto& device = context.GetDevice();
21+
texture_image_ =
22+
impeller::vk::Image(reinterpret_cast<VkImage>(embedder_desc->image));
23+
texture_device_memory_ = impeller::vk::DeviceMemory(
24+
reinterpret_cast<VkDeviceMemory>(embedder_desc->image_memory));
25+
// Figure out how to perform YUV conversions.
26+
auto yuv_conversion = CreateYUVConversion(context, embedder_desc);
27+
if (!yuv_conversion || !yuv_conversion->IsValid()) {
28+
VALIDATION_LOG << "Fail to create yuv conversion";
29+
return;
30+
}
31+
32+
// Create image view for the newly created image.
33+
if (!CreateTextureImageView(device)) {
34+
VALIDATION_LOG << "Fail to create texture image view";
35+
return;
36+
}
37+
38+
yuv_conversion_ = std::move(yuv_conversion);
39+
is_valid_ = true;
40+
}
41+
42+
impeller::PixelFormat ToPixelFormat(int32_t vk_format) {
43+
switch (vk_format) {
44+
case VK_FORMAT_UNDEFINED:
45+
return impeller::PixelFormat::kUnknown;
46+
case VK_FORMAT_R8G8B8A8_UNORM:
47+
return impeller::PixelFormat::kR8G8B8A8UNormInt;
48+
case VK_FORMAT_R8G8B8A8_SRGB:
49+
return impeller::PixelFormat::kR8G8B8A8UNormIntSRGB;
50+
case VK_FORMAT_B8G8R8A8_UNORM:
51+
return impeller::PixelFormat::kB8G8R8A8UNormInt;
52+
case VK_FORMAT_B8G8R8A8_SRGB:
53+
return impeller::PixelFormat::kB8G8R8A8UNormIntSRGB;
54+
case VK_FORMAT_R32G32B32A32_SFLOAT:
55+
return impeller::PixelFormat::kR32G32B32A32Float;
56+
case VK_FORMAT_R16G16B16A16_SFLOAT:
57+
return impeller::PixelFormat::kR16G16B16A16Float;
58+
case VK_FORMAT_S8_UINT:
59+
return impeller::PixelFormat::kS8UInt;
60+
case VK_FORMAT_D24_UNORM_S8_UINT:
61+
return impeller::PixelFormat::kD24UnormS8Uint;
62+
case VK_FORMAT_D32_SFLOAT_S8_UINT:
63+
return impeller::PixelFormat::kD32FloatS8UInt;
64+
case VK_FORMAT_R8_UNORM:
65+
return impeller::PixelFormat::kR8UNormInt;
66+
case VK_FORMAT_R8G8_UNORM:
67+
return impeller::PixelFormat::kR8G8UNormInt;
68+
default:
69+
return impeller::PixelFormat::kUnknown;
70+
}
71+
}
72+
73+
impeller::TextureDescriptor
74+
EmbedderExternalTextureSourceVulkan::ToTextureDescriptor(
75+
FlutterVulkanTexture* embedder_desc) {
76+
const auto size =
77+
impeller::ISize{embedder_desc->width, embedder_desc->height};
78+
impeller::TextureDescriptor desc;
79+
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
80+
desc.format = ToPixelFormat(embedder_desc->format);
81+
desc.size = size;
82+
desc.type = impeller::TextureType::kTexture2D;
83+
desc.sample_count = impeller::SampleCount::kCount1;
84+
desc.compression_type = impeller::CompressionType::kLossless;
85+
desc.mip_count = 1u;
86+
desc.usage = impeller::TextureUsage::kRenderTarget;
87+
return desc;
88+
}
89+
90+
std::shared_ptr<impeller::YUVConversionVK>
91+
EmbedderExternalTextureSourceVulkan::CreateYUVConversion(
92+
const impeller::ContextVK& context,
93+
FlutterVulkanTexture* embedder_desc) {
94+
impeller::YUVConversionDescriptorVK conversion_chain;
95+
auto& conversion_info = conversion_chain.get();
96+
97+
conversion_info.format =
98+
static_cast<impeller::vk::Format>(embedder_desc->format);
99+
conversion_info.ycbcrModel =
100+
impeller::vk::SamplerYcbcrModelConversion::eYcbcr709;
101+
conversion_info.ycbcrRange = impeller::vk::SamplerYcbcrRange::eItuFull;
102+
conversion_info.components = {impeller::vk::ComponentSwizzle::eIdentity,
103+
impeller::vk::ComponentSwizzle::eIdentity,
104+
impeller::vk::ComponentSwizzle::eIdentity,
105+
impeller::vk::ComponentSwizzle::eIdentity};
106+
conversion_info.xChromaOffset = impeller::vk::ChromaLocation::eCositedEven;
107+
conversion_info.yChromaOffset = impeller::vk::ChromaLocation::eCositedEven;
108+
conversion_info.chromaFilter = impeller::vk::Filter::eNearest;
109+
conversion_info.forceExplicitReconstruction = false;
110+
return context.GetYUVConversionLibrary()->GetConversion(conversion_chain);
111+
}
112+
113+
bool EmbedderExternalTextureSourceVulkan::CreateTextureImageView(
114+
const impeller::vk::Device& device) {
115+
impeller::vk::StructureChain<impeller::vk::ImageViewCreateInfo,
116+
impeller::vk::SamplerYcbcrConversionInfo>
117+
view_chain;
118+
auto& view_info = view_chain.get();
119+
view_info.image = texture_image_;
120+
view_info.viewType = impeller::vk::ImageViewType::e2D;
121+
view_info.format = impeller::vk::Format::eR8G8B8A8Srgb;
122+
view_info.subresourceRange.aspectMask =
123+
impeller::vk::ImageAspectFlagBits::eColor;
124+
view_info.subresourceRange.baseMipLevel = 0u;
125+
view_info.subresourceRange.baseArrayLayer = 0u;
126+
view_info.subresourceRange.levelCount = 1;
127+
view_info.subresourceRange.layerCount = 1;
128+
auto image_view = device.createImageViewUnique(view_info);
129+
if (image_view.result != impeller::vk::Result::eSuccess) {
130+
VALIDATION_LOG << "Could not create external image view: "
131+
<< impeller::vk::to_string(image_view.result);
132+
return false;
133+
}
134+
texture_image_view_ = std::move(image_view.value);
135+
return true;
136+
}
137+
138+
// |TextureSourceVK|
139+
EmbedderExternalTextureSourceVulkan::~EmbedderExternalTextureSourceVulkan() =
140+
default;
141+
142+
bool EmbedderExternalTextureSourceVulkan::IsValid() const {
143+
return is_valid_;
144+
}
145+
146+
// |TextureSourceVK|
147+
impeller::vk::Image EmbedderExternalTextureSourceVulkan::GetImage() const {
148+
return texture_image_;
149+
}
150+
151+
// |TextureSourceVK|
152+
impeller::vk::ImageView EmbedderExternalTextureSourceVulkan::GetImageView()
153+
const {
154+
return texture_image_view_.get();
155+
}
156+
157+
// |TextureSourceVK|
158+
impeller::vk::ImageView
159+
EmbedderExternalTextureSourceVulkan::GetRenderTargetView() const {
160+
return texture_image_view_.get();
161+
}
162+
163+
// |TextureSourceVK|
164+
bool EmbedderExternalTextureSourceVulkan::IsSwapchainImage() const {
165+
return is_swapchain_image_;
166+
}
167+
168+
// |TextureSourceVK|
169+
std::shared_ptr<impeller::YUVConversionVK>
170+
EmbedderExternalTextureSourceVulkan::GetYUVConversion() const {
171+
return needs_yuv_conversion_ ? yuv_conversion_ : nullptr;
172+
}
173+
174+
} // namespace flutter

0 commit comments

Comments
 (0)