xref: /aosp_15_r20/external/skia/tests/DeferredDisplayListTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextThreadSafeProxy.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayList.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayListRecorder.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrPromiseImageTexture.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/SkImageChromium.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDeferredDisplayListPriv.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/BackendSurfaceFactory.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ManagedBackendTexture.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ProxyUtils.h"
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
47*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
48*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
49*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker class SkImage;
52*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
55*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLDefines.h"
58*c8dee2aaSAndroid Build Coastguard Worker #endif
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
61*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
62*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkTypes.h"
63*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrVkSecondaryCBDrawContext.h"
64*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkCaps.h"
65*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/vk/VkTestHelper.h"
66*c8dee2aaSAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
67*c8dee2aaSAndroid Build Coastguard Worker #endif
68*c8dee2aaSAndroid Build Coastguard Worker 
is_compatible(const GrSurfaceCharacterization & gsc,const GrBackendTexture & backendTex)69*c8dee2aaSAndroid Build Coastguard Worker static bool is_compatible(const GrSurfaceCharacterization& gsc, const GrBackendTexture& backendTex) {
70*c8dee2aaSAndroid Build Coastguard Worker     if (!gsc.isValid() || !backendTex.isValid()) {
71*c8dee2aaSAndroid Build Coastguard Worker         return false;
72*c8dee2aaSAndroid Build Coastguard Worker     }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.backendFormat() != backendTex.getBackendFormat()) {
75*c8dee2aaSAndroid Build Coastguard Worker         return false;
76*c8dee2aaSAndroid Build Coastguard Worker     }
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.usesGLFBO0()) {
79*c8dee2aaSAndroid Build Coastguard Worker         // It is a backend texture so can't be wrapping FBO0
80*c8dee2aaSAndroid Build Coastguard Worker         return false;
81*c8dee2aaSAndroid Build Coastguard Worker     }
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.vulkanSecondaryCBCompatible()) {
84*c8dee2aaSAndroid Build Coastguard Worker         return false;
85*c8dee2aaSAndroid Build Coastguard Worker     }
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.vkRTSupportsInputAttachment()) {
88*c8dee2aaSAndroid Build Coastguard Worker         if (backendTex.backend() != GrBackendApi::kVulkan) {
89*c8dee2aaSAndroid Build Coastguard Worker             return false;
90*c8dee2aaSAndroid Build Coastguard Worker         }
91*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
92*c8dee2aaSAndroid Build Coastguard Worker         GrVkImageInfo vkInfo;
93*c8dee2aaSAndroid Build Coastguard Worker         if (!GrBackendTextures::GetVkImageInfo(backendTex, &vkInfo)) {
94*c8dee2aaSAndroid Build Coastguard Worker             return false;
95*c8dee2aaSAndroid Build Coastguard Worker         }
96*c8dee2aaSAndroid Build Coastguard Worker         if (!SkToBool(vkInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
97*c8dee2aaSAndroid Build Coastguard Worker             return false;
98*c8dee2aaSAndroid Build Coastguard Worker         }
99*c8dee2aaSAndroid Build Coastguard Worker #endif  // SK_VULKAN
100*c8dee2aaSAndroid Build Coastguard Worker     }
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.isMipMapped() && !backendTex.hasMipmaps()) {
103*c8dee2aaSAndroid Build Coastguard Worker         // backend texture is allowed to have mipmaps even if the characterization doesn't require
104*c8dee2aaSAndroid Build Coastguard Worker         // them.
105*c8dee2aaSAndroid Build Coastguard Worker         return false;
106*c8dee2aaSAndroid Build Coastguard Worker     }
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.width() != backendTex.width() || gsc.height() != backendTex.height()) {
109*c8dee2aaSAndroid Build Coastguard Worker         return false;
110*c8dee2aaSAndroid Build Coastguard Worker     }
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     if (gsc.isProtected() != skgpu::Protected(backendTex.isProtected())) {
113*c8dee2aaSAndroid Build Coastguard Worker         return false;
114*c8dee2aaSAndroid Build Coastguard Worker     }
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker     return true;
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker class SurfaceParameters {
120*c8dee2aaSAndroid Build Coastguard Worker public:
121*c8dee2aaSAndroid Build Coastguard Worker     static const int kNumParams      = 12;
122*c8dee2aaSAndroid Build Coastguard Worker     static const int kFBO0Count      = 9;
123*c8dee2aaSAndroid Build Coastguard Worker     static const int kVkSCBCount     = 11;
124*c8dee2aaSAndroid Build Coastguard Worker 
SurfaceParameters(GrRecordingContext * rContext)125*c8dee2aaSAndroid Build Coastguard Worker     SurfaceParameters(GrRecordingContext* rContext)
126*c8dee2aaSAndroid Build Coastguard Worker             : fBackend(rContext->backend())
127*c8dee2aaSAndroid Build Coastguard Worker             , fCanBeProtected(false)
128*c8dee2aaSAndroid Build Coastguard Worker             , fWidth(64)
129*c8dee2aaSAndroid Build Coastguard Worker             , fHeight(64)
130*c8dee2aaSAndroid Build Coastguard Worker             , fOrigin(kTopLeft_GrSurfaceOrigin)
131*c8dee2aaSAndroid Build Coastguard Worker             , fColorType(kRGBA_8888_SkColorType)
132*c8dee2aaSAndroid Build Coastguard Worker             , fColorSpace(SkColorSpace::MakeSRGB())
133*c8dee2aaSAndroid Build Coastguard Worker             , fSampleCount(1)
134*c8dee2aaSAndroid Build Coastguard Worker             , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
135*c8dee2aaSAndroid Build Coastguard Worker             , fShouldCreateMipMaps(skgpu::Mipmapped::kYes)
136*c8dee2aaSAndroid Build Coastguard Worker             , fUsesGLFBO0(false)
137*c8dee2aaSAndroid Build Coastguard Worker             , fIsTextureable(true)
138*c8dee2aaSAndroid Build Coastguard Worker             , fIsProtected(skgpu::Protected::kNo)
139*c8dee2aaSAndroid Build Coastguard Worker             , fVkRTSupportsInputAttachment(false)
140*c8dee2aaSAndroid Build Coastguard Worker             , fForVulkanSecondaryCommandBuffer(false) {
141*c8dee2aaSAndroid Build Coastguard Worker         const GrCaps* caps = rContext->priv().caps();
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker         if (rContext->backend() == GrBackendApi::kOpenGL ||
144*c8dee2aaSAndroid Build Coastguard Worker             rContext->backend() == GrBackendApi::kVulkan) {
145*c8dee2aaSAndroid Build Coastguard Worker             fCanBeProtected = caps->supportsProtectedContent();
146*c8dee2aaSAndroid Build Coastguard Worker             if (fCanBeProtected) {
147*c8dee2aaSAndroid Build Coastguard Worker                 fIsProtected = skgpu::Protected::kYes;
148*c8dee2aaSAndroid Build Coastguard Worker             }
149*c8dee2aaSAndroid Build Coastguard Worker         }
150*c8dee2aaSAndroid Build Coastguard Worker 
151*c8dee2aaSAndroid Build Coastguard Worker         if (!caps->mipmapSupport()) {
152*c8dee2aaSAndroid Build Coastguard Worker             fShouldCreateMipMaps = skgpu::Mipmapped::kNo;
153*c8dee2aaSAndroid Build Coastguard Worker         }
154*c8dee2aaSAndroid Build Coastguard Worker     }
155*c8dee2aaSAndroid Build Coastguard Worker 
sampleCount() const156*c8dee2aaSAndroid Build Coastguard Worker     int sampleCount() const { return fSampleCount; }
157*c8dee2aaSAndroid Build Coastguard Worker 
setColorType(SkColorType ct)158*c8dee2aaSAndroid Build Coastguard Worker     void setColorType(SkColorType ct) { fColorType = ct; }
colorType() const159*c8dee2aaSAndroid Build Coastguard Worker     SkColorType colorType() const { return fColorType; }
setColorSpace(sk_sp<SkColorSpace> cs)160*c8dee2aaSAndroid Build Coastguard Worker     void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
disableTextureability()161*c8dee2aaSAndroid Build Coastguard Worker     void disableTextureability() {
162*c8dee2aaSAndroid Build Coastguard Worker         fIsTextureable = false;
163*c8dee2aaSAndroid Build Coastguard Worker         fShouldCreateMipMaps = skgpu::Mipmapped::kNo;
164*c8dee2aaSAndroid Build Coastguard Worker     }
setShouldCreateMipMaps(skgpu::Mipmapped shouldCreateMipMaps)165*c8dee2aaSAndroid Build Coastguard Worker     void setShouldCreateMipMaps(skgpu::Mipmapped shouldCreateMipMaps) {
166*c8dee2aaSAndroid Build Coastguard Worker         fShouldCreateMipMaps = shouldCreateMipMaps;
167*c8dee2aaSAndroid Build Coastguard Worker     }
setVkRTInputAttachmentSupport(bool inputSupport)168*c8dee2aaSAndroid Build Coastguard Worker     void setVkRTInputAttachmentSupport(bool inputSupport) {
169*c8dee2aaSAndroid Build Coastguard Worker         fVkRTSupportsInputAttachment = inputSupport;
170*c8dee2aaSAndroid Build Coastguard Worker     }
setForVulkanSecondaryCommandBuffer(bool forVkSCB)171*c8dee2aaSAndroid Build Coastguard Worker     void setForVulkanSecondaryCommandBuffer(bool forVkSCB) {
172*c8dee2aaSAndroid Build Coastguard Worker         fForVulkanSecondaryCommandBuffer = forVkSCB;
173*c8dee2aaSAndroid Build Coastguard Worker     }
174*c8dee2aaSAndroid Build Coastguard Worker 
175*c8dee2aaSAndroid Build Coastguard Worker     // Modify the SurfaceParameters in just one way. Returns false if the requested modification had
176*c8dee2aaSAndroid Build Coastguard Worker     // no effect.
modify(int i)177*c8dee2aaSAndroid Build Coastguard Worker     bool modify(int i) {
178*c8dee2aaSAndroid Build Coastguard Worker         bool changed = false;
179*c8dee2aaSAndroid Build Coastguard Worker         auto set = [&changed](auto& var, auto value) {
180*c8dee2aaSAndroid Build Coastguard Worker             if (var != value) {
181*c8dee2aaSAndroid Build Coastguard Worker                 changed = true;
182*c8dee2aaSAndroid Build Coastguard Worker             }
183*c8dee2aaSAndroid Build Coastguard Worker             var = value;
184*c8dee2aaSAndroid Build Coastguard Worker         };
185*c8dee2aaSAndroid Build Coastguard Worker         switch (i) {
186*c8dee2aaSAndroid Build Coastguard Worker         case 0:
187*c8dee2aaSAndroid Build Coastguard Worker             set(fWidth, 63);
188*c8dee2aaSAndroid Build Coastguard Worker             break;
189*c8dee2aaSAndroid Build Coastguard Worker         case 1:
190*c8dee2aaSAndroid Build Coastguard Worker             set(fHeight, 63);
191*c8dee2aaSAndroid Build Coastguard Worker             break;
192*c8dee2aaSAndroid Build Coastguard Worker         case 2:
193*c8dee2aaSAndroid Build Coastguard Worker             set(fOrigin, kBottomLeft_GrSurfaceOrigin);
194*c8dee2aaSAndroid Build Coastguard Worker             break;
195*c8dee2aaSAndroid Build Coastguard Worker         case 3:
196*c8dee2aaSAndroid Build Coastguard Worker             set(fColorType, kRGBA_F16_SkColorType);
197*c8dee2aaSAndroid Build Coastguard Worker             break;
198*c8dee2aaSAndroid Build Coastguard Worker         case 4:
199*c8dee2aaSAndroid Build Coastguard Worker             // This just needs to be a colorSpace different from that returned by MakeSRGB().
200*c8dee2aaSAndroid Build Coastguard Worker             // In this case we just change the gamut.
201*c8dee2aaSAndroid Build Coastguard Worker             set(fColorSpace, SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
202*c8dee2aaSAndroid Build Coastguard Worker                                                    SkNamedGamut::kAdobeRGB));
203*c8dee2aaSAndroid Build Coastguard Worker             break;
204*c8dee2aaSAndroid Build Coastguard Worker         case 5:
205*c8dee2aaSAndroid Build Coastguard Worker             set(fSampleCount, 4);
206*c8dee2aaSAndroid Build Coastguard Worker             break;
207*c8dee2aaSAndroid Build Coastguard Worker         case 6:
208*c8dee2aaSAndroid Build Coastguard Worker             set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry));
209*c8dee2aaSAndroid Build Coastguard Worker             break;
210*c8dee2aaSAndroid Build Coastguard Worker         case 7:
211*c8dee2aaSAndroid Build Coastguard Worker             set(fSurfaceProps, SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
212*c8dee2aaSAndroid Build Coastguard Worker                                               kUnknown_SkPixelGeometry));
213*c8dee2aaSAndroid Build Coastguard Worker             break;
214*c8dee2aaSAndroid Build Coastguard Worker         case 8:
215*c8dee2aaSAndroid Build Coastguard Worker             set(fShouldCreateMipMaps, skgpu::Mipmapped::kNo);
216*c8dee2aaSAndroid Build Coastguard Worker             break;
217*c8dee2aaSAndroid Build Coastguard Worker         case 9:
218*c8dee2aaSAndroid Build Coastguard Worker             if (GrBackendApi::kOpenGL == fBackend) {
219*c8dee2aaSAndroid Build Coastguard Worker                 set(fUsesGLFBO0, true);
220*c8dee2aaSAndroid Build Coastguard Worker                 set(fShouldCreateMipMaps,
221*c8dee2aaSAndroid Build Coastguard Worker                     skgpu::Mipmapped::kNo);  // needs to changed in tandem w/ textureability
222*c8dee2aaSAndroid Build Coastguard Worker                 set(fIsTextureable, false);
223*c8dee2aaSAndroid Build Coastguard Worker             }
224*c8dee2aaSAndroid Build Coastguard Worker             break;
225*c8dee2aaSAndroid Build Coastguard Worker         case 10:
226*c8dee2aaSAndroid Build Coastguard Worker             set(fShouldCreateMipMaps,
227*c8dee2aaSAndroid Build Coastguard Worker                 skgpu::Mipmapped::kNo);  // needs to changed in tandem w/ textureability
228*c8dee2aaSAndroid Build Coastguard Worker             set(fIsTextureable, false);
229*c8dee2aaSAndroid Build Coastguard Worker             break;
230*c8dee2aaSAndroid Build Coastguard Worker         case 11:
231*c8dee2aaSAndroid Build Coastguard Worker             if (GrBackendApi::kVulkan == fBackend) {
232*c8dee2aaSAndroid Build Coastguard Worker                 set(fForVulkanSecondaryCommandBuffer, true);
233*c8dee2aaSAndroid Build Coastguard Worker                 set(fUsesGLFBO0, false);
234*c8dee2aaSAndroid Build Coastguard Worker                 set(fShouldCreateMipMaps,
235*c8dee2aaSAndroid Build Coastguard Worker                     skgpu::Mipmapped::kNo);  // needs to changed in tandem w/ textureability
236*c8dee2aaSAndroid Build Coastguard Worker                 set(fIsTextureable, false);
237*c8dee2aaSAndroid Build Coastguard Worker                 set(fVkRTSupportsInputAttachment, false);
238*c8dee2aaSAndroid Build Coastguard Worker             }
239*c8dee2aaSAndroid Build Coastguard Worker             break;
240*c8dee2aaSAndroid Build Coastguard Worker         }
241*c8dee2aaSAndroid Build Coastguard Worker         return changed;
242*c8dee2aaSAndroid Build Coastguard Worker     }
243*c8dee2aaSAndroid Build Coastguard Worker 
createCharacterization(GrDirectContext * dContext) const244*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const {
245*c8dee2aaSAndroid Build Coastguard Worker         size_t maxResourceBytes = dContext->getResourceCacheLimit();
246*c8dee2aaSAndroid Build Coastguard Worker 
247*c8dee2aaSAndroid Build Coastguard Worker         if (!dContext->colorTypeSupportedAsSurface(fColorType)) {
248*c8dee2aaSAndroid Build Coastguard Worker             return GrSurfaceCharacterization();
249*c8dee2aaSAndroid Build Coastguard Worker         }
250*c8dee2aaSAndroid Build Coastguard Worker 
251*c8dee2aaSAndroid Build Coastguard Worker         // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
252*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
253*c8dee2aaSAndroid Build Coastguard Worker                                            kPremul_SkAlphaType, fColorSpace);
254*c8dee2aaSAndroid Build Coastguard Worker 
255*c8dee2aaSAndroid Build Coastguard Worker         GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType,
256*c8dee2aaSAndroid Build Coastguard Worker                                                                        GrRenderable::kYes);
257*c8dee2aaSAndroid Build Coastguard Worker         if (!backendFormat.isValid()) {
258*c8dee2aaSAndroid Build Coastguard Worker             return GrSurfaceCharacterization();
259*c8dee2aaSAndroid Build Coastguard Worker         }
260*c8dee2aaSAndroid Build Coastguard Worker 
261*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization c = dContext->threadSafeProxy()->createCharacterization(
262*c8dee2aaSAndroid Build Coastguard Worker                                                 maxResourceBytes, ii, backendFormat, fSampleCount,
263*c8dee2aaSAndroid Build Coastguard Worker                                                 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
264*c8dee2aaSAndroid Build Coastguard Worker                                                 fUsesGLFBO0, fIsTextureable, fIsProtected,
265*c8dee2aaSAndroid Build Coastguard Worker                                                 fVkRTSupportsInputAttachment,
266*c8dee2aaSAndroid Build Coastguard Worker                                                 fForVulkanSecondaryCommandBuffer);
267*c8dee2aaSAndroid Build Coastguard Worker         return c;
268*c8dee2aaSAndroid Build Coastguard Worker     }
269*c8dee2aaSAndroid Build Coastguard Worker 
270*c8dee2aaSAndroid Build Coastguard Worker     // Create a DDL whose characterization captures the current settings
createDDL(GrDirectContext * dContext) const271*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> createDDL(GrDirectContext* dContext) const {
272*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization c = this->createCharacterization(dContext);
273*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(c.isValid());
274*c8dee2aaSAndroid Build Coastguard Worker 
275*c8dee2aaSAndroid Build Coastguard Worker         GrDeferredDisplayListRecorder r(c);
276*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas* canvas = r.getCanvas();
277*c8dee2aaSAndroid Build Coastguard Worker         if (!canvas) {
278*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
279*c8dee2aaSAndroid Build Coastguard Worker         }
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
282*c8dee2aaSAndroid Build Coastguard Worker         return r.detach();
283*c8dee2aaSAndroid Build Coastguard Worker     }
284*c8dee2aaSAndroid Build Coastguard Worker 
285*c8dee2aaSAndroid Build Coastguard Worker     // Create the surface with the current set of parameters
make(GrDirectContext * dContext) const286*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> make(GrDirectContext* dContext) const {
287*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceCharacterization c = this->createCharacterization(dContext);
288*c8dee2aaSAndroid Build Coastguard Worker 
289*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
290*c8dee2aaSAndroid Build Coastguard Worker         if (fUsesGLFBO0) {
291*c8dee2aaSAndroid Build Coastguard Worker             if (GrBackendApi::kOpenGL != dContext->backend()) {
292*c8dee2aaSAndroid Build Coastguard Worker                 return nullptr;
293*c8dee2aaSAndroid Build Coastguard Worker             }
294*c8dee2aaSAndroid Build Coastguard Worker 
295*c8dee2aaSAndroid Build Coastguard Worker             GrGLFramebufferInfo fboInfo;
296*c8dee2aaSAndroid Build Coastguard Worker             fboInfo.fFBOID = 0;
297*c8dee2aaSAndroid Build Coastguard Worker             fboInfo.fFormat = GR_GL_RGBA8;
298*c8dee2aaSAndroid Build Coastguard Worker             fboInfo.fProtected = fIsProtected;
299*c8dee2aaSAndroid Build Coastguard Worker             static constexpr int kStencilBits = 8;
300*c8dee2aaSAndroid Build Coastguard Worker             GrBackendRenderTarget backendRT =
301*c8dee2aaSAndroid Build Coastguard Worker                     GrBackendRenderTargets::MakeGL(fWidth, fHeight, 1, kStencilBits, fboInfo);
302*c8dee2aaSAndroid Build Coastguard Worker 
303*c8dee2aaSAndroid Build Coastguard Worker             if (!backendRT.isValid()) {
304*c8dee2aaSAndroid Build Coastguard Worker                 return nullptr;
305*c8dee2aaSAndroid Build Coastguard Worker             }
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkSurface> result = SkSurfaces::WrapBackendRenderTarget(
308*c8dee2aaSAndroid Build Coastguard Worker                     dContext, backendRT, fOrigin, fColorType, fColorSpace, &fSurfaceProps);
309*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(result->isCompatible(c));
310*c8dee2aaSAndroid Build Coastguard Worker             return result;
311*c8dee2aaSAndroid Build Coastguard Worker         }
312*c8dee2aaSAndroid Build Coastguard Worker #endif
313*c8dee2aaSAndroid Build Coastguard Worker 
314*c8dee2aaSAndroid Build Coastguard Worker         // We can't make SkSurfaces for vulkan secondary command buffers.
315*c8dee2aaSAndroid Build Coastguard Worker         if (fForVulkanSecondaryCommandBuffer) {
316*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
317*c8dee2aaSAndroid Build Coastguard Worker         }
318*c8dee2aaSAndroid Build Coastguard Worker 
319*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> surface;
320*c8dee2aaSAndroid Build Coastguard Worker         if (fIsTextureable) {
321*c8dee2aaSAndroid Build Coastguard Worker             surface = sk_gpu_test::MakeBackendTextureSurface(dContext,
322*c8dee2aaSAndroid Build Coastguard Worker                                                              {fWidth, fHeight},
323*c8dee2aaSAndroid Build Coastguard Worker                                                              fOrigin,
324*c8dee2aaSAndroid Build Coastguard Worker                                                              fSampleCount,
325*c8dee2aaSAndroid Build Coastguard Worker                                                              fColorType,
326*c8dee2aaSAndroid Build Coastguard Worker                                                              fColorSpace,
327*c8dee2aaSAndroid Build Coastguard Worker                                                              fShouldCreateMipMaps,
328*c8dee2aaSAndroid Build Coastguard Worker                                                              fIsProtected,
329*c8dee2aaSAndroid Build Coastguard Worker                                                              &fSurfaceProps);
330*c8dee2aaSAndroid Build Coastguard Worker         } else {
331*c8dee2aaSAndroid Build Coastguard Worker             // Create a surface w/ the current parameters but make it non-textureable
332*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fShouldCreateMipMaps == skgpu::Mipmapped::kNo);
333*c8dee2aaSAndroid Build Coastguard Worker             surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext,
334*c8dee2aaSAndroid Build Coastguard Worker                                                                   {fWidth, fHeight},
335*c8dee2aaSAndroid Build Coastguard Worker                                                                   fOrigin,
336*c8dee2aaSAndroid Build Coastguard Worker                                                                   fSampleCount,
337*c8dee2aaSAndroid Build Coastguard Worker                                                                   fColorType,
338*c8dee2aaSAndroid Build Coastguard Worker                                                                   fColorSpace,
339*c8dee2aaSAndroid Build Coastguard Worker                                                                   fIsProtected,
340*c8dee2aaSAndroid Build Coastguard Worker                                                                   &fSurfaceProps);
341*c8dee2aaSAndroid Build Coastguard Worker         }
342*c8dee2aaSAndroid Build Coastguard Worker 
343*c8dee2aaSAndroid Build Coastguard Worker         if (!surface) {
344*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!c.isValid());
345*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
346*c8dee2aaSAndroid Build Coastguard Worker         }
347*c8dee2aaSAndroid Build Coastguard Worker 
348*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTexture texture = SkSurfaces::GetBackendTexture(
349*c8dee2aaSAndroid Build Coastguard Worker                 surface.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
350*c8dee2aaSAndroid Build Coastguard Worker         if (texture.isValid()) {
351*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(is_compatible(c, texture));
352*c8dee2aaSAndroid Build Coastguard Worker         }
353*c8dee2aaSAndroid Build Coastguard Worker 
354*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(c.isValid());
355*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(surface->isCompatible(c));
356*c8dee2aaSAndroid Build Coastguard Worker         return surface;
357*c8dee2aaSAndroid Build Coastguard Worker     }
358*c8dee2aaSAndroid Build Coastguard Worker 
359*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
makeVkSCB(GrDirectContext * dContext)360*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrVkSecondaryCBDrawContext> makeVkSCB(GrDirectContext* dContext) {
361*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceCharacterization c = this->createCharacterization(dContext);
362*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo imageInfo = SkImageInfo::Make({fWidth, fHeight},
363*c8dee2aaSAndroid Build Coastguard Worker                                                   {fColorType, kPremul_SkAlphaType, fColorSpace});
364*c8dee2aaSAndroid Build Coastguard Worker         GrVkDrawableInfo vkInfo;
365*c8dee2aaSAndroid Build Coastguard Worker         // putting in a bunch of placeholder values here
366*c8dee2aaSAndroid Build Coastguard Worker         vkInfo.fSecondaryCommandBuffer = (VkCommandBuffer)1;
367*c8dee2aaSAndroid Build Coastguard Worker         vkInfo.fColorAttachmentIndex = 0;
368*c8dee2aaSAndroid Build Coastguard Worker         vkInfo.fCompatibleRenderPass = (VkRenderPass)1;
369*c8dee2aaSAndroid Build Coastguard Worker         vkInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
370*c8dee2aaSAndroid Build Coastguard Worker         vkInfo.fDrawBounds = nullptr;
371*c8dee2aaSAndroid Build Coastguard Worker 
372*c8dee2aaSAndroid Build Coastguard Worker         return GrVkSecondaryCBDrawContext::Make(dContext, imageInfo, vkInfo, &fSurfaceProps);
373*c8dee2aaSAndroid Build Coastguard Worker     }
374*c8dee2aaSAndroid Build Coastguard Worker #endif
375*c8dee2aaSAndroid Build Coastguard Worker 
376*c8dee2aaSAndroid Build Coastguard Worker private:
377*c8dee2aaSAndroid Build Coastguard Worker     GrBackendApi        fBackend;
378*c8dee2aaSAndroid Build Coastguard Worker     bool                fCanBeProtected;
379*c8dee2aaSAndroid Build Coastguard Worker 
380*c8dee2aaSAndroid Build Coastguard Worker     int                 fWidth;
381*c8dee2aaSAndroid Build Coastguard Worker     int                 fHeight;
382*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceOrigin     fOrigin;
383*c8dee2aaSAndroid Build Coastguard Worker     SkColorType         fColorType;
384*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorSpace> fColorSpace;
385*c8dee2aaSAndroid Build Coastguard Worker     int                 fSampleCount;
386*c8dee2aaSAndroid Build Coastguard Worker     SkSurfaceProps      fSurfaceProps;
387*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Mipmapped fShouldCreateMipMaps;
388*c8dee2aaSAndroid Build Coastguard Worker     bool                fUsesGLFBO0;
389*c8dee2aaSAndroid Build Coastguard Worker     bool                fIsTextureable;
390*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Protected fIsProtected;
391*c8dee2aaSAndroid Build Coastguard Worker     bool                fVkRTSupportsInputAttachment;
392*c8dee2aaSAndroid Build Coastguard Worker     bool                fForVulkanSecondaryCommandBuffer;
393*c8dee2aaSAndroid Build Coastguard Worker };
394*c8dee2aaSAndroid Build Coastguard Worker 
395*c8dee2aaSAndroid Build Coastguard Worker // Test out operator== && operator!=
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest,reporter,ctxInfo,CtsEnforcement::kNever)396*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest,
397*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
398*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
399*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
400*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
401*c8dee2aaSAndroid Build Coastguard Worker 
402*c8dee2aaSAndroid Build Coastguard Worker     for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
403*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params1(context);
404*c8dee2aaSAndroid Build Coastguard Worker         bool didModify1 = i >= 0 && params1.modify(i);
405*c8dee2aaSAndroid Build Coastguard Worker 
406*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char1 = params1.createCharacterization(context);
407*c8dee2aaSAndroid Build Coastguard Worker         if (!char1.isValid()) {
408*c8dee2aaSAndroid Build Coastguard Worker             continue;  // can happen on some platforms (ChromeOS)
409*c8dee2aaSAndroid Build Coastguard Worker         }
410*c8dee2aaSAndroid Build Coastguard Worker 
411*c8dee2aaSAndroid Build Coastguard Worker         for (int j = -1; j < SurfaceParameters::kNumParams; ++j) {
412*c8dee2aaSAndroid Build Coastguard Worker             SurfaceParameters params2(context);
413*c8dee2aaSAndroid Build Coastguard Worker             bool didModify2 = j >= 0 && params2.modify(j);
414*c8dee2aaSAndroid Build Coastguard Worker 
415*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization char2 = params2.createCharacterization(context);
416*c8dee2aaSAndroid Build Coastguard Worker             if (!char2.isValid()) {
417*c8dee2aaSAndroid Build Coastguard Worker                 continue;  // can happen on some platforms (ChromeOS)
418*c8dee2aaSAndroid Build Coastguard Worker             }
419*c8dee2aaSAndroid Build Coastguard Worker 
420*c8dee2aaSAndroid Build Coastguard Worker             if (i == j || (!didModify1 && !didModify2)) {
421*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, char1 == char2);
422*c8dee2aaSAndroid Build Coastguard Worker             } else {
423*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, char1 != char2);
424*c8dee2aaSAndroid Build Coastguard Worker             }
425*c8dee2aaSAndroid Build Coastguard Worker         }
426*c8dee2aaSAndroid Build Coastguard Worker     }
427*c8dee2aaSAndroid Build Coastguard Worker 
428*c8dee2aaSAndroid Build Coastguard Worker     {
429*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(context);
430*c8dee2aaSAndroid Build Coastguard Worker 
431*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization valid = params.createCharacterization(context);
432*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(valid.isValid());
433*c8dee2aaSAndroid Build Coastguard Worker 
434*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization inval1, inval2;
435*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!inval1.isValid() && !inval2.isValid());
436*c8dee2aaSAndroid Build Coastguard Worker 
437*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, inval1 != inval2);
438*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, valid != inval1);
439*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, inval1 != valid);
440*c8dee2aaSAndroid Build Coastguard Worker     }
441*c8dee2aaSAndroid Build Coastguard Worker }
442*c8dee2aaSAndroid Build Coastguard Worker 
443*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
444*c8dee2aaSAndroid Build Coastguard Worker // This tests GrSurfaceCharacterization/SkSurface compatibility
DDLSurfaceCharacterizationTestImpl(GrDirectContext * dContext,skiatest::Reporter * reporter)445*c8dee2aaSAndroid Build Coastguard Worker void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
446*c8dee2aaSAndroid Build Coastguard Worker     // Create a bitmap that we can readback into
447*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
448*c8dee2aaSAndroid Build Coastguard Worker                                               kPremul_SkAlphaType);
449*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
450*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(imageInfo);
451*c8dee2aaSAndroid Build Coastguard Worker 
452*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl;
453*c8dee2aaSAndroid Build Coastguard Worker 
454*c8dee2aaSAndroid Build Coastguard Worker     // First, create a DDL using the stock SkSurface parameters
455*c8dee2aaSAndroid Build Coastguard Worker     {
456*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
457*c8dee2aaSAndroid Build Coastguard Worker         if (dContext->backend() == GrBackendApi::kVulkan) {
458*c8dee2aaSAndroid Build Coastguard Worker             params.setVkRTInputAttachmentSupport(true);
459*c8dee2aaSAndroid Build Coastguard Worker         }
460*c8dee2aaSAndroid Build Coastguard Worker         ddl = params.createDDL(dContext);
461*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(ddl);
462*c8dee2aaSAndroid Build Coastguard Worker 
463*c8dee2aaSAndroid Build Coastguard Worker         // The DDL should draw into an SkSurface created with the same parameters
464*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
465*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
466*c8dee2aaSAndroid Build Coastguard Worker             return;
467*c8dee2aaSAndroid Build Coastguard Worker         }
468*c8dee2aaSAndroid Build Coastguard Worker 
469*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
470*c8dee2aaSAndroid Build Coastguard Worker         s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
471*c8dee2aaSAndroid Build Coastguard Worker 
472*c8dee2aaSAndroid Build Coastguard Worker         dContext->flush();
473*c8dee2aaSAndroid Build Coastguard Worker     }
474*c8dee2aaSAndroid Build Coastguard Worker 
475*c8dee2aaSAndroid Build Coastguard Worker     // Then, alter each parameter in turn and check that the DDL & surface are incompatible
476*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
477*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
478*c8dee2aaSAndroid Build Coastguard Worker         if (!params.modify(i)) {
479*c8dee2aaSAndroid Build Coastguard Worker             continue;
480*c8dee2aaSAndroid Build Coastguard Worker         }
481*c8dee2aaSAndroid Build Coastguard Worker 
482*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
483*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
484*c8dee2aaSAndroid Build Coastguard Worker             continue;
485*c8dee2aaSAndroid Build Coastguard Worker         }
486*c8dee2aaSAndroid Build Coastguard Worker 
487*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !skgpu::ganesh::DrawDDL(s, ddl),
488*c8dee2aaSAndroid Build Coastguard Worker                         "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
489*c8dee2aaSAndroid Build Coastguard Worker         dContext->flush();
490*c8dee2aaSAndroid Build Coastguard Worker     }
491*c8dee2aaSAndroid Build Coastguard Worker 
492*c8dee2aaSAndroid Build Coastguard Worker     // Next test the compatibility of resource cache parameters
493*c8dee2aaSAndroid Build Coastguard Worker     {
494*c8dee2aaSAndroid Build Coastguard Worker         const SurfaceParameters params(dContext);
495*c8dee2aaSAndroid Build Coastguard Worker 
496*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
497*c8dee2aaSAndroid Build Coastguard Worker 
498*c8dee2aaSAndroid Build Coastguard Worker         size_t maxResourceBytes = dContext->getResourceCacheLimit();
499*c8dee2aaSAndroid Build Coastguard Worker 
500*c8dee2aaSAndroid Build Coastguard Worker         dContext->setResourceCacheLimit(maxResourceBytes/2);
501*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !skgpu::ganesh::DrawDDL(s, ddl));
502*c8dee2aaSAndroid Build Coastguard Worker 
503*c8dee2aaSAndroid Build Coastguard Worker         // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
504*c8dee2aaSAndroid Build Coastguard Worker         // For now, DDLs are drawn once.
505*c8dee2aaSAndroid Build Coastguard Worker #if 0
506*c8dee2aaSAndroid Build Coastguard Worker         // resource limits >= those at characterization time are accepted
507*c8dee2aaSAndroid Build Coastguard Worker         context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
508*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
509*c8dee2aaSAndroid Build Coastguard Worker         s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
510*c8dee2aaSAndroid Build Coastguard Worker 
511*c8dee2aaSAndroid Build Coastguard Worker         context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
512*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
513*c8dee2aaSAndroid Build Coastguard Worker         s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
514*c8dee2aaSAndroid Build Coastguard Worker 
515*c8dee2aaSAndroid Build Coastguard Worker         context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
516*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
517*c8dee2aaSAndroid Build Coastguard Worker         s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
518*c8dee2aaSAndroid Build Coastguard Worker #endif
519*c8dee2aaSAndroid Build Coastguard Worker 
520*c8dee2aaSAndroid Build Coastguard Worker         dContext->flush();
521*c8dee2aaSAndroid Build Coastguard Worker     }
522*c8dee2aaSAndroid Build Coastguard Worker 
523*c8dee2aaSAndroid Build Coastguard Worker     // Test that the textureability of the DDL characterization can block a DDL draw
524*c8dee2aaSAndroid Build Coastguard Worker     {
525*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
526*c8dee2aaSAndroid Build Coastguard Worker         params.disableTextureability();
527*c8dee2aaSAndroid Build Coastguard Worker 
528*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
529*c8dee2aaSAndroid Build Coastguard Worker         if (s) {
530*c8dee2aaSAndroid Build Coastguard Worker             // bc the DDL was made w/ textureability
531*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !skgpu::ganesh::DrawDDL(s, ddl));
532*c8dee2aaSAndroid Build Coastguard Worker 
533*c8dee2aaSAndroid Build Coastguard Worker             dContext->flush();
534*c8dee2aaSAndroid Build Coastguard Worker         }
535*c8dee2aaSAndroid Build Coastguard Worker     }
536*c8dee2aaSAndroid Build Coastguard Worker 
537*c8dee2aaSAndroid Build Coastguard Worker     // Make sure non-GPU-backed surfaces fail characterization
538*c8dee2aaSAndroid Build Coastguard Worker     {
539*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
540*c8dee2aaSAndroid Build Coastguard Worker 
541*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> rasterSurface = SkSurfaces::Raster(ii);
542*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization c;
543*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
544*c8dee2aaSAndroid Build Coastguard Worker     }
545*c8dee2aaSAndroid Build Coastguard Worker 
546*c8dee2aaSAndroid Build Coastguard Worker     // Exercise the createResized method
547*c8dee2aaSAndroid Build Coastguard Worker     {
548*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
549*c8dee2aaSAndroid Build Coastguard Worker 
550*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
551*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
552*c8dee2aaSAndroid Build Coastguard Worker             return;
553*c8dee2aaSAndroid Build Coastguard Worker         }
554*c8dee2aaSAndroid Build Coastguard Worker 
555*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char0;
556*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(s->characterize(&char0));
557*c8dee2aaSAndroid Build Coastguard Worker 
558*c8dee2aaSAndroid Build Coastguard Worker         // Too small
559*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char1 = char0.createResized(-1, -1);
560*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !char1.isValid());
561*c8dee2aaSAndroid Build Coastguard Worker 
562*c8dee2aaSAndroid Build Coastguard Worker         // Too large
563*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char2 = char0.createResized(1000000, 32);
564*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !char2.isValid());
565*c8dee2aaSAndroid Build Coastguard Worker 
566*c8dee2aaSAndroid Build Coastguard Worker         // Just right
567*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char3 = char0.createResized(32, 32);
568*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, char3.isValid());
569*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, 32 == char3.width());
570*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, 32 == char3.height());
571*c8dee2aaSAndroid Build Coastguard Worker     }
572*c8dee2aaSAndroid Build Coastguard Worker 
573*c8dee2aaSAndroid Build Coastguard Worker     // Exercise the createColorSpace method
574*c8dee2aaSAndroid Build Coastguard Worker     {
575*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
576*c8dee2aaSAndroid Build Coastguard Worker 
577*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
578*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
579*c8dee2aaSAndroid Build Coastguard Worker             return;
580*c8dee2aaSAndroid Build Coastguard Worker         }
581*c8dee2aaSAndroid Build Coastguard Worker 
582*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char0;
583*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(s->characterize(&char0));
584*c8dee2aaSAndroid Build Coastguard Worker 
585*c8dee2aaSAndroid Build Coastguard Worker         // The default params create an sRGB color space
586*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, char0.colorSpace()->isSRGB());
587*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !char0.colorSpace()->gammaIsLinear());
588*c8dee2aaSAndroid Build Coastguard Worker 
589*c8dee2aaSAndroid Build Coastguard Worker         {
590*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
591*c8dee2aaSAndroid Build Coastguard Worker 
592*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS));
593*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.isValid());
594*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !char1.colorSpace()->isSRGB());
595*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.colorSpace()->gammaIsLinear());
596*c8dee2aaSAndroid Build Coastguard Worker         }
597*c8dee2aaSAndroid Build Coastguard Worker 
598*c8dee2aaSAndroid Build Coastguard Worker         {
599*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization char2 = char0.createColorSpace(nullptr);
600*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char2.isValid());
601*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !char2.colorSpace());
602*c8dee2aaSAndroid Build Coastguard Worker         }
603*c8dee2aaSAndroid Build Coastguard Worker 
604*c8dee2aaSAndroid Build Coastguard Worker         {
605*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
606*c8dee2aaSAndroid Build Coastguard Worker 
607*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization invalid;
608*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !invalid.isValid());
609*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS));
610*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !stillInvalid.isValid());
611*c8dee2aaSAndroid Build Coastguard Worker         }
612*c8dee2aaSAndroid Build Coastguard Worker     }
613*c8dee2aaSAndroid Build Coastguard Worker 
614*c8dee2aaSAndroid Build Coastguard Worker     // Exercise the createBackendFormat method
615*c8dee2aaSAndroid Build Coastguard Worker     {
616*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
617*c8dee2aaSAndroid Build Coastguard Worker 
618*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
619*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
620*c8dee2aaSAndroid Build Coastguard Worker             return;
621*c8dee2aaSAndroid Build Coastguard Worker         }
622*c8dee2aaSAndroid Build Coastguard Worker 
623*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char0;
624*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(s->characterize(&char0));
625*c8dee2aaSAndroid Build Coastguard Worker 
626*c8dee2aaSAndroid Build Coastguard Worker         // The default params create a renderable RGBA8 surface
627*c8dee2aaSAndroid Build Coastguard Worker         auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
628*c8dee2aaSAndroid Build Coastguard Worker                                                                     GrRenderable::kYes);
629*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, originalBackendFormat.isValid());
630*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat);
631*c8dee2aaSAndroid Build Coastguard Worker 
632*c8dee2aaSAndroid Build Coastguard Worker         auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType,
633*c8dee2aaSAndroid Build Coastguard Worker                                                                GrRenderable::kYes);
634*c8dee2aaSAndroid Build Coastguard Worker 
635*c8dee2aaSAndroid Build Coastguard Worker         if (newBackendFormat.isValid()) {
636*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization char1 = char0.createBackendFormat(kRGB_565_SkColorType,
637*c8dee2aaSAndroid Build Coastguard Worker                                                                         newBackendFormat);
638*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.isValid());
639*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat);
640*c8dee2aaSAndroid Build Coastguard Worker 
641*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization invalid;
642*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !invalid.isValid());
643*c8dee2aaSAndroid Build Coastguard Worker             auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType,
644*c8dee2aaSAndroid Build Coastguard Worker                                                             newBackendFormat);
645*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !stillInvalid.isValid());
646*c8dee2aaSAndroid Build Coastguard Worker         }
647*c8dee2aaSAndroid Build Coastguard Worker     }
648*c8dee2aaSAndroid Build Coastguard Worker 
649*c8dee2aaSAndroid Build Coastguard Worker     // Exercise the createFBO0 method
650*c8dee2aaSAndroid Build Coastguard Worker     if (dContext->backend() == GrBackendApi::kOpenGL) {
651*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
652*c8dee2aaSAndroid Build Coastguard Worker         // If the original characterization is textureable then we will fail trying to make an
653*c8dee2aaSAndroid Build Coastguard Worker         // FBO0 characterization
654*c8dee2aaSAndroid Build Coastguard Worker         params.disableTextureability();
655*c8dee2aaSAndroid Build Coastguard Worker 
656*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
657*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
658*c8dee2aaSAndroid Build Coastguard Worker             return;
659*c8dee2aaSAndroid Build Coastguard Worker         }
660*c8dee2aaSAndroid Build Coastguard Worker 
661*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization char0;
662*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(s->characterize(&char0));
663*c8dee2aaSAndroid Build Coastguard Worker 
664*c8dee2aaSAndroid Build Coastguard Worker         // The default params create a non-FBO0 surface
665*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !char0.usesGLFBO0());
666*c8dee2aaSAndroid Build Coastguard Worker 
667*c8dee2aaSAndroid Build Coastguard Worker         {
668*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization char1 = char0.createFBO0(true);
669*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.isValid());
670*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, char1.usesGLFBO0());
671*c8dee2aaSAndroid Build Coastguard Worker         }
672*c8dee2aaSAndroid Build Coastguard Worker 
673*c8dee2aaSAndroid Build Coastguard Worker         {
674*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization invalid;
675*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !invalid.isValid());
676*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceCharacterization stillInvalid = invalid.createFBO0(true);
677*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !stillInvalid.isValid());
678*c8dee2aaSAndroid Build Coastguard Worker         }
679*c8dee2aaSAndroid Build Coastguard Worker     }
680*c8dee2aaSAndroid Build Coastguard Worker }
681*c8dee2aaSAndroid Build Coastguard Worker 
682*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
683*c8dee2aaSAndroid Build Coastguard Worker 
684*c8dee2aaSAndroid Build Coastguard Worker // Test out the surface compatibility checks regarding FBO0-ness. This test constructs
685*c8dee2aaSAndroid Build Coastguard Worker // two parallel arrays of characterizations and surfaces in the order:
686*c8dee2aaSAndroid Build Coastguard Worker //    FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA
687*c8dee2aaSAndroid Build Coastguard Worker // and then tries all sixteen combinations to check the expected compatibility.
688*c8dee2aaSAndroid Build Coastguard Worker // Note: this is a GL-only test
DEF_GANESH_TEST_FOR_GL_CONTEXT(CharacterizationFBO0nessTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)689*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_GL_CONTEXT(CharacterizationFBO0nessTest,
690*c8dee2aaSAndroid Build Coastguard Worker                                reporter,
691*c8dee2aaSAndroid Build Coastguard Worker                                ctxInfo,
692*c8dee2aaSAndroid Build Coastguard Worker                                CtsEnforcement::kApiLevel_T) {
693*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
694*c8dee2aaSAndroid Build Coastguard Worker     const GrCaps* caps = context->priv().caps();
695*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
696*c8dee2aaSAndroid Build Coastguard Worker     const size_t resourceCacheLimit = context->getResourceCacheLimit();
697*c8dee2aaSAndroid Build Coastguard Worker 
698*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
699*c8dee2aaSAndroid Build Coastguard Worker 
700*c8dee2aaSAndroid Build Coastguard Worker     int availableSamples = caps->getRenderTargetSampleCount(4, format);
701*c8dee2aaSAndroid Build Coastguard Worker     if (availableSamples <= 1) {
702*c8dee2aaSAndroid Build Coastguard Worker         // This context doesn't support MSAA for RGBA8
703*c8dee2aaSAndroid Build Coastguard Worker         return;
704*c8dee2aaSAndroid Build Coastguard Worker     }
705*c8dee2aaSAndroid Build Coastguard Worker 
706*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::Make({ 128, 128 }, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
707*c8dee2aaSAndroid Build Coastguard Worker 
708*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kStencilBits = 8;
709*c8dee2aaSAndroid Build Coastguard Worker     static constexpr bool kNotTextureable = false;
710*c8dee2aaSAndroid Build Coastguard Worker     const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
711*c8dee2aaSAndroid Build Coastguard Worker 
712*c8dee2aaSAndroid Build Coastguard Worker     // Rows are characterizations and columns are surfaces
713*c8dee2aaSAndroid Build Coastguard Worker     static const bool kExpectedCompatibility[4][4] = {
714*c8dee2aaSAndroid Build Coastguard Worker                     //  FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA
715*c8dee2aaSAndroid Build Coastguard Worker /* FBO0 & MSAA     */ { true,        false,           false,           false },
716*c8dee2aaSAndroid Build Coastguard Worker /* FBO0 & not-MSAA */ { false,       true,            false,           true  },
717*c8dee2aaSAndroid Build Coastguard Worker /* not-FBO0 & MSAA */ { false,       false,           true,            false },
718*c8dee2aaSAndroid Build Coastguard Worker /* not-FBO0 & not- */ { false,       false,           false,           true  }
719*c8dee2aaSAndroid Build Coastguard Worker     };
720*c8dee2aaSAndroid Build Coastguard Worker 
721*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization characterizations[4];
722*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> surfaces[4];
723*c8dee2aaSAndroid Build Coastguard Worker 
724*c8dee2aaSAndroid Build Coastguard Worker     int index = 0;
725*c8dee2aaSAndroid Build Coastguard Worker     for (bool isFBO0 : { true, false }) {
726*c8dee2aaSAndroid Build Coastguard Worker         for (int numSamples : { availableSamples, 1 }) {
727*c8dee2aaSAndroid Build Coastguard Worker             characterizations[index] = proxy->createCharacterization(resourceCacheLimit,
728*c8dee2aaSAndroid Build Coastguard Worker                                                                      ii,
729*c8dee2aaSAndroid Build Coastguard Worker                                                                      format,
730*c8dee2aaSAndroid Build Coastguard Worker                                                                      numSamples,
731*c8dee2aaSAndroid Build Coastguard Worker                                                                      kTopLeft_GrSurfaceOrigin,
732*c8dee2aaSAndroid Build Coastguard Worker                                                                      surfaceProps,
733*c8dee2aaSAndroid Build Coastguard Worker                                                                      skgpu::Mipmapped::kNo,
734*c8dee2aaSAndroid Build Coastguard Worker                                                                      isFBO0,
735*c8dee2aaSAndroid Build Coastguard Worker                                                                      kNotTextureable);
736*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(characterizations[index].sampleCount() == numSamples);
737*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(characterizations[index].usesGLFBO0() == isFBO0);
738*c8dee2aaSAndroid Build Coastguard Worker 
739*c8dee2aaSAndroid Build Coastguard Worker             GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 };
740*c8dee2aaSAndroid Build Coastguard Worker             GrBackendRenderTarget backendRT =
741*c8dee2aaSAndroid Build Coastguard Worker                     GrBackendRenderTargets::MakeGL(128, 128, numSamples, kStencilBits, fboInfo);
742*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(backendRT.isValid());
743*c8dee2aaSAndroid Build Coastguard Worker 
744*c8dee2aaSAndroid Build Coastguard Worker             surfaces[index] = SkSurfaces::WrapBackendRenderTarget(context,
745*c8dee2aaSAndroid Build Coastguard Worker                                                                   backendRT,
746*c8dee2aaSAndroid Build Coastguard Worker                                                                   kTopLeft_GrSurfaceOrigin,
747*c8dee2aaSAndroid Build Coastguard Worker                                                                   kRGBA_8888_SkColorType,
748*c8dee2aaSAndroid Build Coastguard Worker                                                                   nullptr,
749*c8dee2aaSAndroid Build Coastguard Worker                                                                   &surfaceProps);
750*c8dee2aaSAndroid Build Coastguard Worker             ++index;
751*c8dee2aaSAndroid Build Coastguard Worker         }
752*c8dee2aaSAndroid Build Coastguard Worker     }
753*c8dee2aaSAndroid Build Coastguard Worker 
754*c8dee2aaSAndroid Build Coastguard Worker     for (int c = 0; c < 4; ++c) {
755*c8dee2aaSAndroid Build Coastguard Worker         for (int s = 0; s < 4; ++s) {
756*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter,
757*c8dee2aaSAndroid Build Coastguard Worker                             kExpectedCompatibility[c][s] ==
758*c8dee2aaSAndroid Build Coastguard Worker                                                  surfaces[s]->isCompatible(characterizations[c]));
759*c8dee2aaSAndroid Build Coastguard Worker         }
760*c8dee2aaSAndroid Build Coastguard Worker     }
761*c8dee2aaSAndroid Build Coastguard Worker }
762*c8dee2aaSAndroid Build Coastguard Worker #endif
763*c8dee2aaSAndroid Build Coastguard Worker 
764*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)765*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest,
766*c8dee2aaSAndroid Build Coastguard Worker                                    reporter,
767*c8dee2aaSAndroid Build Coastguard Worker                                    ctxInfo,
768*c8dee2aaSAndroid Build Coastguard Worker                                    CtsEnforcement::kApiLevel_T) {
769*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
770*c8dee2aaSAndroid Build Coastguard Worker 
771*c8dee2aaSAndroid Build Coastguard Worker     SurfaceParameters params(dContext);
772*c8dee2aaSAndroid Build Coastguard Worker     params.modify(SurfaceParameters::kVkSCBCount);
773*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization characterization = params.createCharacterization(dContext);
774*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, characterization.isValid());
775*c8dee2aaSAndroid Build Coastguard Worker 
776*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl = params.createDDL(dContext);
777*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, ddl.get());
778*c8dee2aaSAndroid Build Coastguard Worker 
779*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrVkSecondaryCBDrawContext> scbDrawContext = params.makeVkSCB(dContext);
780*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, scbDrawContext->isCompatible(characterization));
781*c8dee2aaSAndroid Build Coastguard Worker 
782*c8dee2aaSAndroid Build Coastguard Worker     scbDrawContext->releaseResources();
783*c8dee2aaSAndroid Build Coastguard Worker }
784*c8dee2aaSAndroid Build Coastguard Worker #endif
785*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest,reporter,ctxInfo,CtsEnforcement::kNever)786*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest,
787*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
788*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
789*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
790*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
791*c8dee2aaSAndroid Build Coastguard Worker 
792*c8dee2aaSAndroid Build Coastguard Worker     DDLSurfaceCharacterizationTestImpl(context, reporter);
793*c8dee2aaSAndroid Build Coastguard Worker }
794*c8dee2aaSAndroid Build Coastguard Worker 
795*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_VULKAN)
DEF_GANESH_TEST(VkProtectedContext_DDLSurfaceCharacterizationTest,reporter,ctxInfo,CtsEnforcement::kNever)796*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VkProtectedContext_DDLSurfaceCharacterizationTest,
797*c8dee2aaSAndroid Build Coastguard Worker                 reporter,
798*c8dee2aaSAndroid Build Coastguard Worker                 ctxInfo,
799*c8dee2aaSAndroid Build Coastguard Worker                 CtsEnforcement::kNever) {
800*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
801*c8dee2aaSAndroid Build Coastguard Worker                                                               /* isProtected= */ true);
802*c8dee2aaSAndroid Build Coastguard Worker     if (!helper) {
803*c8dee2aaSAndroid Build Coastguard Worker         return;
804*c8dee2aaSAndroid Build Coastguard Worker     }
805*c8dee2aaSAndroid Build Coastguard Worker 
806*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper->isValid());
807*c8dee2aaSAndroid Build Coastguard Worker 
808*c8dee2aaSAndroid Build Coastguard Worker     DDLSurfaceCharacterizationTestImpl(helper->directContext(), reporter);
809*c8dee2aaSAndroid Build Coastguard Worker }
810*c8dee2aaSAndroid Build Coastguard Worker #endif
811*c8dee2aaSAndroid Build Coastguard Worker 
812*c8dee2aaSAndroid Build Coastguard Worker // Test that a DDL created w/o textureability can be replayed into both a textureable and
813*c8dee2aaSAndroid Build Coastguard Worker // non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
814*c8dee2aaSAndroid Build Coastguard Worker // textureable DDL cannot be played into a non-textureable destination but can be replayed
815*c8dee2aaSAndroid Build Coastguard Worker // into a textureable destination.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest,reporter,ctxInfo,CtsEnforcement::kNever)816*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest,
817*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
818*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
819*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
820*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
821*c8dee2aaSAndroid Build Coastguard Worker 
822*c8dee2aaSAndroid Build Coastguard Worker     // Create a bitmap that we can readback into
823*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
824*c8dee2aaSAndroid Build Coastguard Worker                                               kPremul_SkAlphaType);
825*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
826*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(imageInfo);
827*c8dee2aaSAndroid Build Coastguard Worker 
828*c8dee2aaSAndroid Build Coastguard Worker     for (bool textureability : { true, false }) {
829*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<GrDeferredDisplayList> ddl;
830*c8dee2aaSAndroid Build Coastguard Worker 
831*c8dee2aaSAndroid Build Coastguard Worker         // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have
832*c8dee2aaSAndroid Build Coastguard Worker         // reusable DDLs, move this outside of the loop.
833*c8dee2aaSAndroid Build Coastguard Worker         {
834*c8dee2aaSAndroid Build Coastguard Worker             SurfaceParameters params(context);
835*c8dee2aaSAndroid Build Coastguard Worker             params.disableTextureability();
836*c8dee2aaSAndroid Build Coastguard Worker             if (context->backend() == GrBackendApi::kVulkan) {
837*c8dee2aaSAndroid Build Coastguard Worker                 params.setVkRTInputAttachmentSupport(true);
838*c8dee2aaSAndroid Build Coastguard Worker             }
839*c8dee2aaSAndroid Build Coastguard Worker 
840*c8dee2aaSAndroid Build Coastguard Worker             ddl = params.createDDL(context);
841*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(ddl);
842*c8dee2aaSAndroid Build Coastguard Worker         }
843*c8dee2aaSAndroid Build Coastguard Worker 
844*c8dee2aaSAndroid Build Coastguard Worker         // Then verify it can draw into either flavor of destination
845*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(context);
846*c8dee2aaSAndroid Build Coastguard Worker         if (!textureability) {
847*c8dee2aaSAndroid Build Coastguard Worker             params.disableTextureability();
848*c8dee2aaSAndroid Build Coastguard Worker         }
849*c8dee2aaSAndroid Build Coastguard Worker         if (context->backend() == GrBackendApi::kVulkan) {
850*c8dee2aaSAndroid Build Coastguard Worker             params.setVkRTInputAttachmentSupport(true);
851*c8dee2aaSAndroid Build Coastguard Worker         }
852*c8dee2aaSAndroid Build Coastguard Worker 
853*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(context);
854*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
855*c8dee2aaSAndroid Build Coastguard Worker             continue;
856*c8dee2aaSAndroid Build Coastguard Worker         }
857*c8dee2aaSAndroid Build Coastguard Worker 
858*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
859*c8dee2aaSAndroid Build Coastguard Worker         s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
860*c8dee2aaSAndroid Build Coastguard Worker 
861*c8dee2aaSAndroid Build Coastguard Worker         context->flush();
862*c8dee2aaSAndroid Build Coastguard Worker     }
863*c8dee2aaSAndroid Build Coastguard Worker }
864*c8dee2aaSAndroid Build Coastguard Worker 
test_make_render_target(skiatest::Reporter * reporter,GrDirectContext * dContext,const SurfaceParameters & params)865*c8dee2aaSAndroid Build Coastguard Worker static void test_make_render_target(skiatest::Reporter* reporter,
866*c8dee2aaSAndroid Build Coastguard Worker                                     GrDirectContext* dContext,
867*c8dee2aaSAndroid Build Coastguard Worker                                     const SurfaceParameters& params) {
868*c8dee2aaSAndroid Build Coastguard Worker     {
869*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceCharacterization c = params.createCharacterization(dContext);
870*c8dee2aaSAndroid Build Coastguard Worker 
871*c8dee2aaSAndroid Build Coastguard Worker         if (!c.isValid()) {
872*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkSurface> tmp = params.make(dContext);
873*c8dee2aaSAndroid Build Coastguard Worker             // If we couldn't characterize the surface we shouldn't be able to create it either
874*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !tmp);
875*c8dee2aaSAndroid Build Coastguard Worker             return;
876*c8dee2aaSAndroid Build Coastguard Worker         }
877*c8dee2aaSAndroid Build Coastguard Worker     }
878*c8dee2aaSAndroid Build Coastguard Worker 
879*c8dee2aaSAndroid Build Coastguard Worker     const GrSurfaceCharacterization c = params.createCharacterization(dContext);
880*c8dee2aaSAndroid Build Coastguard Worker     {
881*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = params.make(dContext);
882*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, s);
883*c8dee2aaSAndroid Build Coastguard Worker         if (!s) {
884*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, !c.isValid());
885*c8dee2aaSAndroid Build Coastguard Worker             return;
886*c8dee2aaSAndroid Build Coastguard Worker         }
887*c8dee2aaSAndroid Build Coastguard Worker 
888*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, c.isValid());
889*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTexture backend =
890*c8dee2aaSAndroid Build Coastguard Worker                 SkSurfaces::GetBackendTexture(s.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
891*c8dee2aaSAndroid Build Coastguard Worker         if (backend.isValid()) {
892*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, is_compatible(c, backend));
893*c8dee2aaSAndroid Build Coastguard Worker         }
894*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, s->isCompatible(c));
895*c8dee2aaSAndroid Build Coastguard Worker         // Note that we're leaving 'backend' live here
896*c8dee2aaSAndroid Build Coastguard Worker     }
897*c8dee2aaSAndroid Build Coastguard Worker 
898*c8dee2aaSAndroid Build Coastguard Worker     // Make an SkSurface from scratch
899*c8dee2aaSAndroid Build Coastguard Worker     {
900*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = SkSurfaces::RenderTarget(dContext, c, skgpu::Budgeted::kYes);
901*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, s);
902*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, s->isCompatible(c));
903*c8dee2aaSAndroid Build Coastguard Worker     }
904*c8dee2aaSAndroid Build Coastguard Worker }
905*c8dee2aaSAndroid Build Coastguard Worker 
906*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
907*c8dee2aaSAndroid Build Coastguard Worker // This tests the SkSurfaces::RenderTarget variants that take a GrSurfaceCharacterization.
908*c8dee2aaSAndroid Build Coastguard Worker // In particular, the SkSurface, backendTexture and GrSurfaceCharacterization
909*c8dee2aaSAndroid Build Coastguard Worker // should always be compatible.
DDLMakeRenderTargetTestImpl(GrDirectContext * dContext,skiatest::Reporter * reporter)910*c8dee2aaSAndroid Build Coastguard Worker void DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
911*c8dee2aaSAndroid Build Coastguard Worker     for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
912*c8dee2aaSAndroid Build Coastguard Worker         if (i == SurfaceParameters::kFBO0Count || i == SurfaceParameters::kVkSCBCount) {
913*c8dee2aaSAndroid Build Coastguard Worker             // MakeRenderTarget doesn't support FBO0 or vulkan secondary command buffers
914*c8dee2aaSAndroid Build Coastguard Worker             continue;
915*c8dee2aaSAndroid Build Coastguard Worker         }
916*c8dee2aaSAndroid Build Coastguard Worker 
917*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(dContext);
918*c8dee2aaSAndroid Build Coastguard Worker         if (i >= 0 && !params.modify(i)) {
919*c8dee2aaSAndroid Build Coastguard Worker             continue;
920*c8dee2aaSAndroid Build Coastguard Worker         }
921*c8dee2aaSAndroid Build Coastguard Worker 
922*c8dee2aaSAndroid Build Coastguard Worker         test_make_render_target(reporter, dContext, params);
923*c8dee2aaSAndroid Build Coastguard Worker     }
924*c8dee2aaSAndroid Build Coastguard Worker }
925*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest,reporter,ctxInfo,CtsEnforcement::kNever)926*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest,
927*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
928*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
929*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
930*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
931*c8dee2aaSAndroid Build Coastguard Worker 
932*c8dee2aaSAndroid Build Coastguard Worker     DDLMakeRenderTargetTestImpl(context, reporter);
933*c8dee2aaSAndroid Build Coastguard Worker }
934*c8dee2aaSAndroid Build Coastguard Worker 
935*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_VULKAN)
936*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST(VkProtectedContext_DDLMakeRenderTargetTest,reporter,ctxInfo,CtsEnforcement::kNever)937*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VkProtectedContext_DDLMakeRenderTargetTest,
938*c8dee2aaSAndroid Build Coastguard Worker                 reporter,
939*c8dee2aaSAndroid Build Coastguard Worker                 ctxInfo,
940*c8dee2aaSAndroid Build Coastguard Worker                 CtsEnforcement::kNever) {
941*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
942*c8dee2aaSAndroid Build Coastguard Worker                                                               /* isProtected= */ true);
943*c8dee2aaSAndroid Build Coastguard Worker     if (!helper) {
944*c8dee2aaSAndroid Build Coastguard Worker         return;
945*c8dee2aaSAndroid Build Coastguard Worker     }
946*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper->isValid());
947*c8dee2aaSAndroid Build Coastguard Worker 
948*c8dee2aaSAndroid Build Coastguard Worker     DDLMakeRenderTargetTestImpl(helper->directContext(), reporter);
949*c8dee2aaSAndroid Build Coastguard Worker }
950*c8dee2aaSAndroid Build Coastguard Worker #endif
951*c8dee2aaSAndroid Build Coastguard Worker 
952*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
953*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kSize = 8;
954*c8dee2aaSAndroid Build Coastguard Worker 
955*c8dee2aaSAndroid Build Coastguard Worker struct TextureReleaseChecker {
TextureReleaseCheckerTextureReleaseChecker956*c8dee2aaSAndroid Build Coastguard Worker     TextureReleaseChecker() : fReleaseCount(0) {}
957*c8dee2aaSAndroid Build Coastguard Worker     int fReleaseCount;
ReleaseTextureReleaseChecker958*c8dee2aaSAndroid Build Coastguard Worker     static void Release(void* self) {
959*c8dee2aaSAndroid Build Coastguard Worker         static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
960*c8dee2aaSAndroid Build Coastguard Worker     }
961*c8dee2aaSAndroid Build Coastguard Worker };
962*c8dee2aaSAndroid Build Coastguard Worker 
963*c8dee2aaSAndroid Build Coastguard Worker enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
964*c8dee2aaSAndroid Build Coastguard Worker 
965*c8dee2aaSAndroid Build Coastguard Worker // This tests the ability to create and use wrapped textures in a DDL world
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest,reporter,ctxInfo,CtsEnforcement::kNever)966*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest,
967*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
968*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
969*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
970*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
971*c8dee2aaSAndroid Build Coastguard Worker 
972*c8dee2aaSAndroid Build Coastguard Worker     auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext,
973*c8dee2aaSAndroid Build Coastguard Worker                                                                     kSize,
974*c8dee2aaSAndroid Build Coastguard Worker                                                                     kSize,
975*c8dee2aaSAndroid Build Coastguard Worker                                                                     kRGBA_8888_SkColorType,
976*c8dee2aaSAndroid Build Coastguard Worker                                                                     skgpu::Mipmapped::kNo,
977*c8dee2aaSAndroid Build Coastguard Worker                                                                     GrRenderable::kNo,
978*c8dee2aaSAndroid Build Coastguard Worker                                                                     skgpu::Protected::kNo);
979*c8dee2aaSAndroid Build Coastguard Worker     if (!mbet) {
980*c8dee2aaSAndroid Build Coastguard Worker         return;
981*c8dee2aaSAndroid Build Coastguard Worker     }
982*c8dee2aaSAndroid Build Coastguard Worker 
983*c8dee2aaSAndroid Build Coastguard Worker     SurfaceParameters params(dContext);
984*c8dee2aaSAndroid Build Coastguard Worker 
985*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> s = params.make(dContext);
986*c8dee2aaSAndroid Build Coastguard Worker     if (!s) {
987*c8dee2aaSAndroid Build Coastguard Worker         return;
988*c8dee2aaSAndroid Build Coastguard Worker     }
989*c8dee2aaSAndroid Build Coastguard Worker 
990*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization c;
991*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(s->characterize(&c));
992*c8dee2aaSAndroid Build Coastguard Worker 
993*c8dee2aaSAndroid Build Coastguard Worker     GrDeferredDisplayListRecorder recorder(c);
994*c8dee2aaSAndroid Build Coastguard Worker 
995*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* canvas = recorder.getCanvas();
996*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(canvas);
997*c8dee2aaSAndroid Build Coastguard Worker 
998*c8dee2aaSAndroid Build Coastguard Worker     auto rContext = canvas->recordingContext();
999*c8dee2aaSAndroid Build Coastguard Worker     if (!rContext) {
1000*c8dee2aaSAndroid Build Coastguard Worker         return;
1001*c8dee2aaSAndroid Build Coastguard Worker     }
1002*c8dee2aaSAndroid Build Coastguard Worker 
1003*c8dee2aaSAndroid Build Coastguard Worker     // Wrapped Backend Textures are not supported in DDL
1004*c8dee2aaSAndroid Build Coastguard Worker     TextureReleaseChecker releaseChecker;
1005*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
1006*c8dee2aaSAndroid Build Coastguard Worker             rContext,
1007*c8dee2aaSAndroid Build Coastguard Worker             mbet->texture(),
1008*c8dee2aaSAndroid Build Coastguard Worker             kTopLeft_GrSurfaceOrigin,
1009*c8dee2aaSAndroid Build Coastguard Worker             kRGBA_8888_SkColorType,
1010*c8dee2aaSAndroid Build Coastguard Worker             kPremul_SkAlphaType,
1011*c8dee2aaSAndroid Build Coastguard Worker             nullptr,
1012*c8dee2aaSAndroid Build Coastguard Worker             sk_gpu_test::ManagedBackendTexture::ReleaseProc,
1013*c8dee2aaSAndroid Build Coastguard Worker             mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker));
1014*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, !image);
1015*c8dee2aaSAndroid Build Coastguard Worker }
1016*c8dee2aaSAndroid Build Coastguard Worker 
1017*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
1018*c8dee2aaSAndroid Build Coastguard Worker // Test out the behavior of an invalid DDLRecorder
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder,reporter,ctxInfo,CtsEnforcement::kNever)1019*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder,
1020*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1021*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1022*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1023*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
1024*c8dee2aaSAndroid Build Coastguard Worker 
1025*c8dee2aaSAndroid Build Coastguard Worker     {
1026*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1027*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> s = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, ii);
1028*c8dee2aaSAndroid Build Coastguard Worker 
1029*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization characterization;
1030*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(s->characterize(&characterization));
1031*c8dee2aaSAndroid Build Coastguard Worker 
1032*c8dee2aaSAndroid Build Coastguard Worker         // never calling getCanvas means the backing surface is never allocated
1033*c8dee2aaSAndroid Build Coastguard Worker         GrDeferredDisplayListRecorder recorder(characterization);
1034*c8dee2aaSAndroid Build Coastguard Worker     }
1035*c8dee2aaSAndroid Build Coastguard Worker 
1036*c8dee2aaSAndroid Build Coastguard Worker     {
1037*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization invalid;
1038*c8dee2aaSAndroid Build Coastguard Worker 
1039*c8dee2aaSAndroid Build Coastguard Worker         GrDeferredDisplayListRecorder recorder(invalid);
1040*c8dee2aaSAndroid Build Coastguard Worker 
1041*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceCharacterization c = recorder.characterization();
1042*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !c.isValid());
1043*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !recorder.getCanvas());
1044*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !recorder.detach());
1045*c8dee2aaSAndroid Build Coastguard Worker     }
1046*c8dee2aaSAndroid Build Coastguard Worker }
1047*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures,reporter,ctxInfo,CtsEnforcement::kNever)1048*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures,
1049*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1050*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1051*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1052*c8dee2aaSAndroid Build Coastguard Worker     using namespace skgpu;
1053*c8dee2aaSAndroid Build Coastguard Worker 
1054*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
1055*c8dee2aaSAndroid Build Coastguard Worker     size_t maxResourceBytes = dContext->getResourceCacheLimit();
1056*c8dee2aaSAndroid Build Coastguard Worker     auto proxy = dContext->threadSafeProxy().get();
1057*c8dee2aaSAndroid Build Coastguard Worker 
1058*c8dee2aaSAndroid Build Coastguard Worker     Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
1059*c8dee2aaSAndroid Build Coastguard Worker 
1060*c8dee2aaSAndroid Build Coastguard Worker     auto check_create_fails = [proxy, reporter, maxResourceBytes](
1061*c8dee2aaSAndroid Build Coastguard Worker                                       const GrBackendFormat& backendFormat,
1062*c8dee2aaSAndroid Build Coastguard Worker                                       int width,
1063*c8dee2aaSAndroid Build Coastguard Worker                                       int height,
1064*c8dee2aaSAndroid Build Coastguard Worker                                       SkColorType ct,
1065*c8dee2aaSAndroid Build Coastguard Worker                                       bool willUseGLFBO0,
1066*c8dee2aaSAndroid Build Coastguard Worker                                       bool isTextureable,
1067*c8dee2aaSAndroid Build Coastguard Worker                                       Protected prot,
1068*c8dee2aaSAndroid Build Coastguard Worker                                       bool vkRTSupportsInputAttachment,
1069*c8dee2aaSAndroid Build Coastguard Worker                                       bool forVulkanSecondaryCommandBuffer) {
1070*c8dee2aaSAndroid Build Coastguard Worker         const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
1071*c8dee2aaSAndroid Build Coastguard Worker 
1072*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::Make(width, height, ct,
1073*c8dee2aaSAndroid Build Coastguard Worker                                            kPremul_SkAlphaType, nullptr);
1074*c8dee2aaSAndroid Build Coastguard Worker 
1075*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization c =
1076*c8dee2aaSAndroid Build Coastguard Worker                 proxy->createCharacterization(maxResourceBytes,
1077*c8dee2aaSAndroid Build Coastguard Worker                                               ii,
1078*c8dee2aaSAndroid Build Coastguard Worker                                               backendFormat,
1079*c8dee2aaSAndroid Build Coastguard Worker                                               1,
1080*c8dee2aaSAndroid Build Coastguard Worker                                               kBottomLeft_GrSurfaceOrigin,
1081*c8dee2aaSAndroid Build Coastguard Worker                                               surfaceProps,
1082*c8dee2aaSAndroid Build Coastguard Worker                                               Mipmapped::kNo,
1083*c8dee2aaSAndroid Build Coastguard Worker                                               willUseGLFBO0,
1084*c8dee2aaSAndroid Build Coastguard Worker                                               isTextureable,
1085*c8dee2aaSAndroid Build Coastguard Worker                                               prot,
1086*c8dee2aaSAndroid Build Coastguard Worker                                               vkRTSupportsInputAttachment,
1087*c8dee2aaSAndroid Build Coastguard Worker                                               forVulkanSecondaryCommandBuffer);
1088*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !c.isValid());
1089*c8dee2aaSAndroid Build Coastguard Worker     };
1090*c8dee2aaSAndroid Build Coastguard Worker 
1091*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat goodBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
1092*c8dee2aaSAndroid Build Coastguard Worker                                                                        GrRenderable::kYes);
1093*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(goodBackendFormat.isValid());
1094*c8dee2aaSAndroid Build Coastguard Worker 
1095*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat badBackendFormat;
1096*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!badBackendFormat.isValid());
1097*c8dee2aaSAndroid Build Coastguard Worker 
1098*c8dee2aaSAndroid Build Coastguard Worker     SkColorType kGoodCT = kRGBA_8888_SkColorType;
1099*c8dee2aaSAndroid Build Coastguard Worker     SkColorType kBadCT = kUnknown_SkColorType;
1100*c8dee2aaSAndroid Build Coastguard Worker 
1101*c8dee2aaSAndroid Build Coastguard Worker     static const bool kIsTextureable = true;
1102*c8dee2aaSAndroid Build Coastguard Worker     static const bool kIsNotTextureable = false;
1103*c8dee2aaSAndroid Build Coastguard Worker 
1104*c8dee2aaSAndroid Build Coastguard Worker     static const bool kGoodUseFBO0 = false;
1105*c8dee2aaSAndroid Build Coastguard Worker     static const bool kBadUseFBO0 = true;
1106*c8dee2aaSAndroid Build Coastguard Worker 
1107*c8dee2aaSAndroid Build Coastguard Worker     static const bool kGoodVkInputAttachment = false;
1108*c8dee2aaSAndroid Build Coastguard Worker     static const bool kBadVkInputAttachment = true;
1109*c8dee2aaSAndroid Build Coastguard Worker 
1110*c8dee2aaSAndroid Build Coastguard Worker     static const bool kGoodForVkSCB = false;
1111*c8dee2aaSAndroid Build Coastguard Worker     static const bool kBadForVkSCB = true;
1112*c8dee2aaSAndroid Build Coastguard Worker 
1113*c8dee2aaSAndroid Build Coastguard Worker     int goodWidth = 64;
1114*c8dee2aaSAndroid Build Coastguard Worker     int goodHeight = 64;
1115*c8dee2aaSAndroid Build Coastguard Worker     int badWidths[] = { 0, 1048576 };
1116*c8dee2aaSAndroid Build Coastguard Worker     int badHeights[] = { 0, 1048576 };
1117*c8dee2aaSAndroid Build Coastguard Worker 
1118*c8dee2aaSAndroid Build Coastguard Worker 
1119*c8dee2aaSAndroid Build Coastguard Worker     // In each of the check_create_fails calls there is one bad parameter that should cause the
1120*c8dee2aaSAndroid Build Coastguard Worker     // creation of the characterization to fail.
1121*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, goodWidth, badHeights[0], kGoodCT, kGoodUseFBO0,
1122*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1123*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, goodWidth, badHeights[1], kGoodCT, kGoodUseFBO0,
1124*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1125*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, badWidths[0], goodHeight, kGoodCT, kGoodUseFBO0,
1126*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1127*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, badWidths[1], goodHeight, kGoodCT, kGoodUseFBO0,
1128*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1129*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(badBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1130*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1131*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, goodWidth, goodHeight, kBadCT, kGoodUseFBO0,
1132*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1133*c8dee2aaSAndroid Build Coastguard Worker     // This fails because we always try to make a characterization that is textureable and we can't
1134*c8dee2aaSAndroid Build Coastguard Worker     // have UseFBO0 be true and textureable.
1135*c8dee2aaSAndroid Build Coastguard Worker     check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1136*c8dee2aaSAndroid Build Coastguard Worker                        kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1137*c8dee2aaSAndroid Build Coastguard Worker     if (dContext->backend() == GrBackendApi::kVulkan) {
1138*c8dee2aaSAndroid Build Coastguard Worker         // The following fails because forVulkanSecondaryCommandBuffer is true and
1139*c8dee2aaSAndroid Build Coastguard Worker         // isTextureable is true. This is not a legal combination.
1140*c8dee2aaSAndroid Build Coastguard Worker         check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1141*c8dee2aaSAndroid Build Coastguard Worker                            kIsTextureable, isProtected, kGoodVkInputAttachment, kBadForVkSCB);
1142*c8dee2aaSAndroid Build Coastguard Worker         // The following fails because forVulkanSecondaryCommandBuffer is true and
1143*c8dee2aaSAndroid Build Coastguard Worker         // vkRTSupportsInputAttachment is true. This is not a legal combination.
1144*c8dee2aaSAndroid Build Coastguard Worker         check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1145*c8dee2aaSAndroid Build Coastguard Worker                            kIsNotTextureable, isProtected, kBadVkInputAttachment,
1146*c8dee2aaSAndroid Build Coastguard Worker                            kBadForVkSCB);
1147*c8dee2aaSAndroid Build Coastguard Worker         // The following fails because forVulkanSecondaryCommandBuffer is true and
1148*c8dee2aaSAndroid Build Coastguard Worker         // willUseGLFBO0 is true. This is not a legal combination.
1149*c8dee2aaSAndroid Build Coastguard Worker         check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1150*c8dee2aaSAndroid Build Coastguard Worker                            kIsNotTextureable, isProtected, kGoodVkInputAttachment,
1151*c8dee2aaSAndroid Build Coastguard Worker                            kBadForVkSCB);
1152*c8dee2aaSAndroid Build Coastguard Worker     } else {
1153*c8dee2aaSAndroid Build Coastguard Worker         // The following set vulkan only flags on non vulkan backends.
1154*c8dee2aaSAndroid Build Coastguard Worker         check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1155*c8dee2aaSAndroid Build Coastguard Worker                            kIsTextureable, isProtected, kBadVkInputAttachment, kGoodForVkSCB);
1156*c8dee2aaSAndroid Build Coastguard Worker         check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1157*c8dee2aaSAndroid Build Coastguard Worker                            kIsNotTextureable, isProtected, kGoodVkInputAttachment,
1158*c8dee2aaSAndroid Build Coastguard Worker                            kBadForVkSCB);
1159*c8dee2aaSAndroid Build Coastguard Worker     }
1160*c8dee2aaSAndroid Build Coastguard Worker }
1161*c8dee2aaSAndroid Build Coastguard Worker 
1162*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
1163*c8dee2aaSAndroid Build Coastguard Worker // Test that flushing a DDL via SkSurface::flush works
1164*c8dee2aaSAndroid Build Coastguard Worker 
1165*c8dee2aaSAndroid Build Coastguard Worker struct FulfillInfo {
1166*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrPromiseImageTexture> fTex;
1167*c8dee2aaSAndroid Build Coastguard Worker     bool fFulfilled = false;
1168*c8dee2aaSAndroid Build Coastguard Worker     bool fReleased  = false;
1169*c8dee2aaSAndroid Build Coastguard Worker };
1170*c8dee2aaSAndroid Build Coastguard Worker 
tracking_fulfill_proc(void * context)1171*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrPromiseImageTexture> tracking_fulfill_proc(void* context) {
1172*c8dee2aaSAndroid Build Coastguard Worker     FulfillInfo* info = (FulfillInfo*) context;
1173*c8dee2aaSAndroid Build Coastguard Worker     info->fFulfilled = true;
1174*c8dee2aaSAndroid Build Coastguard Worker     return info->fTex;
1175*c8dee2aaSAndroid Build Coastguard Worker }
1176*c8dee2aaSAndroid Build Coastguard Worker 
tracking_release_proc(void * context)1177*c8dee2aaSAndroid Build Coastguard Worker static void tracking_release_proc(void* context) {
1178*c8dee2aaSAndroid Build Coastguard Worker     FulfillInfo* info = (FulfillInfo*) context;
1179*c8dee2aaSAndroid Build Coastguard Worker     info->fReleased = true;
1180*c8dee2aaSAndroid Build Coastguard Worker }
1181*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush,reporter,ctxInfo,CtsEnforcement::kNever)1182*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush,
1183*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1184*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1185*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1186*c8dee2aaSAndroid Build Coastguard Worker     using namespace skgpu;
1187*c8dee2aaSAndroid Build Coastguard Worker 
1188*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
1189*c8dee2aaSAndroid Build Coastguard Worker 
1190*c8dee2aaSAndroid Build Coastguard Worker     Protected isProtected = Protected(context->priv().caps()->supportsProtectedContent());
1191*c8dee2aaSAndroid Build Coastguard Worker 
1192*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1193*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> s = SkSurfaces::RenderTarget(context, Budgeted::kNo, ii);
1194*c8dee2aaSAndroid Build Coastguard Worker 
1195*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization characterization;
1196*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(s->characterize(&characterization));
1197*c8dee2aaSAndroid Build Coastguard Worker 
1198*c8dee2aaSAndroid Build Coastguard Worker     auto mbet = sk_gpu_test::ManagedBackendTexture::MakeFromInfo(context, ii,
1199*c8dee2aaSAndroid Build Coastguard Worker                                                                  Mipmapped::kNo,
1200*c8dee2aaSAndroid Build Coastguard Worker                                                                  Renderable::kNo,
1201*c8dee2aaSAndroid Build Coastguard Worker                                                                  isProtected);
1202*c8dee2aaSAndroid Build Coastguard Worker     if (!mbet) {
1203*c8dee2aaSAndroid Build Coastguard Worker         ERRORF(reporter, "Could not make texture.");
1204*c8dee2aaSAndroid Build Coastguard Worker         return;
1205*c8dee2aaSAndroid Build Coastguard Worker     }
1206*c8dee2aaSAndroid Build Coastguard Worker 
1207*c8dee2aaSAndroid Build Coastguard Worker     FulfillInfo fulfillInfo;
1208*c8dee2aaSAndroid Build Coastguard Worker     fulfillInfo.fTex = GrPromiseImageTexture::Make(mbet->texture());
1209*c8dee2aaSAndroid Build Coastguard Worker 
1210*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl;
1211*c8dee2aaSAndroid Build Coastguard Worker 
1212*c8dee2aaSAndroid Build Coastguard Worker     {
1213*c8dee2aaSAndroid Build Coastguard Worker         GrDeferredDisplayListRecorder recorder(characterization);
1214*c8dee2aaSAndroid Build Coastguard Worker 
1215*c8dee2aaSAndroid Build Coastguard Worker         GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
1216*c8dee2aaSAndroid Build Coastguard Worker                                                                GrRenderable::kNo);
1217*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(format.isValid());
1218*c8dee2aaSAndroid Build Coastguard Worker 
1219*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas* canvas = recorder.getCanvas();
1220*c8dee2aaSAndroid Build Coastguard Worker 
1221*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage> promiseImage =
1222*c8dee2aaSAndroid Build Coastguard Worker                 SkImages::PromiseTextureFrom(canvas->recordingContext()->threadSafeProxy(),
1223*c8dee2aaSAndroid Build Coastguard Worker                                              format,
1224*c8dee2aaSAndroid Build Coastguard Worker                                              SkISize::Make(32, 32),
1225*c8dee2aaSAndroid Build Coastguard Worker                                              skgpu::Mipmapped::kNo,
1226*c8dee2aaSAndroid Build Coastguard Worker                                              kTopLeft_GrSurfaceOrigin,
1227*c8dee2aaSAndroid Build Coastguard Worker                                              kRGBA_8888_SkColorType,
1228*c8dee2aaSAndroid Build Coastguard Worker                                              kPremul_SkAlphaType,
1229*c8dee2aaSAndroid Build Coastguard Worker                                              nullptr,
1230*c8dee2aaSAndroid Build Coastguard Worker                                              tracking_fulfill_proc,
1231*c8dee2aaSAndroid Build Coastguard Worker                                              tracking_release_proc,
1232*c8dee2aaSAndroid Build Coastguard Worker                                              &fulfillInfo);
1233*c8dee2aaSAndroid Build Coastguard Worker 
1234*c8dee2aaSAndroid Build Coastguard Worker         canvas->clear(SK_ColorRED);
1235*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawImage(promiseImage, 0, 0);
1236*c8dee2aaSAndroid Build Coastguard Worker         ddl = recorder.detach();
1237*c8dee2aaSAndroid Build Coastguard Worker     }
1238*c8dee2aaSAndroid Build Coastguard Worker 
1239*c8dee2aaSAndroid Build Coastguard Worker     context->flushAndSubmit();
1240*c8dee2aaSAndroid Build Coastguard Worker 
1241*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, skgpu::ganesh::DrawDDL(s, ddl));
1242*c8dee2aaSAndroid Build Coastguard Worker 
1243*c8dee2aaSAndroid Build Coastguard Worker     GrFlushInfo flushInfo;
1244*c8dee2aaSAndroid Build Coastguard Worker     context->flush(s.get(), SkSurfaces::BackendSurfaceAccess::kPresent, flushInfo);
1245*c8dee2aaSAndroid Build Coastguard Worker     context->submit(GrSyncCpu::kNo);
1246*c8dee2aaSAndroid Build Coastguard Worker 
1247*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled);
1248*c8dee2aaSAndroid Build Coastguard Worker 
1249*c8dee2aaSAndroid Build Coastguard Worker     // In order to receive the done callback with the low-level APIs we need to re-flush
1250*c8dee2aaSAndroid Build Coastguard Worker     context->flush(s.get());
1251*c8dee2aaSAndroid Build Coastguard Worker     context->submit(GrSyncCpu::kYes);
1252*c8dee2aaSAndroid Build Coastguard Worker 
1253*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, fulfillInfo.fReleased);
1254*c8dee2aaSAndroid Build Coastguard Worker 
1255*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique());
1256*c8dee2aaSAndroid Build Coastguard Worker     fulfillInfo.fTex.reset();
1257*c8dee2aaSAndroid Build Coastguard Worker }
1258*c8dee2aaSAndroid Build Coastguard Worker 
1259*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
1260*c8dee2aaSAndroid Build Coastguard Worker // Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs,reporter,ctxInfo,CtsEnforcement::kNever)1261*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo, CtsEnforcement::kNever) {
1262*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
1263*c8dee2aaSAndroid Build Coastguard Worker 
1264*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1265*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> s = SkSurfaces::RenderTarget(context, skgpu::Budgeted::kNo, ii);
1266*c8dee2aaSAndroid Build Coastguard Worker 
1267*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
1268*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(ii);
1269*c8dee2aaSAndroid Build Coastguard Worker 
1270*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization characterization;
1271*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(s->characterize(&characterization));
1272*c8dee2aaSAndroid Build Coastguard Worker 
1273*c8dee2aaSAndroid Build Coastguard Worker     GrDeferredDisplayListRecorder recorder(characterization);
1274*c8dee2aaSAndroid Build Coastguard Worker 
1275*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* canvas1 = recorder.getCanvas();
1276*c8dee2aaSAndroid Build Coastguard Worker 
1277*c8dee2aaSAndroid Build Coastguard Worker     canvas1->clear(SK_ColorRED);
1278*c8dee2aaSAndroid Build Coastguard Worker 
1279*c8dee2aaSAndroid Build Coastguard Worker     canvas1->save();
1280*c8dee2aaSAndroid Build Coastguard Worker     canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
1281*c8dee2aaSAndroid Build Coastguard Worker 
1282*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = recorder.detach();
1283*c8dee2aaSAndroid Build Coastguard Worker 
1284*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* canvas2 = recorder.getCanvas();
1285*c8dee2aaSAndroid Build Coastguard Worker 
1286*c8dee2aaSAndroid Build Coastguard Worker     SkPaint p;
1287*c8dee2aaSAndroid Build Coastguard Worker     p.setColor(SK_ColorGREEN);
1288*c8dee2aaSAndroid Build Coastguard Worker     canvas2->drawRect(SkRect::MakeWH(32, 32), p);
1289*c8dee2aaSAndroid Build Coastguard Worker 
1290*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = recorder.detach();
1291*c8dee2aaSAndroid Build Coastguard Worker 
1292*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
1293*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
1294*c8dee2aaSAndroid Build Coastguard Worker 
1295*c8dee2aaSAndroid Build Coastguard Worker     // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
1296*c8dee2aaSAndroid Build Coastguard Worker     // lazy proxy are all different between the two DDLs
1297*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
1298*c8dee2aaSAndroid Build Coastguard Worker 
1299*c8dee2aaSAndroid Build Coastguard Worker     skgpu::ganesh::DrawDDL(s, ddl1);
1300*c8dee2aaSAndroid Build Coastguard Worker     skgpu::ganesh::DrawDDL(s, ddl2);
1301*c8dee2aaSAndroid Build Coastguard Worker 
1302*c8dee2aaSAndroid Build Coastguard Worker     // Make sure the clipRect from DDL1 didn't percolate into DDL2
1303*c8dee2aaSAndroid Build Coastguard Worker     s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
1304*c8dee2aaSAndroid Build Coastguard Worker     for (int y = 0; y < 32; ++y) {
1305*c8dee2aaSAndroid Build Coastguard Worker         for (int x = 0; x < 32; ++x) {
1306*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
1307*c8dee2aaSAndroid Build Coastguard Worker             if (bitmap.getColor(x, y) != SK_ColorGREEN) {
1308*c8dee2aaSAndroid Build Coastguard Worker                 return; // we only really need to report the error once
1309*c8dee2aaSAndroid Build Coastguard Worker             }
1310*c8dee2aaSAndroid Build Coastguard Worker         }
1311*c8dee2aaSAndroid Build Coastguard Worker     }
1312*c8dee2aaSAndroid Build Coastguard Worker }
1313*c8dee2aaSAndroid Build Coastguard Worker 
1314*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
1315*c8dee2aaSAndroid Build Coastguard Worker 
noop_fulfill_proc(void *)1316*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrPromiseImageTexture> noop_fulfill_proc(void*) {
1317*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(0);
1318*c8dee2aaSAndroid Build Coastguard Worker     return nullptr;
1319*c8dee2aaSAndroid Build Coastguard Worker }
1320*c8dee2aaSAndroid Build Coastguard Worker 
1321*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
1322*c8dee2aaSAndroid Build Coastguard Worker // Check that the texture-specific flags (i.e., for external & rectangle textures) work
1323*c8dee2aaSAndroid Build Coastguard Worker // for promise images. As such, this is a GL-only test.
DEF_GANESH_TEST_FOR_GL_CONTEXT(DDLTextureFlagsTest,reporter,ctxInfo,CtsEnforcement::kNever)1324*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_GL_CONTEXT(DDLTextureFlagsTest, reporter, ctxInfo, CtsEnforcement::kNever) {
1325*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
1326*c8dee2aaSAndroid Build Coastguard Worker 
1327*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1328*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> s = SkSurfaces::RenderTarget(context, skgpu::Budgeted::kNo, ii);
1329*c8dee2aaSAndroid Build Coastguard Worker 
1330*c8dee2aaSAndroid Build Coastguard Worker     GrSurfaceCharacterization characterization;
1331*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(s->characterize(&characterization));
1332*c8dee2aaSAndroid Build Coastguard Worker 
1333*c8dee2aaSAndroid Build Coastguard Worker     GrDeferredDisplayListRecorder recorder(characterization);
1334*c8dee2aaSAndroid Build Coastguard Worker 
1335*c8dee2aaSAndroid Build Coastguard Worker     for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
1336*c8dee2aaSAndroid Build Coastguard Worker         for (auto mipmapped : {skgpu::Mipmapped::kNo, skgpu::Mipmapped::kYes}) {
1337*c8dee2aaSAndroid Build Coastguard Worker             GrBackendFormat format = GrBackendFormats::MakeGL(GR_GL_RGBA8, target);
1338*c8dee2aaSAndroid Build Coastguard Worker 
1339*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image = SkImages::PromiseTextureFrom(
1340*c8dee2aaSAndroid Build Coastguard Worker                     recorder.getCanvas()->recordingContext()->threadSafeProxy(),
1341*c8dee2aaSAndroid Build Coastguard Worker                     format,
1342*c8dee2aaSAndroid Build Coastguard Worker                     SkISize::Make(32, 32),
1343*c8dee2aaSAndroid Build Coastguard Worker                     mipmapped,
1344*c8dee2aaSAndroid Build Coastguard Worker                     kTopLeft_GrSurfaceOrigin,
1345*c8dee2aaSAndroid Build Coastguard Worker                     kRGBA_8888_SkColorType,
1346*c8dee2aaSAndroid Build Coastguard Worker                     kPremul_SkAlphaType,
1347*c8dee2aaSAndroid Build Coastguard Worker                     /*color space*/ nullptr,
1348*c8dee2aaSAndroid Build Coastguard Worker                     noop_fulfill_proc,
1349*c8dee2aaSAndroid Build Coastguard Worker                     /*release proc*/ nullptr,
1350*c8dee2aaSAndroid Build Coastguard Worker                     /*context*/ nullptr);
1351*c8dee2aaSAndroid Build Coastguard Worker             if (GR_GL_TEXTURE_2D != target && mipmapped == skgpu::Mipmapped::kYes) {
1352*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !image);
1353*c8dee2aaSAndroid Build Coastguard Worker                 continue;
1354*c8dee2aaSAndroid Build Coastguard Worker             }
1355*c8dee2aaSAndroid Build Coastguard Worker             if (!context->priv().caps()->isFormatTexturable(format, format.textureType())) {
1356*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !image);
1357*c8dee2aaSAndroid Build Coastguard Worker                 continue;
1358*c8dee2aaSAndroid Build Coastguard Worker             }
1359*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, image);
1360*c8dee2aaSAndroid Build Coastguard Worker 
1361*c8dee2aaSAndroid Build Coastguard Worker             GrTextureProxy* backingProxy = sk_gpu_test::GetTextureImageProxy(image.get(), context);
1362*c8dee2aaSAndroid Build Coastguard Worker 
1363*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipmapped);
1364*c8dee2aaSAndroid Build Coastguard Worker             if (GR_GL_TEXTURE_2D == target) {
1365*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
1366*c8dee2aaSAndroid Build Coastguard Worker             } else {
1367*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
1368*c8dee2aaSAndroid Build Coastguard Worker             }
1369*c8dee2aaSAndroid Build Coastguard Worker         }
1370*c8dee2aaSAndroid Build Coastguard Worker     }
1371*c8dee2aaSAndroid Build Coastguard Worker }
1372*c8dee2aaSAndroid Build Coastguard Worker #endif  // SK_GL
1373*c8dee2aaSAndroid Build Coastguard Worker 
1374*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
1375*c8dee2aaSAndroid Build Coastguard Worker // Test colorType and pixelConfig compatibility.
DEF_GANESH_TEST_FOR_GL_CONTEXT(DDLCompatibilityTest,reporter,ctxInfo,CtsEnforcement::kNever)1376*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_GL_CONTEXT(DDLCompatibilityTest, reporter, ctxInfo, CtsEnforcement::kNever) {
1377*c8dee2aaSAndroid Build Coastguard Worker     auto context = ctxInfo.directContext();
1378*c8dee2aaSAndroid Build Coastguard Worker 
1379*c8dee2aaSAndroid Build Coastguard Worker     for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1380*c8dee2aaSAndroid Build Coastguard Worker         SkColorType colorType = static_cast<SkColorType>(ct);
1381*c8dee2aaSAndroid Build Coastguard Worker 
1382*c8dee2aaSAndroid Build Coastguard Worker         SurfaceParameters params(context);
1383*c8dee2aaSAndroid Build Coastguard Worker         params.setColorType(colorType);
1384*c8dee2aaSAndroid Build Coastguard Worker         params.setColorSpace(nullptr);
1385*c8dee2aaSAndroid Build Coastguard Worker 
1386*c8dee2aaSAndroid Build Coastguard Worker         test_make_render_target(reporter, context, params);
1387*c8dee2aaSAndroid Build Coastguard Worker     }
1388*c8dee2aaSAndroid Build Coastguard Worker }
1389