|  | /* | 
|  | * Copyright 2019 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | // This is a Vulkan protected memory specific test. | 
|  |  | 
|  | #include "include/core/SkTypes.h" | 
|  |  | 
|  | #if defined(SK_GANESH) && defined(SK_VULKAN) | 
|  |  | 
|  | #include "include/core/SkAlphaType.h" | 
|  | #include "include/core/SkBlendMode.h" | 
|  | #include "include/core/SkBlurTypes.h" | 
|  | #include "include/core/SkCanvas.h" | 
|  | #include "include/core/SkColor.h" | 
|  | #include "include/core/SkColorSpace.h" | 
|  | #include "include/core/SkColorType.h" | 
|  | #include "include/core/SkImageInfo.h" | 
|  | #include "include/core/SkMaskFilter.h" | 
|  | #include "include/core/SkPaint.h" | 
|  | #include "include/core/SkPath.h" | 
|  | #include "include/core/SkRect.h" | 
|  | #include "include/core/SkRefCnt.h" | 
|  | #include "include/core/SkSurface.h" | 
|  | #include "include/core/SkSurfaceProps.h" | 
|  | #include "include/core/SkTypes.h" | 
|  | #include "include/gpu/GpuTypes.h" | 
|  | #include "include/gpu/GrBackendSurface.h" | 
|  | #include "include/gpu/GrDirectContext.h" | 
|  | #include "include/gpu/GrTypes.h" | 
|  | #include "tests/CtsEnforcement.h" | 
|  | #include "tests/Test.h" | 
|  | #include "tools/gpu/BackendSurfaceFactory.h" | 
|  | #include "tools/gpu/vk/VkTestHelper.h" | 
|  |  | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | struct GrContextOptions; | 
|  |  | 
|  | static sk_sp<SkSurface> create_protected_sksurface(GrDirectContext* dContext, | 
|  | skiatest::Reporter* reporter, | 
|  | bool textureable = true) { | 
|  | const int kW = 8; | 
|  | const int kH = 8; | 
|  | SkSurfaceProps surfaceProps = SkSurfaceProps(0, kRGB_H_SkPixelGeometry); | 
|  | sk_sp<SkSurface> surface; | 
|  | if (textureable) { | 
|  | surface = sk_gpu_test::MakeBackendTextureSurface(dContext, | 
|  | {kW, kH}, | 
|  | kTopLeft_GrSurfaceOrigin, | 
|  | 1, | 
|  | kRGBA_8888_SkColorType, | 
|  | /* color space */ nullptr, | 
|  | GrMipmapped::kNo, | 
|  | GrProtected::kYes, | 
|  | &surfaceProps); | 
|  | } else { | 
|  | surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext, | 
|  | {kW, kH}, | 
|  | kTopLeft_GrSurfaceOrigin, | 
|  | 1, | 
|  | kRGBA_8888_SkColorType, | 
|  | /* color space */ nullptr, | 
|  | GrProtected::kYes, | 
|  | &surfaceProps); | 
|  | } | 
|  | if (!surface) { | 
|  | ERRORF(reporter, "Could not create protected surface."); | 
|  | return nullptr; | 
|  | } | 
|  | if (textureable) { | 
|  | GrBackendTexture backendTex = | 
|  | surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); | 
|  | REPORTER_ASSERT(reporter, backendTex.isValid()); | 
|  | REPORTER_ASSERT(reporter, backendTex.isProtected()); | 
|  | } else { | 
|  | GrBackendRenderTarget backendRT = | 
|  | surface->getBackendRenderTarget(SkSurface::kFlushRead_BackendHandleAccess); | 
|  | REPORTER_ASSERT(reporter, backendRT.isValid()); | 
|  | REPORTER_ASSERT(reporter, backendRT.isProtected()); | 
|  | } | 
|  | return surface; | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_CreateNonprotectedContext, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto nonprotectedTestHelper = std::make_unique<VkTestHelper>(false); | 
|  | REPORTER_ASSERT(reporter, nonprotectedTestHelper->init()); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_CreateProtectedContext, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_CreateProtectedSkSurface, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | auto dContext = protectedTestHelper->directContext(); | 
|  | REPORTER_ASSERT(reporter, dContext != nullptr); | 
|  | create_protected_sksurface(dContext, reporter, /*textureable*/ true); | 
|  | create_protected_sksurface(dContext, reporter, /*textureable*/ false); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_CreateNonprotectedTextureInProtectedContext, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | const int kW = 8; | 
|  | const int kH = 8; | 
|  | GrBackendTexture backendTex = | 
|  | protectedTestHelper->directContext()->createBackendTexture( | 
|  | kW, kH, kRGBA_8888_SkColorType, GrMipmapped::kNo, GrRenderable::kNo, | 
|  | GrProtected::kNo); | 
|  | REPORTER_ASSERT(reporter, !backendTex.isValid()); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_CreateProtectedTextureInNonprotectedContext, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(false); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | const int kW = 8; | 
|  | const int kH = 8; | 
|  | GrBackendTexture backendTex = | 
|  | protectedTestHelper->directContext()->createBackendTexture(kW, | 
|  | kH, | 
|  | kRGBA_8888_SkColorType, | 
|  | GrMipmapped::kNo, | 
|  | GrRenderable::kNo, | 
|  | GrProtected::kYes); | 
|  | REPORTER_ASSERT(reporter, !backendTex.isValid()); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_ReadFromProtectedSurface, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | REPORTER_ASSERT(reporter, !surface->readPixels(SkImageInfo(), nullptr, 8, 0, 0)); | 
|  | } | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | struct AsyncContext { | 
|  | bool fCalled = false; | 
|  | std::unique_ptr<const SkSurface::AsyncReadResult> fResult; | 
|  | }; | 
|  |  | 
|  | static void async_callback(void* c, std::unique_ptr<const SkSurface::AsyncReadResult> result) { | 
|  | auto context = static_cast<AsyncContext*>(c); | 
|  | context->fResult = std::move(result); | 
|  | context->fCalled = true; | 
|  | } | 
|  |  | 
|  | }  // anonymous namespace | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_AsyncReadFromProtectedSurface, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | auto dContext = protectedTestHelper->directContext(); | 
|  |  | 
|  | REPORTER_ASSERT(reporter, dContext != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(dContext, reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | AsyncContext cbContext; | 
|  | const auto image_info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType, | 
|  | SkColorSpace::MakeSRGB()); | 
|  | surface->asyncRescaleAndReadPixelsYUV420(kIdentity_SkYUVColorSpace, SkColorSpace::MakeSRGB(), | 
|  | image_info.bounds(), image_info.dimensions(), | 
|  | SkSurface::RescaleGamma::kSrc, | 
|  | SkSurface::RescaleMode::kNearest, | 
|  | &async_callback, &cbContext); | 
|  | dContext->submit(); | 
|  | while (!cbContext.fCalled) { | 
|  | dContext->checkAsyncWorkCompletion(); | 
|  | } | 
|  | REPORTER_ASSERT(reporter, !cbContext.fResult); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawRectangle, reporter, options, CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | canvas->drawRect(SkRect::MakeWH(4, 4), paint); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithAntiAlias, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | paint.setAntiAlias(true); | 
|  | canvas->drawRect(SkRect::MakeWH(4, 4), paint); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithBlendMode, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | paint.setBlendMode(SkBlendMode::kColorDodge); | 
|  | canvas->drawRect(SkRect::MakeWH(4, 4), paint); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithFilter, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | paint.setStyle(SkPaint::kFill_Style); | 
|  | paint.setMaskFilter(SkMaskFilter::MakeBlur( | 
|  | SkBlurStyle::kOuter_SkBlurStyle, 1.1f)); | 
|  | canvas->drawRect(SkRect::MakeWH(4, 4), paint); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawThinPath, reporter, options, CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | paint.setStyle(SkPaint::kStroke_Style); | 
|  | paint.setAntiAlias(true); | 
|  | paint.setStrokeWidth(.4f); | 
|  | canvas->drawPath(SkPath().moveTo(4, 4).lineTo(6, 6), paint); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_SaveLayer, reporter, options, CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | auto surface = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface); | 
|  | SkCanvas* canvas = surface->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  | canvas->saveLayer(nullptr, nullptr); | 
|  | SkPaint paint; | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | canvas->drawRect(SkRect::MakeWH(4, 4), paint); | 
|  | canvas->restore(); | 
|  | } | 
|  |  | 
|  | DEF_GANESH_TEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface, | 
|  | reporter, | 
|  | options, | 
|  | CtsEnforcement::kNever) { | 
|  | auto protectedTestHelper = std::make_unique<VkTestHelper>(true); | 
|  | if (!protectedTestHelper->init()) { | 
|  | return; | 
|  | } | 
|  | REPORTER_ASSERT(reporter, protectedTestHelper->directContext() != nullptr); | 
|  |  | 
|  | // Create protected image. | 
|  | auto surface1 = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface1); | 
|  | auto image = surface1->makeImageSnapshot(); | 
|  | REPORTER_ASSERT(reporter, image); | 
|  |  | 
|  | // Create protected canvas. | 
|  | auto surface2 = create_protected_sksurface(protectedTestHelper->directContext(), reporter); | 
|  | REPORTER_ASSERT(reporter, surface2); | 
|  | SkCanvas* canvas = surface2->getCanvas(); | 
|  | REPORTER_ASSERT(reporter, canvas); | 
|  |  | 
|  | canvas->drawImage(image, 0, 0); | 
|  | } | 
|  |  | 
|  | #endif  // defined(SK_GANESH) && defined(SK_VULKAN) |