blob: 2375d510a0573b7ac190182a9e7873e558b93b33 [file] [log] [blame]
Robert Phillips7ffbcf92017-12-04 12:52:46 -05001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
9#include "include/core/SkCanvas.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040010#include "include/core/SkColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkColorSpace.h"
Robert Phillips4d5594d2020-02-21 14:24:40 -050012#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkDeferredDisplayListRecorder.h"
14#include "include/core/SkImage.h"
15#include "include/core/SkImageInfo.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkPromiseImageTexture.h"
18#include "include/core/SkRect.h"
19#include "include/core/SkRefCnt.h"
20#include "include/core/SkSurface.h"
21#include "include/core/SkSurfaceCharacterization.h"
22#include "include/core/SkSurfaceProps.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040023#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/gpu/GrBackendSurface.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040025#include "include/gpu/GrContextThreadSafeProxy.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040026#include "include/gpu/GrDirectContext.h"
Robert Phillipsc8ae4942020-07-20 10:56:01 -040027#include "include/gpu/GrRecordingContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "include/gpu/GrTypes.h"
29#include "include/gpu/gl/GrGLTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "src/core/SkDeferredDisplayListPriv.h"
32#include "src/gpu/GrCaps.h"
33#include "src/gpu/GrContextPriv.h"
34#include "src/gpu/GrGpu.h"
Robert Phillipsc8ae4942020-07-20 10:56:01 -040035#include "src/gpu/GrRecordingContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050036#include "src/gpu/GrRenderTargetContext.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040037#include "src/gpu/GrRenderTargetProxy.h"
38#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050039#include "src/gpu/SkGpuDevice.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050040#include "src/gpu/gl/GrGLDefines.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040041#include "src/image/SkImage_GpuBase.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050042#include "src/image/SkSurface_Gpu.h"
43#include "tests/Test.h"
Robert Phillipsee5fd132019-05-07 13:29:22 -040044#include "tests/TestUtils.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050045#include "tools/gpu/GrContextFactory.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040046
47#include <initializer_list>
48#include <memory>
49#include <utility>
Robert Phillipsfc711a22018-02-13 17:03:00 -050050
Robert Phillips3cd54322019-07-10 09:28:59 -040051#ifdef SK_VULKAN
52#include "src/gpu/vk/GrVkCaps.h"
53#endif
54
Robert Phillips7ffbcf92017-12-04 12:52:46 -050055class SurfaceParameters {
56public:
Robert Phillips3cd54322019-07-10 09:28:59 -040057 static const int kNumParams = 12;
58 static const int kSampleCount = 5;
59 static const int kMipMipCount = 8;
60 static const int kFBO0Count = 9;
61 static const int kProtectedCount = 11;
Robert Phillips7ffbcf92017-12-04 12:52:46 -050062
Robert Phillipsc8ae4942020-07-20 10:56:01 -040063 SurfaceParameters(GrRecordingContext* rContext)
64 : fBackend(rContext->backend())
Robert Phillipsb45f47d2019-02-03 17:17:54 -050065 , fWidth(64)
Robert Phillips7ffbcf92017-12-04 12:52:46 -050066 , fHeight(64)
67 , fOrigin(kTopLeft_GrSurfaceOrigin)
68 , fColorType(kRGBA_8888_SkColorType)
69 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -050070 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -050071 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
Robert Phillipsb45f47d2019-02-03 17:17:54 -050072 , fShouldCreateMipMaps(true)
73 , fUsesGLFBO0(false)
Robert Phillips3cd54322019-07-10 09:28:59 -040074 , fIsTextureable(true)
75 , fIsProtected(GrProtected::kNo) {
76#ifdef SK_VULKAN
Robert Phillipsc8ae4942020-07-20 10:56:01 -040077 if (GrBackendApi::kVulkan == rContext->backend()) {
78 const GrVkCaps* vkCaps = (const GrVkCaps*) rContext->priv().caps();
Robert Phillips3cd54322019-07-10 09:28:59 -040079
80 fIsProtected = GrProtected(vkCaps->supportsProtectedMemory());
81 }
82#endif
Robert Phillipse8fabb22018-02-04 14:33:21 -050083 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -050084
85 int sampleCount() const { return fSampleCount; }
86
Robert Phillipsbe77a022018-04-03 17:17:05 -040087 void setColorType(SkColorType ct) { fColorType = ct; }
Robert Phillipsd8f79a22019-06-24 13:25:42 -040088 SkColorType colorType() const { return fColorType; }
Robert Phillipsbe77a022018-04-03 17:17:05 -040089 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
Robert Phillipsb45f47d2019-02-03 17:17:54 -050090 void setTextureable(bool isTextureable) { fIsTextureable = isTextureable; }
Brian Salomon4687bdd2019-05-09 16:28:04 -040091 void setShouldCreateMipMaps(bool shouldCreateMipMaps) {
92 fShouldCreateMipMaps = shouldCreateMipMaps;
93 }
Robert Phillipsbe77a022018-04-03 17:17:05 -040094
Robert Phillips7ffbcf92017-12-04 12:52:46 -050095 // Modify the SurfaceParameters in just one way
96 void modify(int i) {
97 switch (i) {
98 case 0:
99 fWidth = 63;
100 break;
101 case 1:
102 fHeight = 63;
103 break;
104 case 2:
105 fOrigin = kBottomLeft_GrSurfaceOrigin;
106 break;
107 case 3:
108 fColorType = kRGBA_F16_SkColorType;
109 break;
110 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400111 // This just needs to be a colorSpace different from that returned by MakeSRGB().
112 // In this case we just change the gamut.
Brian Osman82ebe042019-01-04 17:03:00 -0500113 fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500114 break;
115 case kSampleCount:
116 fSampleCount = 4;
117 break;
118 case 6:
119 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
120 break;
121 case 7:
122 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
123 kUnknown_SkPixelGeometry);
124 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500125 case 8:
126 fShouldCreateMipMaps = false;
127 break;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500128 case 9:
129 if (GrBackendApi::kOpenGL == fBackend) {
130 fUsesGLFBO0 = true;
Robert Phillipsc046ff02019-07-01 10:34:03 -0400131 fShouldCreateMipMaps = false; // needs to changed in tandem w/ textureability
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500132 fIsTextureable = false;
133 }
134 break;
135 case 10:
Robert Phillipsc046ff02019-07-01 10:34:03 -0400136 fShouldCreateMipMaps = false; // needs to changed in tandem w/ textureability
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500137 fIsTextureable = false;
138 break;
Robert Phillips3cd54322019-07-10 09:28:59 -0400139 case 11:
140 fIsProtected = GrProtected::kYes == fIsProtected ? GrProtected::kNo
141 : GrProtected::kYes;
142 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500143 }
144 }
145
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400146 SkSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const {
147 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500148
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400149 if (!dContext->colorTypeSupportedAsSurface(fColorType)) {
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400150 return SkSurfaceCharacterization();
151 }
152
Robert Phillipsfc711a22018-02-13 17:03:00 -0500153 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
154 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
155 kPremul_SkAlphaType, fColorSpace);
156
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400157 GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType,
158 GrRenderable::kYes);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400159 if (!backendFormat.isValid()) {
160 return SkSurfaceCharacterization();
161 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500162
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400163 SkSurfaceCharacterization c = dContext->threadSafeProxy()->createCharacterization(
Robert Phillipsfc711a22018-02-13 17:03:00 -0500164 maxResourceBytes, ii, backendFormat, fSampleCount,
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500165 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
Robert Phillips3cd54322019-07-10 09:28:59 -0400166 fUsesGLFBO0, fIsTextureable, fIsProtected);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400167 return c;
168 }
169
170 // Create a DDL whose characterization captures the current settings
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400171 sk_sp<SkDeferredDisplayList> createDDL(GrDirectContext* dContext) const {
172 SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500173 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500174
175 SkDeferredDisplayListRecorder r(c);
176 SkCanvas* canvas = r.getCanvas();
177 if (!canvas) {
178 return nullptr;
179 }
180
181 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
182 return r.detach();
183 }
184
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500185 // Create the surface with the current set of parameters
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400186 sk_sp<SkSurface> make(GrDirectContext* dContext, GrBackendTexture* backend) const {
187 const SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400188
Brian Salomon7e67dca2020-07-21 09:27:25 -0400189 GrMipmapped mipmapped = !fIsTextureable
190 ? GrMipmapped::kNo
191 : GrMipmapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500192
John Rosasco24cbdab2019-09-25 14:14:35 -0700193#ifdef SK_GL
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500194 if (fUsesGLFBO0) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400195 if (GrBackendApi::kOpenGL != dContext->backend()) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500196 return nullptr;
197 }
198
199 GrGLFramebufferInfo fboInfo;
200 fboInfo.fFBOID = 0;
201 fboInfo.fFormat = GR_GL_RGBA8;
202 static constexpr int kStencilBits = 8;
203 GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500204
205 if (!backendRT.isValid()) {
206 return nullptr;
207 }
208
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400209 sk_sp<SkSurface> result = SkSurface::MakeFromBackendRenderTarget(dContext, backendRT,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400210 fOrigin, fColorType,
211 fColorSpace,
212 &fSurfaceProps);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400213 SkASSERT(result->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400214 return result;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500215 }
John Rosasco24cbdab2019-09-25 14:14:35 -0700216#endif
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400217 CreateBackendTexture(dContext, backend, fWidth, fHeight, fColorType,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400218 SkColors::kTransparent, mipmapped, GrRenderable::kYes, fIsProtected);
Robert Phillips7c8af172019-07-08 15:55:24 -0400219 if (!backend->isValid()) {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500220 return nullptr;
221 }
222
Robert Phillipsc046ff02019-07-01 10:34:03 -0400223 // Even if a characterization couldn't be constructed we want to soldier on to make
224 // sure that surface creation will/would've also failed
225 SkASSERT(!c.isValid() || c.isCompatible(*backend));
226
Robert Phillipsbe77a022018-04-03 17:17:05 -0400227 sk_sp<SkSurface> surface;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500228 if (!fIsTextureable) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400229 // Create a surface w/ the current parameters but make it non-textureable
230 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400231 dContext, *backend, fOrigin, fSampleCount, fColorType,
Robert Phillipsbe77a022018-04-03 17:17:05 -0400232 fColorSpace, &fSurfaceProps);
233 } else {
234 surface = SkSurface::MakeFromBackendTexture(
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400235 dContext, *backend, fOrigin, fSampleCount, fColorType,
Robert Phillipsbe77a022018-04-03 17:17:05 -0400236 fColorSpace, &fSurfaceProps);
237 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500238
239 if (!surface) {
Robert Phillipsc046ff02019-07-01 10:34:03 -0400240 SkASSERT(!c.isValid());
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400241 this->cleanUpBackEnd(dContext, *backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500242 return nullptr;
243 }
244
Robert Phillipsc046ff02019-07-01 10:34:03 -0400245 SkASSERT(c.isValid());
Robert Phillips9907e6e2019-06-25 14:47:04 -0400246 SkASSERT(surface->isCompatible(c));
Robert Phillipse8fabb22018-02-04 14:33:21 -0500247 return surface;
248 }
249
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400250 void cleanUpBackEnd(GrDirectContext* dContext, const GrBackendTexture& backend) const {
251 dContext->deleteBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500252 }
253
254private:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500255 GrBackendApi fBackend;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500256 int fWidth;
257 int fHeight;
258 GrSurfaceOrigin fOrigin;
259 SkColorType fColorType;
260 sk_sp<SkColorSpace> fColorSpace;
261 int fSampleCount;
262 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500263 bool fShouldCreateMipMaps;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500264 bool fUsesGLFBO0;
265 bool fIsTextureable;
Robert Phillips3cd54322019-07-10 09:28:59 -0400266 GrProtected fIsProtected;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500267};
268
Robert Phillipsc1267c62018-04-04 11:12:39 -0400269// Test out operator== && operator!=
270DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400271 auto context = ctxInfo.directContext();
Robert Phillipsc1267c62018-04-04 11:12:39 -0400272
Brian Salomon69100f02020-07-21 10:49:25 -0400273 bool mipmapSupport = context->priv().caps()->mipmapSupport();
Robert Phillipsc1267c62018-04-04 11:12:39 -0400274 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400275 SurfaceParameters params1(context);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400276 params1.modify(i);
277
278 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
279 if (!char1.isValid()) {
280 continue; // can happen on some platforms (ChromeOS)
281 }
282
Brian Salomon69100f02020-07-21 10:49:25 -0400283 if (SurfaceParameters::kMipMipCount == i && !mipmapSupport) {
Stephen White33603fd2020-06-29 11:04:43 -0400284 // If changing the mipmap setting won't result in a different surface characterization,
285 // skip this step.
286 continue;
287 }
288
Robert Phillipsc1267c62018-04-04 11:12:39 -0400289 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400290 SurfaceParameters params2(context);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400291 params2.modify(j);
292
293 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
294 if (!char2.isValid()) {
295 continue; // can happen on some platforms (ChromeOS)
296 }
297
Brian Salomon69100f02020-07-21 10:49:25 -0400298 if (SurfaceParameters::kMipMipCount == j && !mipmapSupport) {
Stephen White33603fd2020-06-29 11:04:43 -0400299 // If changing the mipmap setting won't result in a different surface
300 // characterization, skip this step.
301 continue;
302 }
303
Robert Phillipsc1267c62018-04-04 11:12:39 -0400304 if (i == j) {
305 REPORTER_ASSERT(reporter, char1 == char2);
306 } else {
307 REPORTER_ASSERT(reporter, char1 != char2);
308 }
309
310 }
311 }
312
313 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400314 SurfaceParameters params(context);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400315
316 SkSurfaceCharacterization valid = params.createCharacterization(context);
317 SkASSERT(valid.isValid());
318
319 SkSurfaceCharacterization inval1, inval2;
320 SkASSERT(!inval1.isValid() && !inval2.isValid());
321
322 REPORTER_ASSERT(reporter, inval1 != inval2);
323 REPORTER_ASSERT(reporter, valid != inval1);
324 REPORTER_ASSERT(reporter, inval1 != valid);
325 }
326}
327
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400328////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500329// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400330void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
331 GrGpu* gpu = dContext->priv().getGpu();
332 const GrCaps* caps = dContext->priv().caps();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500333
Robert Phillips9e441ee2018-02-01 15:14:55 -0500334 // Create a bitmap that we can readback into
335 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
336 kPremul_SkAlphaType);
337 SkBitmap bitmap;
338 bitmap.allocPixels(imageInfo);
339
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400340 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500341
342 // First, create a DDL using the stock SkSurface parameters
343 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400344 SurfaceParameters params(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500345
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400346 ddl = params.createDDL(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500347 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500348
349 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400350 GrBackendTexture backend;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400351 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500352 if (!s) {
353 return;
354 }
355
Adlai Holler7580ad42020-06-24 13:45:25 -0400356 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500357 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400358 dContext->flushAndSubmit();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400359 gpu->testingOnly_flushGpuAndSync();
360 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400361 params.cleanUpBackEnd(dContext, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500362 }
363
364 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
365 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400366 SurfaceParameters params(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500367 params.modify(i);
368
Robert Phillips3cd54322019-07-10 09:28:59 -0400369 if (SurfaceParameters::kProtectedCount == i) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400370 if (dContext->backend() != GrBackendApi::kVulkan) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400371 // Only the Vulkan backend respects the protected parameter
372 continue;
373 }
374#ifdef SK_VULKAN
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400375 const GrVkCaps* vkCaps = (const GrVkCaps*) dContext->priv().caps();
Robert Phillips3cd54322019-07-10 09:28:59 -0400376
377 // And, even then, only when it is a protected context
378 if (!vkCaps->supportsProtectedMemory()) {
379 continue;
380 }
381#endif
382 }
383
Robert Phillipsbe77a022018-04-03 17:17:05 -0400384 GrBackendTexture backend;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400385 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500386 if (!s) {
387 continue;
388 }
389
390 if (SurfaceParameters::kSampleCount == i) {
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400391 int supportedSampleCount = caps->getRenderTargetSampleCount(
Greg Daniel6fa62e22019-08-07 15:52:37 -0400392 params.sampleCount(), backend.getBackendFormat());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500393 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500394 // If changing the sample count won't result in a different
395 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400396 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400397 params.cleanUpBackEnd(dContext, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500398 continue;
399 }
400 }
401
Brian Salomon69100f02020-07-21 10:49:25 -0400402 if (SurfaceParameters::kMipMipCount == i && !caps->mipmapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400403 // If changing the mipmap setting won't result in a different surface characterization,
404 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400405 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400406 params.cleanUpBackEnd(dContext, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500407 continue;
408 }
409
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400410 if (SurfaceParameters::kFBO0Count == i && dContext->backend() != GrBackendApi::kOpenGL) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500411 // FBO0 only affects the surface characterization when using OpenGL
412 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400413 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500414 continue;
415 }
416
Adlai Holler7580ad42020-06-24 13:45:25 -0400417 REPORTER_ASSERT(reporter, !s->draw(ddl),
Robert Phillipse8fabb22018-02-04 14:33:21 -0500418 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400419
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400420 dContext->flushAndSubmit();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400421 gpu->testingOnly_flushGpuAndSync();
422 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400423 params.cleanUpBackEnd(dContext, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500424 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500425
426 // Next test the compatibility of resource cache parameters
427 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400428 const SurfaceParameters params(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400429 GrBackendTexture backend;
430
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400431 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500432
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400433 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500434
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400435 dContext->setResourceCacheLimit(maxResourceBytes/2);
Adlai Holler7580ad42020-06-24 13:45:25 -0400436 REPORTER_ASSERT(reporter, !s->draw(ddl));
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500437
Robert Phillips9e441ee2018-02-01 15:14:55 -0500438 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
439 // For now, DDLs are drawn once.
440#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500441 // resource limits >= those at characterization time are accepted
442 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400443 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500444 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500445
446 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400447 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500448 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500449
450 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400451 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500452 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
453#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400454
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400455 dContext->flushAndSubmit();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400456 gpu->testingOnly_flushGpuAndSync();
457 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400458 params.cleanUpBackEnd(dContext, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500459 }
460
Robert Phillipse8fabb22018-02-04 14:33:21 -0500461 // Test that the textureability of the DDL characterization can block a DDL draw
462 {
463 GrBackendTexture backend;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400464 SurfaceParameters params(dContext);
Robert Phillipsc046ff02019-07-01 10:34:03 -0400465 params.setShouldCreateMipMaps(false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500466 params.setTextureable(false);
467
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400468 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500469 if (s) {
Adlai Holler7580ad42020-06-24 13:45:25 -0400470 REPORTER_ASSERT(reporter, !s->draw(ddl)); // bc the DDL was made w/ textureability
Robert Phillipse8fabb22018-02-04 14:33:21 -0500471
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400472 dContext->flushAndSubmit();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400473 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500474 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400475 params.cleanUpBackEnd(dContext, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500476 }
477 }
478
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500479 // Make sure non-GPU-backed surfaces fail characterization
480 {
481 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
482
483 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
484 SkSurfaceCharacterization c;
485 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
486 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500487
488 // Exercise the createResized method
489 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400490 SurfaceParameters params(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400491 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500492
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400493 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500494 if (!s) {
495 return;
496 }
497
498 SkSurfaceCharacterization char0;
499 SkAssertResult(s->characterize(&char0));
500
501 // Too small
502 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
503 REPORTER_ASSERT(reporter, !char1.isValid());
504
505 // Too large
506 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
507 REPORTER_ASSERT(reporter, !char2.isValid());
508
509 // Just right
510 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
511 REPORTER_ASSERT(reporter, char3.isValid());
512 REPORTER_ASSERT(reporter, 32 == char3.width());
513 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400514
515 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400516 params.cleanUpBackEnd(dContext, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500517 }
Robert Phillipsa975ef32019-10-03 11:09:17 -0400518
519 // Exercise the createColorSpace method
520 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400521 SurfaceParameters params(dContext);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400522 GrBackendTexture backend;
523
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400524 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400525 if (!s) {
526 return;
527 }
528
529 SkSurfaceCharacterization char0;
530 SkAssertResult(s->characterize(&char0));
531
532 // The default params create an sRGB color space
533 REPORTER_ASSERT(reporter, char0.colorSpace()->isSRGB());
534 REPORTER_ASSERT(reporter, !char0.colorSpace()->gammaIsLinear());
535
536 {
537 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
538
539 SkSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS));
540 REPORTER_ASSERT(reporter, char1.isValid());
541 REPORTER_ASSERT(reporter, !char1.colorSpace()->isSRGB());
542 REPORTER_ASSERT(reporter, char1.colorSpace()->gammaIsLinear());
543 }
544
545 {
546 SkSurfaceCharacterization char2 = char0.createColorSpace(nullptr);
547 REPORTER_ASSERT(reporter, char2.isValid());
548 REPORTER_ASSERT(reporter, !char2.colorSpace());
549 }
550
551 {
552 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
553
554 SkSurfaceCharacterization invalid;
555 REPORTER_ASSERT(reporter, !invalid.isValid());
556 SkSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS));
557 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
558 }
559
560 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400561 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400562 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500563
564 // Exercise the createBackendFormat method
565 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400566 SurfaceParameters params(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500567 GrBackendTexture backend;
568
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400569 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500570 if (!s) {
571 return;
572 }
573
574 SkSurfaceCharacterization char0;
575 SkAssertResult(s->characterize(&char0));
576
577 // The default params create a renderable RGBA8 surface
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400578 auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
579 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500580 REPORTER_ASSERT(reporter, originalBackendFormat.isValid());
581 REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat);
582
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400583 auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType,
584 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500585
586 if (newBackendFormat.isValid()) {
587 SkSurfaceCharacterization char1 = char0.createBackendFormat(kRGB_565_SkColorType,
588 newBackendFormat);
589 REPORTER_ASSERT(reporter, char1.isValid());
590 REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat);
591
592 SkSurfaceCharacterization invalid;
593 REPORTER_ASSERT(reporter, !invalid.isValid());
594 auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType,
595 newBackendFormat);
596 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
597 }
598
599 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400600 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500601 }
602
603 // Exercise the createFBO0 method
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400604 if (dContext->backend() == GrBackendApi::kOpenGL) {
605 SurfaceParameters params(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500606 GrBackendTexture backend;
607
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400608 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500609 if (!s) {
610 return;
611 }
612
613 SkSurfaceCharacterization char0;
614 SkAssertResult(s->characterize(&char0));
615
616 // The default params create a non-FBO0 surface
617 REPORTER_ASSERT(reporter, !char0.usesGLFBO0());
618
619 {
620 SkSurfaceCharacterization char1 = char0.createFBO0(true);
621 REPORTER_ASSERT(reporter, char1.isValid());
622 REPORTER_ASSERT(reporter, char1.usesGLFBO0());
623 }
624
625 {
626 SkSurfaceCharacterization invalid;
627 REPORTER_ASSERT(reporter, !invalid.isValid());
628 SkSurfaceCharacterization stillInvalid = invalid.createFBO0(true);
629 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
630 }
631
632 s = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400633 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500634 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500635}
636
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500637#ifdef SK_GL
638
639// Test out the surface compatibility checks regarding FBO0-ness. This test constructs
640// two parallel arrays of characterizations and surfaces in the order:
641// FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA
642// and then tries all sixteen combinations to check the expected compatibility.
643// Note: this is a GL-only test
644DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CharacterizationFBO0nessTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400645 auto context = ctxInfo.directContext();
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500646 const GrCaps* caps = context->priv().caps();
647 sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
648 const size_t resourceCacheLimit = context->getResourceCacheLimit();
649
650 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
651
652 int availableSamples = caps->getRenderTargetSampleCount(4, format);
653 if (availableSamples <= 1) {
654 // This context doesn't support MSAA for RGBA8
655 return;
656 }
657
658 SkImageInfo ii = SkImageInfo::Make({ 128, 128 }, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
659
660 static constexpr int kStencilBits = 8;
661 static constexpr bool kNotMipMapped = false;
662 static constexpr bool kNotTextureable = false;
663 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
664
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500665 // Rows are characterizations and columns are surfaces
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500666 static const bool kExpectedCompatibility[4][4] = {
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500667 // FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA
668/* FBO0 & MSAA */ { true, false, false, false },
669/* FBO0 & not-MSAA */ { false, true, false, true },
670/* not-FBO0 & MSAA */ { false, false, true, false },
671/* not-FBO0 & not- */ { false, false, false, true }
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500672 };
673
674 SkSurfaceCharacterization characterizations[4];
675 sk_sp<SkSurface> surfaces[4];
676
677 int index = 0;
678 for (bool isFBO0 : { true, false }) {
679 for (int numSamples : { availableSamples, 1 }) {
680 characterizations[index] = proxy->createCharacterization(resourceCacheLimit,
681 ii, format, numSamples,
682 kTopLeft_GrSurfaceOrigin,
683 surfaceProps, kNotMipMapped,
684 isFBO0, kNotTextureable);
685 SkASSERT(characterizations[index].sampleCount() == numSamples);
686 SkASSERT(characterizations[index].usesGLFBO0() == isFBO0);
687
688 GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 };
689 GrBackendRenderTarget backendRT(128, 128, numSamples, kStencilBits, fboInfo);
690 SkAssertResult(backendRT.isValid());
691
692 surfaces[index] = SkSurface::MakeFromBackendRenderTarget(context, backendRT,
693 kTopLeft_GrSurfaceOrigin,
694 kRGBA_8888_SkColorType,
695 nullptr, &surfaceProps);
696 ++index;
697 }
698 }
699
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500700 for (int c = 0; c < 4; ++c) {
701 for (int s = 0; s < 4; ++s) {
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500702 REPORTER_ASSERT(reporter,
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500703 kExpectedCompatibility[c][s] ==
704 surfaces[s]->isCompatible(characterizations[c]));
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500705 }
706 }
707}
708#endif
709
Robert Phillips3cd54322019-07-10 09:28:59 -0400710DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400711 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400712
713 DDLSurfaceCharacterizationTestImpl(context, reporter);
714}
715
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500716// Test that a DDL created w/o textureability can be replayed into both a textureable and
717// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
718// textureable DDL cannot be played into a non-textureable destination but can be replayed
719// into a textureable destination.
720DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400721 auto context = ctxInfo.directContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500722 GrGpu* gpu = context->priv().getGpu();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500723
724 // Create a bitmap that we can readback into
725 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
726 kPremul_SkAlphaType);
727 SkBitmap bitmap;
728 bitmap.allocPixels(imageInfo);
729
730 for (bool textureability : { true, false }) {
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400731 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500732
Robert Phillipsc046ff02019-07-01 10:34:03 -0400733 // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have
734 // reusable DDLs, move this outside of the loop.
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500735 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400736 SurfaceParameters params(context);
Robert Phillipsc046ff02019-07-01 10:34:03 -0400737 params.setShouldCreateMipMaps(false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500738 params.setTextureable(false);
739
740 ddl = params.createDDL(context);
741 SkAssertResult(ddl);
742 }
743
744 // Then verify it can draw into either flavor of destination
Robert Phillips3cd54322019-07-10 09:28:59 -0400745 SurfaceParameters params(context);
Robert Phillipsc046ff02019-07-01 10:34:03 -0400746 params.setShouldCreateMipMaps(textureability);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500747 params.setTextureable(textureability);
748
749 GrBackendTexture backend;
750 sk_sp<SkSurface> s = params.make(context, &backend);
751 if (!s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500752 continue;
753 }
754
Adlai Holler7580ad42020-06-24 13:45:25 -0400755 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500756 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Greg Daniel0a2464f2020-05-14 15:45:44 -0400757 context->flushAndSubmit();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500758 gpu->testingOnly_flushGpuAndSync();
759 s = nullptr;
760 params.cleanUpBackEnd(context, backend);
761 }
762
763}
764
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400765static void test_make_render_target(skiatest::Reporter* reporter,
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400766 GrDirectContext* dContext,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400767 const SurfaceParameters& params) {
768 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400769 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400770
Robert Phillipsbe77a022018-04-03 17:17:05 -0400771 if (!c.isValid()) {
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400772 GrBackendTexture backend;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400773 sk_sp<SkSurface> tmp = params.make(dContext, &backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400774
775 // If we couldn't characterize the surface we shouldn't be able to create it either
776 REPORTER_ASSERT(reporter, !tmp);
777 if (tmp) {
778 tmp = nullptr;
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400779 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400780 }
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400781 return;
782 }
783 }
784
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400785 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400786 GrBackendTexture backend;
787
788 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400789 sk_sp<SkSurface> s = params.make(dContext, &backend);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400790 REPORTER_ASSERT(reporter, s);
791 if (!s) {
792 REPORTER_ASSERT(reporter, !c.isValid());
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400793 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400794 return;
795 }
796
797 REPORTER_ASSERT(reporter, c.isValid());
Robert Phillipsc046ff02019-07-01 10:34:03 -0400798 REPORTER_ASSERT(reporter, c.isCompatible(backend));
Robert Phillips9907e6e2019-06-25 14:47:04 -0400799 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400800 // Note that we're leaving 'backend' live here
801 }
802
803 // Make an SkSurface from scratch
804 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400805 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, c, SkBudgeted::kYes);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400806 REPORTER_ASSERT(reporter, s);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400807 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400808 }
809
Robert Phillips02dc0302019-07-02 17:58:27 -0400810 // Make an SkSurface that wraps the existing backend texture
811 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400812 sk_sp<SkSurface> s = SkSurface::MakeFromBackendTexture(dContext, c, backend);
Robert Phillips02dc0302019-07-02 17:58:27 -0400813 REPORTER_ASSERT(reporter, s);
814 REPORTER_ASSERT(reporter, s->isCompatible(c));
815 }
816
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400817 params.cleanUpBackEnd(dContext, backend);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400818}
819
820////////////////////////////////////////////////////////////////////////////////
821// This tests the SkSurface::MakeRenderTarget variants that take an SkSurfaceCharacterization.
822// In particular, the SkSurface, backendTexture and SkSurfaceCharacterization
823// should always be compatible.
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400824void DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400825 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
826
827 if (SurfaceParameters::kFBO0Count == i) {
828 // MakeRenderTarget doesn't support FBO0
Robert Phillipsbe77a022018-04-03 17:17:05 -0400829 continue;
830 }
831
Robert Phillips3cd54322019-07-10 09:28:59 -0400832 if (SurfaceParameters::kProtectedCount == i) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400833 if (dContext->backend() != GrBackendApi::kVulkan) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400834 // Only the Vulkan backend respects the protected parameter
835 continue;
836 }
837#ifdef SK_VULKAN
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400838 const GrVkCaps* vkCaps = (const GrVkCaps*) dContext->priv().caps();
Robert Phillips3cd54322019-07-10 09:28:59 -0400839
840 // And, even then, only when it is a protected context
841 if (!vkCaps->supportsProtectedMemory()) {
842 continue;
843 }
844#endif
845 }
846
847
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400848 SurfaceParameters params(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400849 params.modify(i);
850
Brian Salomon69100f02020-07-21 10:49:25 -0400851 if (!dContext->priv().caps()->mipmapSupport()) {
Brian Salomon4687bdd2019-05-09 16:28:04 -0400852 params.setShouldCreateMipMaps(false);
853 }
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400854
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400855 test_make_render_target(reporter, dContext, params);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400856 }
857}
858
Robert Phillips3cd54322019-07-10 09:28:59 -0400859DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400860 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400861
862 DDLMakeRenderTargetTestImpl(context, reporter);
863}
864
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400865////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500866static constexpr int kSize = 8;
867
868struct TextureReleaseChecker {
869 TextureReleaseChecker() : fReleaseCount(0) {}
870 int fReleaseCount;
871 static void Release(void* self) {
872 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
873 }
874};
875
876enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
877
878// This tests the ability to create and use wrapped textures in a DDL world
879DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400880 auto context = ctxInfo.directContext();
Robert Phillips9b16f812019-05-17 10:01:21 -0400881
Greg Danielc1ad77c2020-05-06 11:40:03 -0400882 GrBackendTexture backendTex;
883 CreateBackendTexture(context, &backendTex, kSize, kSize, kRGBA_8888_SkColorType,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400884 SkColors::kTransparent, GrMipmapped::kNo, GrRenderable::kNo, GrProtected::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500885 if (!backendTex.isValid()) {
886 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500887 }
Brian Salomonf7778972018-03-08 10:13:17 -0500888
Robert Phillips3cd54322019-07-10 09:28:59 -0400889 SurfaceParameters params(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400890 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500891
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500892 sk_sp<SkSurface> s = params.make(context, &backend);
Brian Salomonf7778972018-03-08 10:13:17 -0500893 if (!s) {
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400894 context->deleteBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500895 return;
896 }
897
898 SkSurfaceCharacterization c;
899 SkAssertResult(s->characterize(&c));
900
901 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
902
903 SkCanvas* canvas = recorder->getCanvas();
904 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400905 s = nullptr;
906 params.cleanUpBackEnd(context, backend);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400907 context->deleteBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500908 return;
909 }
910
911 GrContext* deferredContext = canvas->getGrContext();
912 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400913 s = nullptr;
914 params.cleanUpBackEnd(context, backend);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400915 context->deleteBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500916 return;
917 }
918
919 // Wrapped Backend Textures are not supported in DDL
Brian Salomonf7778972018-03-08 10:13:17 -0500920 TextureReleaseChecker releaseChecker;
Adlai Hollere34b2822020-07-29 12:50:56 -0400921 sk_sp<SkImage> image =
922 SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
Brian Salomonf7778972018-03-08 10:13:17 -0500923 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
924 TextureReleaseChecker::Release, &releaseChecker);
925 REPORTER_ASSERT(reporter, !image);
926
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400927 context->deleteBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400928
929 s = nullptr;
930 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500931}
932
Brian Salomon59ef8c32019-01-30 12:20:56 -0500933static sk_sp<SkPromiseImageTexture> dummy_fulfill_proc(void*) {
934 SkASSERT(0);
935 return nullptr;
936}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400937static void dummy_release_proc(void*) { SkASSERT(0); }
Brian Salomon59ef8c32019-01-30 12:20:56 -0500938static void dummy_done_proc(void*) {}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400939
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400940////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400941// Test out the behavior of an invalid DDLRecorder
942DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400943 auto context = ctxInfo.directContext();
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400944
945 {
946 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
947 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
948
949 SkSurfaceCharacterization characterization;
950 SkAssertResult(s->characterize(&characterization));
951
952 // never calling getCanvas means the backing surface is never allocated
953 SkDeferredDisplayListRecorder recorder(characterization);
954 }
955
956 {
957 SkSurfaceCharacterization invalid;
958
959 SkDeferredDisplayListRecorder recorder(invalid);
960
961 const SkSurfaceCharacterization c = recorder.characterization();
962 REPORTER_ASSERT(reporter, !c.isValid());
963 REPORTER_ASSERT(reporter, !recorder.getCanvas());
964 REPORTER_ASSERT(reporter, !recorder.detach());
965
Robert Phillips0a15cc62019-07-30 12:49:10 -0400966 GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
967 GrRenderable::kNo);
968 SkASSERT(format.isValid());
Greg Daniel60ea40c2019-02-12 13:38:44 -0500969
Brian Salomonf55e8d52019-01-30 17:28:20 -0500970 sk_sp<SkImage> image = recorder.makePromiseTexture(
Brian Salomon7e67dca2020-07-21 09:27:25 -0400971 format, 32, 32, GrMipmapped::kNo,
Brian Salomonf55e8d52019-01-30 17:28:20 -0500972 kTopLeft_GrSurfaceOrigin,
973 kRGBA_8888_SkColorType,
974 kPremul_SkAlphaType, nullptr,
975 dummy_fulfill_proc,
976 dummy_release_proc,
977 dummy_done_proc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500978 nullptr,
979 SkDeferredDisplayListRecorder::PromiseImageApiVersion::kNew);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400980 REPORTER_ASSERT(reporter, !image);
981 }
982
983}
984
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400985////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400986// Ensure that flushing while DDL recording doesn't cause a crash
987DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
Robert Phillipsb27b38b2020-07-10 16:23:47 -0400988 auto direct = ctxInfo.directContext();
Robert Phillips874b5352018-03-16 08:48:24 -0400989
990 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
Robert Phillipsb27b38b2020-07-10 16:23:47 -0400991 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(direct, SkBudgeted::kNo, ii);
Robert Phillips874b5352018-03-16 08:48:24 -0400992
993 SkSurfaceCharacterization characterization;
994 SkAssertResult(s->characterize(&characterization));
995
996 SkDeferredDisplayListRecorder recorder(characterization);
997 SkCanvas* canvas = recorder.getCanvas();
998
Robert Phillipsb27b38b2020-07-10 16:23:47 -0400999 // CONTEXT TODO: once getGrContext goes away this test should be deleted since this
1000 // situation won't be possible.
Greg Daniel0a2464f2020-05-14 15:45:44 -04001001 canvas->getGrContext()->flushAndSubmit();
Robert Phillips874b5352018-03-16 08:48:24 -04001002}
Greg Danielf2336e42018-01-23 16:38:14 -05001003
Robert Phillips6b6fcc72018-03-30 13:57:00 -04001004////////////////////////////////////////////////////////////////////////////////
Robert Phillipsee5fd132019-05-07 13:29:22 -04001005// Test that flushing a DDL via SkSurface::flush works
1006
1007struct FulfillInfo {
1008 sk_sp<SkPromiseImageTexture> fTex;
1009 bool fFulfilled = false;
1010 bool fReleased = false;
1011 bool fDone = false;
1012};
1013
1014static sk_sp<SkPromiseImageTexture> tracking_fulfill_proc(void* context) {
1015 FulfillInfo* info = (FulfillInfo*) context;
1016 info->fFulfilled = true;
1017 return info->fTex;
1018}
1019
1020static void tracking_release_proc(void* context) {
1021 FulfillInfo* info = (FulfillInfo*) context;
1022 info->fReleased = true;
1023}
1024
1025static void tracking_done_proc(void* context) {
1026 FulfillInfo* info = (FulfillInfo*) context;
1027 info->fDone = true;
1028}
1029
1030DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001031 auto context = ctxInfo.directContext();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001032
1033 SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1034 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1035
1036 SkSurfaceCharacterization characterization;
1037 SkAssertResult(s->characterize(&characterization));
1038
1039 GrBackendTexture backendTexture;
1040
Brian Salomon7e67dca2020-07-21 09:27:25 -04001041 if (!CreateBackendTexture(context, &backendTexture, ii, SkColors::kCyan, GrMipmapped::kNo,
Robert Phillips0efc01d2019-11-06 17:19:30 +00001042 GrRenderable::kNo)) {
Robert Phillipsee5fd132019-05-07 13:29:22 -04001043 REPORTER_ASSERT(reporter, false);
1044 return;
1045 }
1046
1047 FulfillInfo fulfillInfo;
1048 fulfillInfo.fTex = SkPromiseImageTexture::Make(backendTexture);
1049
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001050 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsee5fd132019-05-07 13:29:22 -04001051
1052 {
1053 SkDeferredDisplayListRecorder recorder(characterization);
1054
Robert Phillips0a15cc62019-07-30 12:49:10 -04001055 GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
1056 GrRenderable::kNo);
1057 SkASSERT(format.isValid());
Robert Phillipsee5fd132019-05-07 13:29:22 -04001058
1059 sk_sp<SkImage> promiseImage = recorder.makePromiseTexture(
Brian Salomon7e67dca2020-07-21 09:27:25 -04001060 format, 32, 32, GrMipmapped::kNo,
Robert Phillipsee5fd132019-05-07 13:29:22 -04001061 kTopLeft_GrSurfaceOrigin,
1062 kRGBA_8888_SkColorType,
1063 kPremul_SkAlphaType, nullptr,
1064 tracking_fulfill_proc,
1065 tracking_release_proc,
1066 tracking_done_proc,
1067 &fulfillInfo,
1068 SkDeferredDisplayListRecorder::PromiseImageApiVersion::kNew);
1069
1070 SkCanvas* canvas = recorder.getCanvas();
1071
1072 canvas->clear(SK_ColorRED);
1073 canvas->drawImage(promiseImage, 0, 0);
1074 ddl = recorder.detach();
1075 }
1076
Greg Daniel0a2464f2020-05-14 15:45:44 -04001077 context->flushAndSubmit();
Robert Phillips15c91422019-05-07 16:54:48 -04001078
Adlai Holler7580ad42020-06-24 13:45:25 -04001079 s->draw(ddl);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001080
1081 GrFlushInfo flushInfo;
Robert Phillips8e49a692019-05-07 15:57:25 -04001082 s->flush(SkSurface::BackendSurfaceAccess::kPresent, flushInfo);
Greg Daniel0a2464f2020-05-14 15:45:44 -04001083 context->submit();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001084
1085 REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled);
1086 REPORTER_ASSERT(reporter, fulfillInfo.fReleased);
1087
Robert Phillips8e49a692019-05-07 15:57:25 -04001088 if (GrBackendApi::kVulkan == context->backend() ||
1089 GrBackendApi::kMetal == context->backend()) {
Robert Phillips15c91422019-05-07 16:54:48 -04001090 // In order to receive the done callback with Vulkan we need to perform the equivalent
Robert Phillipsee5fd132019-05-07 13:29:22 -04001091 // of a glFinish
Greg Danielce9f0162020-06-30 13:42:46 -04001092 s->flush();
Greg Daniel0a2464f2020-05-14 15:45:44 -04001093 context->submit(true);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001094 }
1095
1096 REPORTER_ASSERT(reporter, fulfillInfo.fDone);
1097
1098 REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique());
1099 fulfillInfo.fTex.reset();
1100
Brian Salomon28a8f282019-10-24 20:07:39 -04001101 DeleteBackendTexture(context, backendTexture);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001102}
1103
1104////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -05001105// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
1106DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001107 auto context = ctxInfo.directContext();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001108
1109 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1110 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1111
1112 SkBitmap bitmap;
1113 bitmap.allocPixels(ii);
1114
1115 SkSurfaceCharacterization characterization;
1116 SkAssertResult(s->characterize(&characterization));
1117
1118 SkDeferredDisplayListRecorder recorder(characterization);
1119
1120 SkCanvas* canvas1 = recorder.getCanvas();
1121
1122 canvas1->clear(SK_ColorRED);
1123
1124 canvas1->save();
1125 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
1126
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001127 sk_sp<SkDeferredDisplayList> ddl1 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001128
1129 SkCanvas* canvas2 = recorder.getCanvas();
1130
1131 SkPaint p;
1132 p.setColor(SK_ColorGREEN);
1133 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
1134
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001135 sk_sp<SkDeferredDisplayList> ddl2 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001136
1137 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
1138 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
1139
1140 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
1141 // lazy proxy are all different between the two DDLs
1142 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
1143
Adlai Holler7580ad42020-06-24 13:45:25 -04001144 s->draw(ddl1);
1145 s->draw(ddl2);
Robert Phillipsf54883c2018-12-18 08:29:09 -05001146
1147 // Make sure the clipRect from DDL1 didn't percolate into DDL2
1148 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
1149 for (int y = 0; y < 32; ++y) {
1150 for (int x = 0; x < 32; ++x) {
1151 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
1152 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
1153 return; // we only really need to report the error once
1154 }
1155 }
1156 }
1157}
1158
John Rosascoa9b348f2019-11-08 13:18:15 -08001159#ifdef SK_GL
Robert Phillipsf54883c2018-12-18 08:29:09 -05001160////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -04001161// Check that the texture-specific flags (i.e., for external & rectangle textures) work
1162// for promise images. As such, this is a GL-only test.
1163DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001164 auto context = ctxInfo.directContext();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001165
1166 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1167 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1168
1169 SkSurfaceCharacterization characterization;
1170 SkAssertResult(s->characterize(&characterization));
1171
1172 SkDeferredDisplayListRecorder recorder(characterization);
1173
1174 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Brian Salomon7e67dca2020-07-21 09:27:25 -04001175 for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
Greg Daniel09c94002018-06-08 22:11:51 +00001176 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001177
Brian Salomonf55e8d52019-01-30 17:28:20 -05001178 sk_sp<SkImage> image = recorder.makePromiseTexture(
1179 format, 32, 32, mipMapped,
1180 kTopLeft_GrSurfaceOrigin,
1181 kRGBA_8888_SkColorType,
1182 kPremul_SkAlphaType, nullptr,
1183 dummy_fulfill_proc,
1184 dummy_release_proc,
1185 dummy_done_proc,
Brian Salomon0cc57542019-03-08 13:28:46 -05001186 nullptr,
1187 SkDeferredDisplayListRecorder::PromiseImageApiVersion::kNew);
Brian Salomon7e67dca2020-07-21 09:27:25 -04001188 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipmapped::kYes) {
Greg Daniel09c94002018-06-08 22:11:51 +00001189 REPORTER_ASSERT(reporter, !image);
1190 continue;
1191 }
1192 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001193
Jim Van Verth21bd60d2018-10-12 15:00:20 -04001194 GrTextureProxy* backingProxy = ((SkImage_GpuBase*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001195
Brian Salomon8c82a872020-07-21 12:09:58 -04001196 REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipMapped);
Greg Daniel09c94002018-06-08 22:11:51 +00001197 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001198 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001199 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001200 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001201 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001202 }
1203 }
Robert Phillipsbe77a022018-04-03 17:17:05 -04001204}
John Rosascoa9b348f2019-11-08 13:18:15 -08001205#endif // SK_GL
Robert Phillipsbe77a022018-04-03 17:17:05 -04001206
1207////////////////////////////////////////////////////////////////////////////////
Robert Phillips646f6372018-09-25 09:31:10 -04001208// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -04001209DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001210 auto context = ctxInfo.directContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -04001211
1212 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1213 SkColorType colorType = static_cast<SkColorType>(ct);
1214
Robert Phillips3cd54322019-07-10 09:28:59 -04001215 SurfaceParameters params(context);
Greg Daniel60ea40c2019-02-12 13:38:44 -05001216 params.setColorType(colorType);
1217 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001218
Brian Salomon69100f02020-07-21 10:49:25 -04001219 if (!context->priv().caps()->mipmapSupport()) {
Brian Salomon4687bdd2019-05-09 16:28:04 -04001220 params.setShouldCreateMipMaps(false);
1221 }
Greg Daniel60ea40c2019-02-12 13:38:44 -05001222
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001223 test_make_render_target(reporter, context, params);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001224 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001225
1226}