Flutter Engine
The Flutter Engine
VkTestHelper.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
10#if defined(SK_VULKAN)
11
13#include "include/gpu/GrTypes.h"
16#include "tests/TestType.h"
19
20#if defined(SK_GANESH)
23#endif
24
25#if defined(SK_GRAPHITE)
29#endif
30
31#define ACQUIRE_INST_VK_PROC(name) \
32 fVk##name = reinterpret_cast<PFN_vk##name>(instProc(fBackendContext.fInstance, "vk" #name)); \
33 if (fVk##name == nullptr) { \
34 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
35 return false; \
36 }
37
38#define ACQUIRE_DEVICE_VK_PROC(name) \
39 fVk##name = reinterpret_cast<PFN_vk##name>(fVkGetDeviceProcAddr(fDevice, "vk" #name)); \
40 if (fVk##name == nullptr) { \
41 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
42 return false; \
43 }
44
45#if defined(SK_GANESH)
46
47class GaneshVkTestHelper : public VkTestHelper {
48public:
49 GaneshVkTestHelper(bool isProtected) : VkTestHelper(isProtected) {}
50
51 ~GaneshVkTestHelper() override {
52 // Make sure any work, release procs, etc left on the context are finished with before we
53 // start tearing everything down.
54 if (fDirectContext) {
55 fDirectContext->flushAndSubmit(GrSyncCpu::kYes);
56 }
57
58 fDirectContext.reset();
59 }
60
61 bool isValid() const override { return fDirectContext != nullptr; }
62
63 sk_sp<SkSurface> createSurface(SkISize size, bool textureable, bool isProtected) override {
64 // Make Ganesh use DMSAA to better match Graphite's behavior
66
67 return ProtectedUtils::CreateProtectedSkSurface(fDirectContext.get(), size,
68 textureable, isProtected,
69 &props);
70 }
71
72 void submitAndWaitForCompletion(bool* completionMarker) override {
73 fDirectContext->submit();
74 while (!*completionMarker) {
75 fDirectContext->checkAsyncWorkCompletion();
76 }
77 }
78
79 GrDirectContext* directContext() override { return fDirectContext.get(); }
80
81protected:
82 bool init() override {
83 if (!this->setupBackendContext()) {
84 return false;
85 }
86
87 fDirectContext = GrDirectContexts::MakeVulkan(fBackendContext);
88 if (!fDirectContext) {
89 return false;
90 }
91
92 SkASSERT(fDirectContext->supportsProtectedContent() == fIsProtected);
93 return true;
94 }
95
96private:
97 sk_sp<GrDirectContext> fDirectContext;
98};
99
100#endif // SK_GANESH
101
102#if defined(SK_GRAPHITE)
103
104class GraphiteVkTestHelper : public VkTestHelper {
105public:
106 GraphiteVkTestHelper(bool isProtected) : VkTestHelper(isProtected) {}
107
108 ~GraphiteVkTestHelper() override {
109 // Make sure any work, release procs, etc left on the context are finished with before we
110 // start tearing everything down.
111
112 std::unique_ptr<skgpu::graphite::Recording> recording;
113 if (fRecorder) {
114 recording = fRecorder->snap();
115 }
116
117 if (fContext) {
118 fContext->insertRecording({ recording.get() });
120 }
121
122 recording.reset();
123 fRecorder.reset();
124 fContext.reset();
125 }
126
127 bool isValid() const override { return fContext != nullptr && fRecorder != nullptr; }
128
129 sk_sp<SkSurface> createSurface(SkISize size,
130 bool /* textureable */,
131 bool isProtected) override {
132 return ProtectedUtils::CreateProtectedSkSurface(fRecorder.get(), size,
133 skgpu::Protected(isProtected));
134 }
135
136 void submitAndWaitForCompletion(bool* completionMarker) override {
137 fContext->submit();
138 while (!*completionMarker) {
139 fContext->checkAsyncWorkCompletion();
140 }
141 }
142
143 skgpu::graphite::Recorder* recorder() override { return fRecorder.get(); }
144
145protected:
146 bool init() override {
147 if (!this->setupBackendContext()) {
148 return false;
149 }
150
151 skgpu::graphite::ContextOptions contextOptions;
152 skgpu::graphite::ContextOptionsPriv contextOptionsPriv;
153 // Needed to make ManagedGraphiteTexture::ReleaseProc (w/in CreateProtectedSkSurface) work
154 contextOptionsPriv.fStoreContextRefInRecorder = true;
155 contextOptions.fOptionsPriv = &contextOptionsPriv;
156
157 fContext = skgpu::graphite::ContextFactory::MakeVulkan(fBackendContext, contextOptions);
158 if (!fContext) {
159 return false;
160 }
161
162 SkASSERT(fContext->supportsProtectedContent() == fIsProtected);
163
164 fRecorder = fContext->makeRecorder();
165 if (!fRecorder) {
166 return false;
167 }
168
169 return true;
170 }
171
172private:
173 std::unique_ptr<skgpu::graphite::Context> fContext;
174 std::unique_ptr<skgpu::graphite::Recorder> fRecorder;
175};
176
177#endif // SK_GRAPHITE
178
179std::unique_ptr<VkTestHelper> VkTestHelper::Make(skiatest::TestType testType,
180 bool isProtected) {
181 std::unique_ptr<VkTestHelper> helper;
182
183 switch (testType) {
184#if defined(SK_GANESH)
186 helper = std::make_unique<GaneshVkTestHelper>(isProtected);
187 break;
188#endif
189#if defined(SK_GRAPHITE)
191 helper = std::make_unique<GraphiteVkTestHelper>(isProtected);
192 break;
193#endif
194 default:
195 return nullptr;
196 }
197 if (!helper->init()) {
198 return nullptr;
199 }
200
201 return helper;
202}
203
204bool VkTestHelper::setupBackendContext() {
206 if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
207 return false;
208 }
209
211 fFeatures.pNext = nullptr;
212
213 fBackendContext.fInstance = VK_NULL_HANDLE;
214 fBackendContext.fDevice = VK_NULL_HANDLE;
215
216 if (!sk_gpu_test::CreateVkBackendContext(instProc, &fBackendContext, &fExtensions,
217 &fFeatures, &fDebugCallback, nullptr,
218 sk_gpu_test::CanPresentFn(), fIsProtected)) {
219 return false;
220 }
221 fDevice = fBackendContext.fDevice;
222
223 if (fDebugCallback != VK_NULL_HANDLE) {
224 fDestroyDebugCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
225 instProc(fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT"));
226 }
227 ACQUIRE_INST_VK_PROC(DestroyInstance)
228 ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
229 ACQUIRE_INST_VK_PROC(DestroyDevice)
230
231 ACQUIRE_INST_VK_PROC(GetPhysicalDeviceFormatProperties)
232 ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties)
233
234 ACQUIRE_INST_VK_PROC(GetDeviceProcAddr)
235
236 ACQUIRE_DEVICE_VK_PROC(CreateImage)
237 ACQUIRE_DEVICE_VK_PROC(DestroyImage)
238 ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements)
239 ACQUIRE_DEVICE_VK_PROC(AllocateMemory)
240 ACQUIRE_DEVICE_VK_PROC(FreeMemory)
241 ACQUIRE_DEVICE_VK_PROC(BindImageMemory)
242 ACQUIRE_DEVICE_VK_PROC(MapMemory)
243 ACQUIRE_DEVICE_VK_PROC(UnmapMemory)
244 ACQUIRE_DEVICE_VK_PROC(FlushMappedMemoryRanges)
245 ACQUIRE_DEVICE_VK_PROC(GetImageSubresourceLayout)
246 return true;
247}
248
249VkTestHelper::~VkTestHelper() {
250 fBackendContext.fMemoryAllocator.reset();
251 if (fDevice != VK_NULL_HANDLE) {
252 fVkDeviceWaitIdle(fDevice);
253 fVkDestroyDevice(fDevice, nullptr);
254 fDevice = VK_NULL_HANDLE;
255 }
256 if (fDebugCallback != VK_NULL_HANDLE) {
257 fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
258 }
259
260 if (fBackendContext.fInstance != VK_NULL_HANDLE) {
261 fVkDestroyInstance(fBackendContext.fInstance, nullptr);
262 fBackendContext.fInstance = VK_NULL_HANDLE;
263 }
264
265 sk_gpu_test::FreeVulkanFeaturesStructs(&fFeatures);
266}
267
268#endif // SK_VULKAN
#define SkASSERT(cond)
Definition: SkAssert.h:116
const Context & fContext
@ kUnknown_SkPixelGeometry
#define ACQUIRE_INST_VK_PROC(name)
Definition: VulkanBasic.cpp:28
SK_API sk_sp< GrDirectContext > MakeVulkan(const skgpu::VulkanBackendContext &, const GrContextOptions &)
sk_sp< SkSurface > CreateProtectedSkSurface(GrDirectContext *dContext, SkISize size, bool textureable, bool isProtected, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
static bool init()
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
SK_API std::unique_ptr< Context > MakeVulkan(const VulkanBackendContext &, const ContextOptions &)
Protected
Definition: GpuTypes.h:61
Definition: SkSize.h:16
ContextOptionsPriv * fOptionsPriv
void(VKAPI_PTR * PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator)
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
Definition: vulkan_core.h:3989
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2
Definition: vulkan_core.h:271