Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit afa70e9

Browse files
committed
Add EmbedderSurface for Vulkan, init skia contexts, correct API callbacks, init proctable, and init GPUSurfaceVulkan with callback delegate
1 parent f3ecb6e commit afa70e9

11 files changed

+315
-45
lines changed

shell/gpu/gpu_surface_vulkan.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
namespace flutter {
1010

11-
GPUSurfaceVulkan::GPUSurfaceVulkan(const sk_sp<GrDirectContext>& skia_context,
12-
GPUSurfaceVulkanDelegate* delegate)
13-
: skia_context_(skia_context), delegate_(delegate), weak_factory_(this) {}
11+
GPUSurfaceVulkan::GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate,
12+
const sk_sp<GrDirectContext>& skia_context,
13+
bool render_to_surface)
14+
: delegate_(delegate),
15+
skia_context_(skia_context),
16+
render_to_surface_(render_to_surface),
17+
weak_factory_(this) {}
1418

1519
GPUSurfaceVulkan::~GPUSurfaceVulkan() = default;
1620

1721
bool GPUSurfaceVulkan::IsValid() {
18-
return image_ != nullptr;
22+
return skia_context_ != nullptr;
1923
}
2024

2125
std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
@@ -64,12 +68,10 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const {
6468
}
6569

6670
GrDirectContext* GPUSurfaceVulkan::GetContext() {
67-
return skia_context_;
71+
return skia_context_.get();
6872
}
6973

7074
sk_sp<SkSurface> GPUSurfaceVulkan::AcquireSurfaceFromVulkanImage(
71-
VkImage image) {
72-
73-
}
75+
VkImage image) {}
7476

7577
} // namespace flutter

shell/gpu/gpu_surface_vulkan.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
namespace flutter {
2020

21-
2221
//------------------------------------------------------------------------------
2322
/// @brief A GPU surface backed by VkImages provided by a
2423
/// GPUSurfaceVulkanDelegate.
@@ -29,8 +28,9 @@ class GPUSurfaceVulkan : public Surface {
2928
/// @brief Create a GPUSurfaceVulkan while letting it reuse an existing
3029
/// GrDirectContext.
3130
///
32-
GPUSurfaceVulkan(const sk_sp<GrDirectContext>& context,
33-
GPUSurfaceVulkanDelegate* delegate);
31+
GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate,
32+
const sk_sp<GrDirectContext>& context,
33+
bool render_to_surface);
3434

3535
~GPUSurfaceVulkan() override;
3636

@@ -52,11 +52,12 @@ class GPUSurfaceVulkan : public Surface {
5252
GrDirectContext* GetContext() override;
5353

5454
private:
55-
sk_sp<GrDirectContext> skia_context_;
5655
GPUSurfaceVulkanDelegate* delegate_;
56+
sk_sp<GrDirectContext> skia_context_;
57+
bool render_to_surface_;
5758

58-
std::vector<std::unique_ptr<VulkanBackbuffer>> backbuffers_;
59-
std::vector<sk_sp<SkSurface>> surfaces_;
59+
std::unique_ptr<vulkan::VulkanBackbuffer> backbuffer_;
60+
sk_sp<SkSurface> surface_;
6061
size_t current_backbuffer_index_;
6162

6263
fml::WeakPtrFactory<GPUSurfaceVulkan> weak_factory_;

shell/gpu/gpu_surface_vulkan_delegate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class GPUSurfaceVulkanDelegate {
3131

3232
/// @brief Obtain a reference to the Vulkan implementation's proc table.
3333
///
34-
virtual fml::RefPtr<vulkan::VulkanProcTable> vk() = 0;
34+
virtual const vulkan::VulkanProcTable& vk() = 0;
3535

3636
/// @brief Called by the engine to fetch a VkImage for writing the next
3737
/// frame.

shell/platform/embedder/BUILD.gn

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,6 @@ template("embedder_source_set") {
104104
deps += [ "//flutter/shell/platform/darwin/graphics" ]
105105
}
106106

107-
if (embedder_enable_gl) {
108-
sources += [
109-
"embedder_surface_vulkan.cc",
110-
"embedder_surface_vulkan.h",
111-
]
112-
}
113-
114107
public_deps = [ ":embedder_headers" ]
115108

116109
public_configs += [

shell/platform/embedder/embedder.cc

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include "shell/gpu/gpu_surface_vulkan_delegate.h"
6+
#include "shell/platform/embedder/embedder_surface_vulkan.h"
57
#define FML_USED_ON_EMBEDDER
68
#define RAPIDJSON_HAS_STDSTRING 1
79

@@ -170,7 +172,7 @@ static void* DefaultGLProcResolver(const char* name) {
170172
fml::NativeLibrary::CreateForCurrentProcess();
171173
#elif OS_WIN // OS_LINUX
172174
fml::NativeLibrary::Create("opengl32.dll");
173-
#endif // OS_WIN
175+
#endif // OS_WIN
174176
return static_cast<void*>(
175177
const_cast<uint8_t*>(proc_library->ResolveSymbol(name)));
176178
}
@@ -381,11 +383,51 @@ InferVulkanPlatformViewCreationCallback(
381383
}
382384

383385
#ifdef SHELL_ENABLE_VULKAN
386+
std::function<void*(VkInstance, const char*)>
387+
vulkan_get_instance_proc_address =
388+
[ptr = config->vulkan.get_instance_proc_address_callback, user_data](
389+
VkInstance instance, const char* proc_name) -> void* {
390+
ptr(user_data, instance, proc_name);
391+
};
392+
393+
auto vulkan_get_next_image =
394+
[ptr = config->vulkan.get_next_image_callback,
395+
user_data](const SkISize& frame_size) -> VkImage {
396+
FlutterFrameInfo frame_info = {
397+
.struct_size = sizeof(FlutterFrameInfo),
398+
.size = {static_cast<uint32_t>(frame_size.width()),
399+
static_cast<uint32_t>(frame_size.height())},
400+
};
401+
402+
FlutterVulkanImage vulkan_image = ptr(user_data, &frame_info);
403+
return static_cast<VkImage>(vulkan_image.image);
404+
};
405+
406+
auto vulkan_present_image_callback =
407+
[ptr = config->vulkan.present_image_callback,
408+
user_data](VkImage image) -> bool {
409+
FlutterVulkanImage image_desc = {
410+
.struct_size = sizeof(FlutterVulkanImage),
411+
.image = image,
412+
.user_data = user_data,
413+
};
414+
return ptr(user_data, &image_desc);
415+
};
416+
417+
flutter::EmbedderSurfaceVulkan::VulkanDispatchTable vulkan_dispatch_table = {
418+
.get_instance_proc_address = vulkan_get_instance_proc_address,
419+
.get_next_image = vulkan_get_next_image,
420+
.present_image = vulkan_present_image_callback,
421+
};
422+
384423
std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
385424
std::move(external_view_embedder);
386425

387426
std::unique_ptr<flutter::EmbedderSurfaceVulkan> embedder_surface =
388-
std::make_unique<flutter::EmbedderSurfaceVulkan>(view_embedder);
427+
std::make_unique<flutter::EmbedderSurfaceVulkan>(
428+
config->vulkan.device, config->vulkan.physical_device,
429+
config->vulkan.instance, config->vulkan.queue_family_index,
430+
config->vulkan.queue, vulkan_dispatch_table, view_embedder);
389431

390432
return fml::MakeCopyable(
391433
[embedder_surface = std::move(embedder_surface), platform_dispatch_table,
@@ -647,7 +689,7 @@ static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
647689
GrDirectContext* context,
648690
const FlutterBackingStoreConfig& config,
649691
const FlutterVulkanBackingStore* vulkan) {
650-
assert(false); // TODO(bdero)
692+
assert(false); // TODO(bdero)
651693
return nullptr;
652694
}
653695

shell/platform/embedder/embedder.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,19 +543,19 @@ typedef struct {
543543
} FlutterMetalRendererConfig;
544544

545545
/// Alias for VkInstance.
546-
typedef const uint64_t* FlutterVulkanInstanceHandle;
546+
typedef void* FlutterVulkanInstanceHandle;
547547

548548
/// Alias for VkPhysicalDevice.
549-
typedef const uint64_t* FlutterVulkanPhysicalDeviceHandle;
549+
typedef void* FlutterVulkanPhysicalDeviceHandle;
550550

551551
/// Alias for VkDevice.
552-
typedef const uint64_t* FlutterVulkanDeviceHandle;
552+
typedef void* FlutterVulkanDeviceHandle;
553553

554554
/// Alias for VkQueue.
555-
typedef const uint64_t* FlutterVulkanQueueHandle;
555+
typedef void* FlutterVulkanQueueHandle;
556556

557557
/// Alias for VkImage.
558-
typedef const uint64_t* FlutterVulkanImageHandle;
558+
typedef void* FlutterVulkanImageHandle;
559559

560560
typedef struct {
561561
/// The size of this struct. Must be sizeof(FlutterVulkanImage).
@@ -567,8 +567,8 @@ typedef struct {
567567
/// back to the embedder in the destruction callback below. Embedder resources
568568
/// may be associated with this baton.
569569
void* user_data;
570-
/// The callback invoked by the engine when it no longer needs this backing
571-
/// store.
570+
/// Only called when releasing custom compositor backing stores. The callback
571+
/// invoked by the engine when it no longer needs this backing store.
572572
VoidCallback destruction_callback;
573573
} FlutterVulkanImage;
574574

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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_surface_vulkan.h"
6+
7+
#include "flutter/shell/common/shell_io_manager.h"
8+
#include "include/gpu/GrDirectContext.h"
9+
#include "include/gpu/vk/GrVkBackendContext.h"
10+
#include "shell/gpu/gpu_surface_vulkan.h"
11+
#include "shell/gpu/gpu_surface_vulkan_delegate.h"
12+
13+
namespace flutter {
14+
15+
EmbedderSurfaceVulkan::EmbedderSurfaceVulkan(
16+
VkInstance instance,
17+
VkPhysicalDevice physical_device,
18+
VkDevice device,
19+
uint32_t queue_family_index,
20+
VkQueue queue,
21+
VulkanDispatchTable vulkan_dispatch_table,
22+
std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
23+
: vk_(vulkan_dispatch_table.get_instance_proc_address),
24+
device_(vk_, physical_device, device, queue_family_index, queue),
25+
vulkan_dispatch_table_(vulkan_dispatch_table),
26+
external_view_embedder_(external_view_embedder) {
27+
// Make sure all required members of the dispatch table are checked.
28+
if (!vulkan_dispatch_table_.get_instance_proc_address ||
29+
!vulkan_dispatch_table_.get_next_image ||
30+
!vulkan_dispatch_table_.present_image) {
31+
return;
32+
}
33+
34+
vk_.SetupInstanceProcAddresses(instance);
35+
vk_.SetupDeviceProcAddresses(device);
36+
if (!vk_.IsValid()) {
37+
FML_LOG(ERROR) << "VulkanProcTable invalid.";
38+
return;
39+
}
40+
41+
main_context_ = CreateGrContext(instance, ContextType::kRender);
42+
// TODO(bdero): Add a second (optional) queue+family index to the Embedder API
43+
// to allow embedders to specify a dedicated transfer queue for
44+
// use by the resource context. Queue families with graphics
45+
// capability can always be used for memory transferring, but it
46+
// would be adventageous to use a dedicated transter queue here.
47+
resource_context_ = CreateGrContext(instance, ContextType::kResource);
48+
49+
valid_ = main_context_ && resource_context_;
50+
}
51+
52+
EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() = default;
53+
54+
// |GPUSurfaceVulkanDelegate|
55+
const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() {
56+
return vk_;
57+
}
58+
59+
// |GPUSurfaceVulkanDelegate|
60+
VkImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) {
61+
return vulkan_dispatch_table_.get_next_image(size);
62+
}
63+
64+
// |GPUSurfaceVulkanDelegate|
65+
bool EmbedderSurfaceVulkan::PresentImage(VkImage image) {
66+
return vulkan_dispatch_table_.present_image(image);
67+
}
68+
69+
// |EmbedderSurface|
70+
bool EmbedderSurfaceVulkan::IsValid() const {
71+
return valid_;
72+
}
73+
74+
// |EmbedderSurface|
75+
std::unique_ptr<Surface> EmbedderSurfaceVulkan::CreateGPUSurface() {
76+
const bool render_to_surface = !external_view_embedder_;
77+
return std::make_unique<GPUSurfaceVulkan>(this, main_context_,
78+
render_to_surface);
79+
}
80+
81+
// |EmbedderSurface|
82+
sk_sp<GrDirectContext> EmbedderSurfaceVulkan::CreateResourceContext() const {
83+
return resource_context_;
84+
}
85+
86+
sk_sp<GrDirectContext> EmbedderSurfaceVulkan::CreateGrContext(
87+
VkInstance instance,
88+
ContextType context_type) const {
89+
uint32_t skia_features = 0;
90+
if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) {
91+
FML_LOG(ERROR) << "Failed to get physical device features.";
92+
93+
return nullptr;
94+
}
95+
96+
auto get_proc = vk_.CreateSkiaGetProc();
97+
if (get_proc == nullptr) {
98+
FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia.";
99+
return nullptr;
100+
}
101+
102+
GrVkBackendContext backend_context = {
103+
.fInstance = instance,
104+
.fPhysicalDevice = device_.GetPhysicalDeviceHandle(),
105+
.fDevice = device_.GetHandle(),
106+
.fQueue = device_.GetQueueHandle(),
107+
.fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(),
108+
.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0),
109+
.fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0),
110+
.fFeatures = skia_features,
111+
.fGetProc = get_proc,
112+
.fOwnsInstanceAndDevice = false,
113+
};
114+
// TODO(bdero): Activate MEMORY_REQUIREMENTS_2 if available because VMA (the
115+
// allocator used by Skia) knows how to take advantage of these
116+
// features.
117+
/*
118+
const char* device_extensions[] = {
119+
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
120+
};
121+
GrVkExtensions vk_extensions;
122+
vk_extensions.init(backend_context.fGetProc, backend_context.fInstance,
123+
backend_context.fPhysicalDevice, 0, nullptr,
124+
countof(device_extensions), device_extensions);
125+
backend_context.fVkExtensions = &vk_extensions;
126+
*/
127+
128+
GrContextOptions options =
129+
MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan);
130+
options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
131+
return GrDirectContext::MakeVulkan(backend_context, options);
132+
}
133+
134+
} // namespace flutter

0 commit comments

Comments
 (0)