Flutter Engine
The Flutter Engine
shell_test_platform_view_vulkan.cc
Go to the documentation of this file.
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/common/shell_test_platform_view_vulkan.h"
6
7#include <utility>
8
9#include "flutter/common/graphics/persistent_cache.h"
10#include "flutter/flutter_vma/flutter_skia_vma.h"
11#include "flutter/shell/common/context_options.h"
12#include "flutter/vulkan/vulkan_skia_proc_table.h"
13#include "flutter/vulkan/vulkan_utilities.h"
14
19
20#if OS_FUCHSIA
21#define VULKAN_SO_PATH "libvulkan.so"
22#else
23#include "flutter/vulkan/swiftshader_path.h"
24#endif
25
26namespace flutter {
27namespace testing {
28
30 PlatformView::Delegate& delegate,
31 const TaskRunners& task_runners,
32 std::shared_ptr<ShellTestVsyncClock> vsync_clock,
33 CreateVsyncWaiter create_vsync_waiter,
34 std::shared_ptr<ShellTestExternalViewEmbedder>
35 shell_test_external_view_embedder)
36 : ShellTestPlatformView(delegate, task_runners),
37 create_vsync_waiter_(std::move(create_vsync_waiter)),
38 vsync_clock_(std::move(vsync_clock)),
39 proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>(VULKAN_SO_PATH)),
40 shell_test_external_view_embedder_(
41 std::move(shell_test_external_view_embedder)) {}
42
44
45std::unique_ptr<VsyncWaiter> ShellTestPlatformViewVulkan::CreateVSyncWaiter() {
46 return create_vsync_waiter_();
47}
48
50 vsync_clock_->SimulateVSync();
51}
52
53// |PlatformView|
54std::unique_ptr<Surface> ShellTestPlatformViewVulkan::CreateRenderingSurface() {
55 return std::make_unique<OffScreenSurface>(proc_table_,
56 shell_test_external_view_embedder_);
57}
58
59// |PlatformView|
60std::shared_ptr<ExternalViewEmbedder>
61ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() {
62 return shell_test_external_view_embedder_;
63}
64
65// |PlatformView|
66PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() {
67 return [](DefaultPointerDataDispatcher::Delegate& delegate) {
68 return std::make_unique<SmoothPointerDataDispatcher>(delegate);
69 };
70}
71
72// TODO(gw280): This code was forked from vulkan_window.cc specifically for
73// shell_test.
74// We need to merge this functionality back into //vulkan.
75// https://github.com/flutter/flutter/issues/51132
76ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface(
78 std::shared_ptr<ShellTestExternalViewEmbedder>
79 shell_test_external_view_embedder)
80 : vk_(std::move(vk)),
81 shell_test_external_view_embedder_(
82 std::move(shell_test_external_view_embedder)) {
83 if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) {
84 FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses.";
85 return;
86 }
87
88 // Create the application instance.
89 std::vector<std::string> extensions = {
91 };
92
93 application_ = std::make_unique<vulkan::VulkanApplication>(
94 *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0),
95 VK_MAKE_VERSION(1, 1, 0), true);
96
97 if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) {
98 // Make certain the application instance was created and it set up the
99 // instance proc table entries.
100 FML_DLOG(ERROR) << "Instance proc addresses have not been set up.";
101 return;
102 }
103
104 // Create the device.
105
106 logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();
107
108 if (logical_device_ == nullptr || !logical_device_->IsValid() ||
109 !vk_->AreDeviceProcsSetup()) {
110 // Make certain the device was created and it set up the device proc table
111 // entries.
112 FML_DLOG(ERROR) << "Device proc addresses have not been set up.";
113 return;
114 }
115
116 memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make(
117 application_->GetAPIVersion(), application_->GetInstance(),
118 logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(),
119 vk_, true);
120
121 // Create the Skia GrContext.
122 if (!CreateSkiaGrContext()) {
123 FML_DLOG(ERROR) << "Could not create Skia context.";
124 return;
125 }
126
127 valid_ = true;
128}
129
130bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() {
131 GrVkBackendContext backend_context;
132 skgpu::VulkanExtensions no_extensions;
133 // For now, Skia crashes if fDeviceFeatures is set but fVkExtensions is not.
134 backend_context.fVkExtensions = &no_extensions;
136 // It may be tempting to put features into backend_context here
137 // and pass just backend_context into the below function, however the pointers
138 // for features are const, so we won't be able to update them.
139
140 if (!this->CreateSkiaBackendContext(&backend_context, &features)) {
141 FML_DLOG(ERROR) << "Could not create Skia backend context.";
142 return false;
143 }
144
145 const auto options =
147
148 sk_sp<GrDirectContext> context =
149 GrDirectContexts::MakeVulkan(backend_context, options);
150
151 if (context == nullptr) {
152 FML_DLOG(ERROR) << "Failed to create GrDirectContext";
153 return false;
154 }
155
157
158 context_ = context;
159
160 return true;
161}
162
163bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext(
164 GrVkBackendContext* context,
165 VkPhysicalDeviceFeatures* features) {
166 FML_CHECK(context);
167 FML_CHECK(features);
168 auto getProc = CreateSkiaGetProc(vk_);
169
170 if (getProc == nullptr) {
171 FML_DLOG(ERROR) << "GetProcAddress is null";
172 return false;
173 }
174
175 if (!logical_device_->GetPhysicalDeviceFeatures(features)) {
176 FML_DLOG(ERROR) << "Failed to get Physical Device features";
177 return false;
178 }
179
180 context->fInstance = application_->GetInstance();
181 context->fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle();
182 context->fDevice = logical_device_->GetHandle();
183 context->fQueue = logical_device_->GetQueueHandle();
184 context->fGraphicsQueueIndex = logical_device_->GetGraphicsQueueIndex();
185 context->fMaxAPIVersion = application_->GetAPIVersion();
186 context->fDeviceFeatures = features;
187 context->fGetProc = std::move(getProc);
188 context->fMemoryAllocator = memory_allocator_;
189
190 return true;
191}
192
193ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {}
194
195bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() {
196 return valid_;
197}
198
199std::unique_ptr<SurfaceFrame>
200ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame(
201 const SkISize& size) {
205 image_info, 0, nullptr);
206 SurfaceFrame::SubmitCallback callback = [](const SurfaceFrame&,
207 DlCanvas* canvas) -> bool {
208 canvas->Flush();
209 return true;
210 };
211
212 SurfaceFrame::FramebufferInfo framebuffer_info;
213 framebuffer_info.supports_readback = true;
214
215 return std::make_unique<SurfaceFrame>(std::move(surface), framebuffer_info,
216 std::move(callback),
217 /*frame_size=*/SkISize::Make(800, 600));
218}
219
221 return context_.get();
222}
223
224SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation()
225 const {
227 matrix.reset();
228 return matrix;
229}
230
231} // namespace testing
232} // namespace flutter
const char * options
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
void setResourceCacheLimit(size_t maxResourceBytes)
static sk_sp< VulkanMemoryAllocator > Make(uint32_t vulkan_api_version, VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, const fml::RefPtr< vulkan::VulkanProcTable > &vk, bool mustUseCoherentHostVisibleMemory)
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
Definition: platform_view.h:60
std::function< bool(SurfaceFrame &surface_frame, DlCanvas *canvas)> SubmitCallback
Definition: surface_frame.h:27
ShellTestPlatformViewVulkan(PlatformView::Delegate &delegate, const TaskRunners &task_runners, std::shared_ptr< ShellTestVsyncClock > vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr< ShellTestExternalViewEmbedder > shell_test_external_view_embedder)
VkSurfaceKHR surface
Definition: main.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DLOG(severity)
Definition: logging.h:102
#define FML_CHECK(condition)
Definition: logging.h:85
SK_API sk_sp< GrDirectContext > MakeVulkan(const skgpu::VulkanBackendContext &, const GrContextOptions &)
SK_API GrDirectContext * GetContext(const SkImage *src)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
std::function< std::unique_ptr< VsyncWaiter >()> CreateVsyncWaiter
GrContextOptions MakeDefaultContextOptions(ContextType type, std::optional< GrBackendApi > api)
Initializes GrContextOptions with values suitable for Flutter. The options can be further tweaked bef...
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
@ kRender
The context is used to render to a texture or renderbuffer.
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: ascii_trie.cc:9
RefPtr< T > MakeRefCounted(Args &&... args)
Definition: ref_ptr.h:248
vk
Definition: malisc.py:42
Definition: ref_ptr.h:256
flutter::DlCanvas DlCanvas
static const size_t kGrCacheMaxByteSize
GrVkGetProc CreateSkiaGetProc(const fml::RefPtr< vulkan::VulkanProcTable > &vk)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
sk_sp< VulkanMemoryAllocator > fMemoryAllocator
const VkPhysicalDeviceFeatures * fDeviceFeatures
const skgpu::VulkanExtensions * fVkExtensions
#define VULKAN_SO_PATH
#define ERROR(message)
Definition: elf_loader.cc:260
#define VK_MAKE_VERSION(major, minor, patch)
Definition: vulkan_core.h:78
#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME
Definition: vulkan_core.h:8762