• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
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 #include "tests/Test.h"
9 
10 #if defined(SK_GANESH)
11 
12 #include "include/core/SkBitmap.h"
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkSurface.h"
15 #include "include/gpu/GrBackendSurface.h"
16 #include "include/gpu/GrDirectContext.h"
17 #include "include/gpu/ganesh/SkImageGanesh.h"
18 #include "tests/CtsEnforcement.h"
19 #include "tools/gpu/ProtectedUtils.h"
20 
21 static const int kSize = 8;
22 
DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_SmokeTest,reporter,ctxInfo,CtsEnforcement::kNever)23 DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_SmokeTest, reporter, ctxInfo, CtsEnforcement::kNever) {
24     auto dContext = ctxInfo.directContext();
25 
26     if (!dContext->supportsProtectedContent()) {
27         // Protected content not supported
28         return;
29     }
30 
31     for (bool textureable : { true, false }) {
32         for (bool isProtected : { true, false }) {
33             if (!isProtected && GrBackendApi::kVulkan == dContext->backend()) {
34                 continue;
35             }
36 
37             sk_sp<SkSurface> surface = ProtectedUtils::CreateProtectedSkSurface(dContext,
38                                                                                 { kSize, kSize },
39                                                                                 textureable,
40                                                                                 isProtected);
41             if (!surface) {
42                 continue;
43             }
44 
45             sk_sp<SkImage> image = surface->makeImageSnapshot();
46             if (!image) {
47                 ERRORF(reporter, "Could not makeImageSnapshot from a %s surface.",
48                        isProtected ? "protected" : "unprotected");
49                 continue;
50             }
51 
52             dContext->submit(GrSyncCpu::kYes);
53 
54             REPORTER_ASSERT(reporter, image->isProtected() == isProtected);
55             ProtectedUtils::CheckImageBEProtection(image.get(), isProtected);
56         }
57     }
58 
59     for (bool isProtected : { true, false }) {
60         if (!isProtected && GrBackendApi::kVulkan == dContext->backend()) {
61             continue;
62         }
63 
64         sk_sp<SkImage> image = ProtectedUtils::CreateProtectedSkImage(dContext,
65                                                                       { kSize, kSize },
66                                                                       SkColors::kBlue,
67                                                                       isProtected);
68         if (!image) {
69             continue;
70         }
71 
72         dContext->submit(GrSyncCpu::kYes);
73 
74         REPORTER_ASSERT(reporter, image->isProtected() == isProtected);
75         ProtectedUtils::CheckImageBEProtection(image.get(), isProtected);
76     }
77 
78     for (bool renderable : { true, false }) {
79         for (bool isProtected : { true, false }) {
80             GrBackendTexture beTex = dContext->createBackendTexture(16,
81                                                                     16,
82                                                                     kRGBA_8888_SkColorType,
83                                                                     SkColors::kTransparent,
84                                                                     skgpu::Mipmapped::kNo,
85                                                                     GrRenderable(renderable),
86                                                                     GrProtected(isProtected));
87 
88             REPORTER_ASSERT(reporter, beTex.isValid());
89             REPORTER_ASSERT(reporter, beTex.isProtected() == isProtected);
90 
91             dContext->flushAndSubmit(GrSyncCpu::kYes);
92 
93             {
94                 sk_sp<SkImage> img = SkImages::BorrowTextureFrom(dContext, beTex,
95                                                                  kTopLeft_GrSurfaceOrigin,
96                                                                  kRGBA_8888_SkColorType,
97                                                                  kPremul_SkAlphaType,
98                                                                  /* colorSpace= */ nullptr);
99 
100                 REPORTER_ASSERT(reporter, img->isProtected() == isProtected);
101             }
102 
103             if (beTex.isValid()) {
104                 dContext->deleteBackendTexture(beTex);
105             }
106         }
107     }
108 }
109 
110 // Verify that readPixels fails on protected surfaces
DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_readPixelsFromSurfaces,reporter,ctxInfo,CtsEnforcement::kNever)111 DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_readPixelsFromSurfaces, reporter, ctxInfo,
112                                  CtsEnforcement::kNever) {
113     auto dContext = ctxInfo.directContext();
114 
115     if (!dContext->supportsProtectedContent()) {
116         // Protected content not supported
117         return;
118     }
119 
120     for (bool isProtected : { true, false }) {
121         if (!isProtected && GrBackendApi::kVulkan == dContext->backend()) {
122             continue;
123         }
124 
125         sk_sp<SkSurface> surface = ProtectedUtils::CreateProtectedSkSurface(dContext,
126                                                                             { kSize, kSize },
127                                                                             /* textureable= */ true,
128                                                                             isProtected);
129         if (!surface) {
130             continue;
131         }
132 
133         SkBitmap readback;
134         readback.allocPixels(surface->imageInfo());
135         REPORTER_ASSERT(reporter, isProtected != surface->readPixels(readback, 0, 0));
136     }
137 }
138 
139 namespace {
140 
141 struct AsyncContext {
142     bool fCalled = false;
143     std::unique_ptr<const SkSurface::AsyncReadResult> fResult;
144 };
145 
async_callback(void * c,std::unique_ptr<const SkSurface::AsyncReadResult> result)146 static void async_callback(void* c, std::unique_ptr<const SkSurface::AsyncReadResult> result) {
147     auto context = static_cast<AsyncContext*>(c);
148     context->fResult = std::move(result);
149     context->fCalled = true;
150 }
151 
152 }  // anonymous namespace
153 
154 // Verify that asyncRescaleAndReadPixels fails on protected surfaces
DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_asyncRescaleAndReadPixelsFromSurfaces,reporter,ctxInfo,CtsEnforcement::kNever)155 DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_asyncRescaleAndReadPixelsFromSurfaces, reporter, ctxInfo,
156                                  CtsEnforcement::kNever) {
157     auto dContext = ctxInfo.directContext();
158 
159     if (!dContext->supportsProtectedContent()) {
160         // Protected content not supported
161         return;
162     }
163 
164     for (bool isProtected : { true, false }) {
165         if (!isProtected && GrBackendApi::kVulkan == dContext->backend()) {
166             continue;
167         }
168 
169         sk_sp<SkSurface> surface = ProtectedUtils::CreateProtectedSkSurface(dContext,
170                                                                             { kSize, kSize },
171                                                                             /* textureable= */ true,
172                                                                             isProtected);
173         if (!surface) {
174             continue;
175         }
176 
177         AsyncContext cbContext;
178 
179         surface->asyncRescaleAndReadPixels(surface->imageInfo(),
180                                            SkIRect::MakeWH(surface->width(), surface->height()),
181                                            SkSurface::RescaleGamma::kSrc,
182                                            SkSurface::RescaleMode::kNearest,
183                                            async_callback, &cbContext);
184         dContext->submit();
185         while (!cbContext.fCalled) {
186             dContext->checkAsyncWorkCompletion();
187         }
188         REPORTER_ASSERT(reporter, isProtected != SkToBool(cbContext.fResult));
189     }
190 }
191 
192 #endif  // defined(SK_GANESH)
193