blob: 2283a7f38ed957e77c66d2d6cc928936926f99cd [file] [log] [blame]
Emircan Uysaler23ca4e72019-06-24 10:53:09 -04001/*
2 * Copyright 2019 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
8// This is a Vulkan protected memory specific test.
9
10#include "include/core/SkTypes.h"
11
12#if SK_SUPPORT_GPU && defined(SK_VULKAN)
13
14#include "include/core/SkCanvas.h"
15#include "include/core/SkMaskFilter.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkSurface.h"
18#include "include/gpu/GrBackendSurface.h"
19#include "include/gpu/vk/GrVkBackendContext.h"
20#include "include/gpu/vk/GrVkExtensions.h"
21#include "tests/Test.h"
22#include "tools/gpu/GrContextFactory.h"
23#include "tools/gpu/vk/VkTestUtils.h"
24
25namespace {
26
27#define DECLARE_VK_PROC(name) PFN_vk##name fVk##name
28
29#define ACQUIRE_INST_VK_PROC(name) \
30 fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
31 VK_NULL_HANDLE)); \
32 if (fVk##name == nullptr) { \
33 ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
34 return false; \
35 }
36
37#define ACQUIRE_DEVICE_VK_PROC(name) \
38 fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
39 if (fVk##name == nullptr) { \
40 ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
41 return false; \
42 }
43
44class VulkanTestHelper {
45public:
46 VulkanTestHelper(bool isProtected) : fIsProtected(isProtected) {}
47
48 ~VulkanTestHelper() {
49 cleanup();
50 }
51
52 bool init(skiatest::Reporter* reporter);
53
54 GrContext* grContext() { return fGrContext.get(); }
55
56 sk_sp<SkSurface> createSkSurface(skiatest::Reporter* reporter);
57
58 private:
59 void cleanup();
60
61 DECLARE_VK_PROC(DestroyInstance);
62 DECLARE_VK_PROC(DeviceWaitIdle);
63 DECLARE_VK_PROC(DestroyDevice);
64
65 bool fIsProtected = false;
66 VkDevice fDevice = VK_NULL_HANDLE;
67
68 GrVkExtensions* fExtensions = nullptr;
69 VkPhysicalDeviceFeatures2* fFeatures = nullptr;
70 VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
71 PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr;
72 GrVkBackendContext fBackendContext;
73 sk_sp<GrContext> fGrContext;
74};
75
76} // namespace
77
78bool VulkanTestHelper::init(skiatest::Reporter* reporter) {
79 PFN_vkGetInstanceProcAddr instProc;
80 PFN_vkGetDeviceProcAddr devProc;
81 if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
82 return false;
83 }
84 auto getProc = [&instProc, &devProc](const char* proc_name,
85 VkInstance instance, VkDevice device) {
86 if (device != VK_NULL_HANDLE) {
87 return devProc(device, proc_name);
88 }
89 return instProc(instance, proc_name);
90 };
91
92 fExtensions = new GrVkExtensions();
93 fFeatures = new VkPhysicalDeviceFeatures2;
94 memset(fFeatures, 0, sizeof(VkPhysicalDeviceFeatures2));
95 fFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
96 fFeatures->pNext = nullptr;
97
98 fBackendContext.fInstance = VK_NULL_HANDLE;
99 fBackendContext.fDevice = VK_NULL_HANDLE;
100
101 if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, fExtensions,
102 fFeatures, &fDebugCallback, nullptr,
103 sk_gpu_test::CanPresentFn(), fIsProtected)) {
104 return false;
105 }
106 fDevice = fBackendContext.fDevice;
107
108 if (fDebugCallback != VK_NULL_HANDLE) {
109 fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
110 fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT");
111 }
112 ACQUIRE_INST_VK_PROC(DestroyInstance)
113 ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
114 ACQUIRE_INST_VK_PROC(DestroyDevice)
115
116 fGrContext = GrContext::MakeVulkan(fBackendContext);
117 if (!fGrContext) {
118 return false;
119 }
120
121 return true;
122}
123
124void VulkanTestHelper::cleanup() {
125 fGrContext.reset();
126
127 fBackendContext.fMemoryAllocator.reset();
128 if (fDevice != VK_NULL_HANDLE) {
129 fVkDeviceWaitIdle(fDevice);
130 fVkDestroyDevice(fDevice, nullptr);
131 fDevice = VK_NULL_HANDLE;
132 }
133 if (fDebugCallback != VK_NULL_HANDLE) {
134 fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
135 }
136
137 if (fBackendContext.fInstance != VK_NULL_HANDLE) {
138 fVkDestroyInstance(fBackendContext.fInstance, nullptr);
139 fBackendContext.fInstance = VK_NULL_HANDLE;
140 }
141
142 delete fExtensions;
143
144 sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures);
145 delete fFeatures;
146}
147
148sk_sp<SkSurface> VulkanTestHelper::createSkSurface(skiatest::Reporter* reporter) {
149 const int kW = 8;
150 const int kH = 8;
151 GrBackendTexture backendTex = grContext()->createBackendTexture(
152 kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
153 fIsProtected ? GrProtected::kYes : GrProtected::kNo);
154 REPORTER_ASSERT(reporter, backendTex.isValid());
155 REPORTER_ASSERT(reporter, backendTex.isProtected() == fIsProtected);
156
157 SkSurfaceProps surfaceProps =
158 SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
159 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
160 grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
161 kRGBA_8888_SkColorType, nullptr, &surfaceProps);
162 REPORTER_ASSERT(reporter, surface);
163 return surface;
164}
165
166DEF_GPUTEST(VkProtectedContext_CreateNonprotectedContext, reporter, options) {
167 auto nonprotectedTestHelper = std::make_unique<VulkanTestHelper>(false);
168 REPORTER_ASSERT(reporter, nonprotectedTestHelper->init(reporter));
169}
170
171
172DEF_GPUTEST(VkProtectedContext_CreateProtectedContext, reporter, options) {
173 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
174 if (!protectedTestHelper->init(reporter)) {
175 return;
176 }
177}
178
179DEF_GPUTEST(VkProtectedContext_CreateProtectedSkSurface, reporter, options) {
180 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
181 if (!protectedTestHelper->init(reporter)) {
182 return;
183 }
184 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
185
186 const int kW = 8;
187 const int kH = 8;
188 GrBackendTexture backendTex =
189 protectedTestHelper->grContext()->createBackendTexture(
190 kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
191 GrProtected::kYes);
192 REPORTER_ASSERT(reporter, backendTex.isValid());
193 REPORTER_ASSERT(reporter, backendTex.isProtected());
194
195 SkSurfaceProps surfaceProps =
196 SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
197 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
198 protectedTestHelper->grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
199 kRGBA_8888_SkColorType, nullptr, &surfaceProps);
200 REPORTER_ASSERT(reporter, surface);
201
202 protectedTestHelper->grContext()->deleteBackendTexture(backendTex);
203}
204
205DEF_GPUTEST(VkProtectedContext_CreateNonprotectedTextureInProtectedContext, reporter, options) {
206 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
207 if (!protectedTestHelper->init(reporter)) {
208 return;
209 }
210 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
211
212 const int kW = 8;
213 const int kH = 8;
214 GrBackendTexture backendTex =
215 protectedTestHelper->grContext()->createBackendTexture(
216 kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
217 GrProtected::kNo);
218 REPORTER_ASSERT(reporter, !backendTex.isValid());
219}
220
221DEF_GPUTEST(VkProtectedContext_CreateProtectedTextureInNonprotectedContext, reporter, options) {
222 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(false);
223 if (!protectedTestHelper->init(reporter)) {
224 return;
225 }
226 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
227
228 const int kW = 8;
229 const int kH = 8;
230 GrBackendTexture backendTex =
231 protectedTestHelper->grContext()->createBackendTexture(
232 kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
233 GrProtected::kYes);
234 REPORTER_ASSERT(reporter, !backendTex.isValid());
235}
236
237DEF_GPUTEST(VkProtectedContext_ReadFromProtectedSurface, reporter, options) {
238 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
239 if (!protectedTestHelper->init(reporter)) {
240 return;
241 }
242 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
243
244 auto surface = protectedTestHelper->createSkSurface(reporter);
245 REPORTER_ASSERT(reporter, surface);
246 REPORTER_ASSERT(reporter,
247 !surface->readPixels(SkImageInfo(), nullptr, 8, 0, 0));
248
249 protectedTestHelper->grContext()->deleteBackendTexture(
250 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
251}
252
Emircan Uysaler76974762019-10-25 13:28:54 -0400253namespace {
254
255struct AsyncContext {
256 bool fCalled = false;
257 std::unique_ptr<const SkSurface::AsyncReadResult> fResult;
258};
259
260static void async_callback(void* c, std::unique_ptr<const SkSurface::AsyncReadResult> result) {
261 auto context = static_cast<AsyncContext*>(c);
262 context->fResult = std::move(result);
263 context->fCalled = true;
264};
265
266} // anonymous namespace
267
268DEF_GPUTEST(VkProtectedContext_AsyncReadFromProtectedSurface, reporter, options) {
269 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
270 if (!protectedTestHelper->init(reporter)) {
271 return;
272 }
273 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
274
275 auto surface = protectedTestHelper->createSkSurface(reporter);
276 REPORTER_ASSERT(reporter, surface);
277 AsyncContext cbContext;
278 const auto image_info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
279 SkColorSpace::MakeSRGB());
280 surface->asyncRescaleAndReadPixelsYUV420(kIdentity_SkYUVColorSpace, SkColorSpace::MakeSRGB(),
281 image_info.bounds(), image_info.dimensions(),
282 SkSurface::RescaleGamma::kSrc, kNone_SkFilterQuality,
283 &async_callback, &cbContext);
284 while (!cbContext.fCalled) {
285 surface->getCanvas()->getGrContext()->checkAsyncWorkCompletion();
286 }
287 REPORTER_ASSERT(reporter, !cbContext.fResult);
288
289 protectedTestHelper->grContext()->deleteBackendTexture(
290 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
291}
292
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400293DEF_GPUTEST(VkProtectedContext_DrawRectangle, reporter, options) {
294 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
295 if (!protectedTestHelper->init(reporter)) {
296 return;
297 }
298 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
299
300 auto surface = protectedTestHelper->createSkSurface(reporter);
301 REPORTER_ASSERT(reporter, surface);
302 SkCanvas* canvas = surface->getCanvas();
303 REPORTER_ASSERT(reporter, canvas);
304 SkPaint paint;
305 paint.setColor(SK_ColorBLACK);
306 canvas->drawRect(SkRect::MakeWH(4, 4), paint);
307
308 GrFlushInfo flushInfo;
309 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
310 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
311 protectedTestHelper->grContext()->deleteBackendTexture(
312 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
313}
314
315DEF_GPUTEST(VkProtectedContext_DrawRectangleWithAntiAlias, reporter, options) {
316 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
317 if (!protectedTestHelper->init(reporter)) {
318 return;
319 }
320 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
321
322 auto surface = protectedTestHelper->createSkSurface(reporter);
323 REPORTER_ASSERT(reporter, surface);
324 SkCanvas* canvas = surface->getCanvas();
325 REPORTER_ASSERT(reporter, canvas);
326 SkPaint paint;
327 paint.setColor(SK_ColorBLACK);
328 paint.setAntiAlias(true);
329 canvas->drawRect(SkRect::MakeWH(4, 4), paint);
330
331 GrFlushInfo flushInfo;
332 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
333 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
334 protectedTestHelper->grContext()->deleteBackendTexture(
335 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
336}
337
338DEF_GPUTEST(VkProtectedContext_DrawRectangleWithBlendMode, reporter, options) {
339 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
340 if (!protectedTestHelper->init(reporter)) {
341 return;
342 }
343 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
344
345 auto surface = protectedTestHelper->createSkSurface(reporter);
346 REPORTER_ASSERT(reporter, surface);
347 SkCanvas* canvas = surface->getCanvas();
348 REPORTER_ASSERT(reporter, canvas);
349 SkPaint paint;
350 paint.setColor(SK_ColorBLACK);
351 paint.setBlendMode(SkBlendMode::kColorDodge);
352 canvas->drawRect(SkRect::MakeWH(4, 4), paint);
353
354 GrFlushInfo flushInfo;
355 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
356 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
357 protectedTestHelper->grContext()->deleteBackendTexture(
358 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
359}
360
361DEF_GPUTEST(VkProtectedContext_DrawRectangleWithFilter, reporter, options) {
362 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
363 if (!protectedTestHelper->init(reporter)) {
364 return;
365 }
366 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
367
368 auto surface = protectedTestHelper->createSkSurface(reporter);
369 REPORTER_ASSERT(reporter, surface);
370 SkCanvas* canvas = surface->getCanvas();
371 REPORTER_ASSERT(reporter, canvas);
372 SkPaint paint;
373 paint.setColor(SK_ColorBLACK);
374 paint.setStyle(SkPaint::kFill_Style);
375 paint.setMaskFilter(SkMaskFilter::MakeBlur(
376 SkBlurStyle::kOuter_SkBlurStyle, 1.1f));
377 canvas->drawRect(SkRect::MakeWH(4, 4), paint);
378
379 GrFlushInfo flushInfo;
380 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
381 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
382 protectedTestHelper->grContext()->deleteBackendTexture(
383 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
384}
385
386DEF_GPUTEST(VkProtectedContext_DrawThinPath, reporter, options) {
387 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
388 if (!protectedTestHelper->init(reporter)) {
389 return;
390 }
391 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
392
393 auto surface = protectedTestHelper->createSkSurface(reporter);
394 REPORTER_ASSERT(reporter, surface);
395 SkCanvas* canvas = surface->getCanvas();
396 REPORTER_ASSERT(reporter, canvas);
397 SkPaint paint;
398 paint.setColor(SK_ColorBLACK);
399 paint.setStyle(SkPaint::kStroke_Style);
400 paint.setAntiAlias(true);
401 paint.setStrokeWidth(.4f);
402 canvas->drawPath(SkPath().moveTo(4, 4).lineTo(6, 6), paint);
403
404 GrFlushInfo flushInfo;
405 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
406 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
407 protectedTestHelper->grContext()->deleteBackendTexture(
408 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
409}
410
411DEF_GPUTEST(VkProtectedContext_SaveLayer, reporter, options) {
412 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
413 if (!protectedTestHelper->init(reporter)) {
414 return;
415 }
416 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
417
418 auto surface = protectedTestHelper->createSkSurface(reporter);
419 REPORTER_ASSERT(reporter, surface);
420 SkCanvas* canvas = surface->getCanvas();
421 REPORTER_ASSERT(reporter, canvas);
422 canvas->saveLayer(nullptr, nullptr);
423 SkPaint paint;
424 paint.setColor(SK_ColorBLACK);
425 canvas->drawRect(SkRect::MakeWH(4, 4), paint);
426 canvas->restore();
427
428 GrFlushInfo flushInfo;
429 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
430 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
431 protectedTestHelper->grContext()->deleteBackendTexture(
432 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
433}
434
435
436DEF_GPUTEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface, reporter, options) {
437 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
438 if (!protectedTestHelper->init(reporter)) {
439 return;
440 }
441 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
442
443 // Create protected image.
444 auto surface1 = protectedTestHelper->createSkSurface(reporter);
445 REPORTER_ASSERT(reporter, surface1);
446 auto image = surface1->makeImageSnapshot();
447 REPORTER_ASSERT(reporter, image);
448
449 // Create protected canvas.
450 auto surface2 = protectedTestHelper->createSkSurface(reporter);
451 REPORTER_ASSERT(reporter, surface2);
452 SkCanvas* canvas = surface2->getCanvas();
453 REPORTER_ASSERT(reporter, canvas);
454
455 canvas->drawImage(image, 0, 0);
456
457 GrFlushInfo flushInfo;
458 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
459 surface1->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
460 protectedTestHelper->grContext()->deleteBackendTexture(
461 surface1->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
462 surface2->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
463 protectedTestHelper->grContext()->deleteBackendTexture(
464 surface2->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
465}
466
Robert Phillips3cd54322019-07-10 09:28:59 -0400467//////////////////////////////////////////////////////////////////////////////////////////////////
468// Test out DDLs using a protected Vulkan context
469
470void DDLMakeRenderTargetTestImpl(GrContext* context, skiatest::Reporter* reporter);
471
472DEF_GPUTEST(VkProtectedContext_DDLMakeRenderTargetTest, reporter, ctxInfo) {
473 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
474 if (!protectedTestHelper->init(reporter)) {
475 return;
476 }
477 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
478
479 DDLMakeRenderTargetTestImpl(protectedTestHelper->grContext(), reporter);
480}
481
482void DDLSurfaceCharacterizationTestImpl(GrContext* context, skiatest::Reporter* reporter);
483
484DEF_GPUTEST(VkProtectedContext_DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
485 auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
486 if (!protectedTestHelper->init(reporter)) {
487 return;
488 }
489 REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
490
491 DDLSurfaceCharacterizationTestImpl(protectedTestHelper->grContext(), reporter);
492}
493
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400494#endif // SK_SUPPORT_GPU && defined(SK_VULKAN)