blob: c8f0728e79e8315dc159b7f13b572d3f4ed69231 [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
Brian Salomon59ef8c32019-01-30 12:20:56 -05008#include <initializer_list>
9#include <memory>
10#include <utility>
Greg Danielf2336e42018-01-23 16:38:14 -050011#include "GrBackendSurface.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040012#include "GrCaps.h"
13#include "GrContext.h"
14#include "GrContextFactory.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040015#include "GrContextPriv.h"
Greg Danielf2336e42018-01-23 16:38:14 -050016#include "GrGpu.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040017#include "GrRenderTargetContext.h"
18#include "GrRenderTargetProxy.h"
19#include "GrTextureProxy.h"
Robert Phillipsabf7b762018-03-21 12:13:37 -040020#include "GrTextureProxyPriv.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040021#include "GrTypes.h"
22#include "GrTypesPriv.h"
23#include "SkBitmap.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050024#include "SkCanvas.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040025#include "SkColorSpace.h"
26#include "SkDeferredDisplayList.h"
Robert Phillipsf54883c2018-12-18 08:29:09 -050027#include "SkDeferredDisplayListPriv.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050028#include "SkDeferredDisplayListRecorder.h"
29#include "SkGpuDevice.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040030#include "SkImage.h"
31#include "SkImageInfo.h"
Robert Phillipsabf7b762018-03-21 12:13:37 -040032#include "SkImage_Gpu.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040033#include "SkPaint.h"
Brian Salomon59ef8c32019-01-30 12:20:56 -050034#include "SkPromiseImageTexture.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040035#include "SkRect.h"
36#include "SkRefCnt.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050037#include "SkSurface.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050038#include "SkSurfaceCharacterization.h"
39#include "SkSurfaceProps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040040#include "SkSurface_Gpu.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050041#include "Test.h"
Robert Phillipsbe77a022018-04-03 17:17:05 -040042#include "gl/GrGLCaps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040043#include "gl/GrGLDefines.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040044#include "gl/GrGLTypes.h"
Robert Phillipsfc711a22018-02-13 17:03:00 -050045#ifdef SK_VULKAN
Greg Daniel54bfb182018-11-20 17:12:36 -050046#include <vulkan/vulkan_core.h>
Robert Phillipsfc711a22018-02-13 17:03:00 -050047#endif
48
Robert Phillipsbe77a022018-04-03 17:17:05 -040049// Try to create a backend format from the provided colorType and config. Return an invalid
50// backend format if the combination is infeasible.
51static GrBackendFormat create_backend_format(GrContext* context,
Brian Osman37f99882018-08-09 10:26:57 -040052 SkColorType ct,
Robert Phillipsbe77a022018-04-03 17:17:05 -040053 GrPixelConfig config) {
Robert Phillips9da87e02019-02-04 13:26:26 -050054 const GrCaps* caps = context->priv().caps();
Robert Phillipsfc711a22018-02-13 17:03:00 -050055
Robert Phillips4217ea72019-01-30 13:08:28 -050056 switch (context->backend()) {
Robert Phillipsc1bee132019-02-06 16:04:34 -050057#ifdef SK_METAL
58 case GrBackendApi::kMetal:
59 return caps->getBackendFormatFromColorType(ct);
60#endif
Greg Danielbdf12ad2018-10-12 09:31:11 -040061 case GrBackendApi::kOpenGL: {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040062 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(caps);
Robert Phillipsbe77a022018-04-03 17:17:05 -040063 GrGLStandard standard = glCaps->standard();
64
65 switch (ct) {
66 case kUnknown_SkColorType:
67 return GrBackendFormat();
68 case kAlpha_8_SkColorType:
69 if (kAlpha_8_as_Alpha_GrPixelConfig == config) {
70 return GrBackendFormat::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D);
71 } else if (kAlpha_8_GrPixelConfig == config ||
72 kAlpha_8_as_Red_GrPixelConfig == config) {
73 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
74 }
75 break;
76 case kRGB_565_SkColorType:
77 if (kRGB_565_GrPixelConfig == config) {
78 return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D);
79 }
80 break;
81 case kARGB_4444_SkColorType:
82 if (kRGBA_4444_GrPixelConfig == config) {
83 return GrBackendFormat::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D);
84 }
85 break;
86 case kRGBA_8888_SkColorType:
87 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -040088 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
Robert Phillipsbe77a022018-04-03 17:17:05 -040089 }
90 break;
91 case kRGB_888x_SkColorType:
92 if (kRGB_888_GrPixelConfig == config) {
93 return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D);
94 }
95 break;
96 case kBGRA_8888_SkColorType:
97 if (kBGRA_8888_GrPixelConfig == config) {
98 if (kGL_GrGLStandard == standard) {
99 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
100 } else if (kGLES_GrGLStandard == standard) {
101 return GrBackendFormat::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D);
102 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400103 }
104 break;
105 case kRGBA_1010102_SkColorType:
106 if (kRGBA_1010102_GrPixelConfig == config) {
107 return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D);
108 }
109 break;
110 case kRGB_101010x_SkColorType:
111 return GrBackendFormat();
112 case kGray_8_SkColorType:
113 if (kGray_8_as_Lum_GrPixelConfig == config) {
114 return GrBackendFormat::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D);
115 } else if (kGray_8_GrPixelConfig == config ||
116 kGray_8_as_Red_GrPixelConfig == config) {
117 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
118 }
119 break;
120 case kRGBA_F16_SkColorType:
121 if (kRGBA_half_GrPixelConfig == config) {
122 return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D);
123 }
124 break;
Mike Klein37854712018-06-26 11:43:06 -0400125 case kRGBA_F32_SkColorType:
126 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500127 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400128 }
129 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500130#ifdef SK_VULKAN
Greg Danielbdf12ad2018-10-12 09:31:11 -0400131 case GrBackendApi::kVulkan:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400132 switch (ct) {
133 case kUnknown_SkColorType:
134 return GrBackendFormat();
135 case kAlpha_8_SkColorType:
136 // TODO: what about kAlpha_8_GrPixelConfig and kAlpha_8_as_Alpha_GrPixelConfig
137 if (kAlpha_8_as_Red_GrPixelConfig == config) {
138 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
139 }
140 break;
141 case kRGB_565_SkColorType:
142 if (kRGB_565_GrPixelConfig == config) {
143 return GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16);
144 }
145 break;
146 case kARGB_4444_SkColorType:
147 if (kRGBA_4444_GrPixelConfig == config) {
148 return GrBackendFormat::MakeVk(VK_FORMAT_B4G4R4A4_UNORM_PACK16);
149 }
150 break;
151 case kRGBA_8888_SkColorType:
152 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400153 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400154 }
155 break;
156 case kRGB_888x_SkColorType:
157 if (kRGB_888_GrPixelConfig == config) {
158 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM);
159 }
160 break;
161 case kBGRA_8888_SkColorType:
162 if (kBGRA_8888_GrPixelConfig == config) {
163 return GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400164 }
165 break;
166 case kRGBA_1010102_SkColorType:
167 if (kRGBA_1010102_GrPixelConfig == config) {
168 return GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
169 }
170 break;
171 case kRGB_101010x_SkColorType:
172 return GrBackendFormat();
173 case kGray_8_SkColorType:
174 // TODO: what about kAlpha_8_GrPixelConfig and kGray_8_as_Lum_GrPixelConfig?
175 if (kGray_8_as_Red_GrPixelConfig == config) {
176 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
177 }
178 break;
179 case kRGBA_F16_SkColorType:
180 if (kRGBA_half_GrPixelConfig == config) {
181 return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
182 }
183 break;
Mike Klein37854712018-06-26 11:43:06 -0400184 case kRGBA_F32_SkColorType:
185 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500186 }
187 break;
188#endif
Greg Danielbdf12ad2018-10-12 09:31:11 -0400189 case GrBackendApi::kMock:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400190 switch (ct) {
191 case kUnknown_SkColorType:
192 return GrBackendFormat();
193 case kAlpha_8_SkColorType:
194 if (kAlpha_8_GrPixelConfig == config ||
195 kAlpha_8_as_Alpha_GrPixelConfig == config ||
196 kAlpha_8_as_Red_GrPixelConfig == config) {
197 return GrBackendFormat::MakeMock(config);
198 }
199 break;
200 case kRGB_565_SkColorType:
201 if (kRGB_565_GrPixelConfig == config) {
202 return GrBackendFormat::MakeMock(config);
203 }
204 break;
205 case kARGB_4444_SkColorType:
206 if (kRGBA_4444_GrPixelConfig == config) {
207 return GrBackendFormat::MakeMock(config);
208 }
209 break;
210 case kRGBA_8888_SkColorType:
211 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400212 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400213 }
214 break;
215 case kRGB_888x_SkColorType:
216 if (kRGB_888_GrPixelConfig == config) {
217 return GrBackendFormat::MakeMock(config);
218 }
219 break;
220 case kBGRA_8888_SkColorType:
221 if (kBGRA_8888_GrPixelConfig == config) {
222 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400223 }
224 break;
225 case kRGBA_1010102_SkColorType:
226 if (kRGBA_1010102_GrPixelConfig == config) {
227 return GrBackendFormat::MakeMock(config);
228 }
229 break;
230 case kRGB_101010x_SkColorType:
231 return GrBackendFormat();
232 case kGray_8_SkColorType:
233 if (kGray_8_GrPixelConfig == config ||
234 kGray_8_as_Lum_GrPixelConfig == config ||
235 kGray_8_as_Red_GrPixelConfig == config) {
236 return GrBackendFormat::MakeMock(config);
237 }
238 break;
239 case kRGBA_F16_SkColorType:
240 if (kRGBA_half_GrPixelConfig == config) {
241 return GrBackendFormat::MakeMock(config);
242 }
243 break;
Mike Klein37854712018-06-26 11:43:06 -0400244 case kRGBA_F32_SkColorType:
245 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500246 }
247 break;
248 default:
249 return GrBackendFormat(); // return an invalid format
250 }
251
252 return GrBackendFormat(); // return an invalid format
253}
254
255
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500256class SurfaceParameters {
257public:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500258 static const int kNumParams = 11;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500259 static const int kSampleCount = 5;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500260 static const int kMipMipCount = 8;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500261 static const int kFBO0Count = 9;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500262
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500263 SurfaceParameters(GrBackendApi backend)
264 : fBackend(backend)
265 , fWidth(64)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500266 , fHeight(64)
267 , fOrigin(kTopLeft_GrSurfaceOrigin)
268 , fColorType(kRGBA_8888_SkColorType)
Brian Osman37f99882018-08-09 10:26:57 -0400269 , fConfig(kRGBA_8888_GrPixelConfig)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500270 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -0500271 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -0500272 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500273 , fShouldCreateMipMaps(true)
274 , fUsesGLFBO0(false)
275 , fIsTextureable(true) {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500276 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500277
278 int sampleCount() const { return fSampleCount; }
279
Robert Phillipsbe77a022018-04-03 17:17:05 -0400280 void setColorType(SkColorType ct) { fColorType = ct; }
281 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
282 void setConfig(GrPixelConfig config) { fConfig = config; }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500283 void setTextureable(bool isTextureable) { fIsTextureable = isTextureable; }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400284
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500285 // Modify the SurfaceParameters in just one way
286 void modify(int i) {
287 switch (i) {
288 case 0:
289 fWidth = 63;
290 break;
291 case 1:
292 fHeight = 63;
293 break;
294 case 2:
295 fOrigin = kBottomLeft_GrSurfaceOrigin;
296 break;
297 case 3:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400298 // The color type and config need to be changed together.
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500299 fColorType = kRGBA_F16_SkColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400300 fConfig = kRGBA_half_GrPixelConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500301 break;
302 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400303 // This just needs to be a colorSpace different from that returned by MakeSRGB().
304 // In this case we just change the gamut.
Brian Osman82ebe042019-01-04 17:03:00 -0500305 fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500306 break;
307 case kSampleCount:
308 fSampleCount = 4;
309 break;
310 case 6:
311 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
312 break;
313 case 7:
314 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
315 kUnknown_SkPixelGeometry);
316 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500317 case 8:
318 fShouldCreateMipMaps = false;
319 break;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500320 case 9:
321 if (GrBackendApi::kOpenGL == fBackend) {
322 fUsesGLFBO0 = true;
323 fIsTextureable = false;
324 }
325 break;
326 case 10:
327 fIsTextureable = false;
328 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500329 }
330 }
331
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400332 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500333 int maxResourceCount;
334 size_t maxResourceBytes;
335 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
336
337 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
338 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
339 kPremul_SkAlphaType, fColorSpace);
340
Brian Osman37f99882018-08-09 10:26:57 -0400341 GrBackendFormat backendFormat = create_backend_format(context, fColorType, fConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400342 if (!backendFormat.isValid()) {
343 return SkSurfaceCharacterization();
344 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500345
346 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
347 maxResourceBytes, ii, backendFormat, fSampleCount,
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500348 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
349 fUsesGLFBO0, fIsTextureable);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400350 return c;
351 }
352
353 // Create a DDL whose characterization captures the current settings
354 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
355 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500356 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500357
358 SkDeferredDisplayListRecorder r(c);
359 SkCanvas* canvas = r.getCanvas();
360 if (!canvas) {
361 return nullptr;
362 }
363
364 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
365 return r.detach();
366 }
367
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500368 // Create the surface with the current set of parameters
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500369 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend) const {
Robert Phillips9da87e02019-02-04 13:26:26 -0500370 GrGpu* gpu = context->priv().getGpu();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500371
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500372 GrMipMapped mipmapped = !fIsTextureable
Robert Phillipsbe77a022018-04-03 17:17:05 -0400373 ? GrMipMapped::kNo
374 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500375
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500376 if (fUsesGLFBO0) {
377 if (GrBackendApi::kOpenGL != context->backend()) {
378 return nullptr;
379 }
380
381 GrGLFramebufferInfo fboInfo;
382 fboInfo.fFBOID = 0;
383 fboInfo.fFormat = GR_GL_RGBA8;
384 static constexpr int kStencilBits = 8;
385 GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo);
386 backendRT.setPixelConfig(fConfig);
387
388 if (!backendRT.isValid()) {
389 return nullptr;
390 }
391
392 return SkSurface::MakeFromBackendRenderTarget(context, backendRT, fOrigin,
393 fColorType, fColorSpace, &fSurfaceProps);
394 }
395
Robert Phillipse8fabb22018-02-04 14:33:21 -0500396 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillips646f6372018-09-25 09:31:10 -0400397 fColorType, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500398 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
399 return nullptr;
400 }
401
Robert Phillipsbe77a022018-04-03 17:17:05 -0400402 sk_sp<SkSurface> surface;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500403 if (!fIsTextureable) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400404 // Create a surface w/ the current parameters but make it non-textureable
405 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
406 context, *backend, fOrigin, fSampleCount, fColorType,
407 fColorSpace, &fSurfaceProps);
408 } else {
409 surface = SkSurface::MakeFromBackendTexture(
410 context, *backend, fOrigin, fSampleCount, fColorType,
411 fColorSpace, &fSurfaceProps);
412 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500413
414 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500415 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500416 return nullptr;
417 }
418
419 return surface;
420 }
421
Brian Salomon26102cb2018-03-09 09:33:19 -0500422 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500423 if (!backend.isValid()) {
424 return;
425 }
426
Robert Phillips9da87e02019-02-04 13:26:26 -0500427 GrGpu* gpu = context->priv().getGpu();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500428
429 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500430 }
431
432private:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500433 GrBackendApi fBackend;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500434 int fWidth;
435 int fHeight;
436 GrSurfaceOrigin fOrigin;
437 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400438 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500439 sk_sp<SkColorSpace> fColorSpace;
440 int fSampleCount;
441 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500442 bool fShouldCreateMipMaps;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500443 bool fUsesGLFBO0;
444 bool fIsTextureable;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500445};
446
Robert Phillipsc1267c62018-04-04 11:12:39 -0400447// Test out operator== && operator!=
448DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
449 GrContext* context = ctxInfo.grContext();
450
451 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500452 SurfaceParameters params1(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400453 params1.modify(i);
454
455 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
456 if (!char1.isValid()) {
457 continue; // can happen on some platforms (ChromeOS)
458 }
459
460 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500461 SurfaceParameters params2(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400462 params2.modify(j);
463
464 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
465 if (!char2.isValid()) {
466 continue; // can happen on some platforms (ChromeOS)
467 }
468
469 if (i == j) {
470 REPORTER_ASSERT(reporter, char1 == char2);
471 } else {
472 REPORTER_ASSERT(reporter, char1 != char2);
473 }
474
475 }
476 }
477
478 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500479 SurfaceParameters params(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400480
481 SkSurfaceCharacterization valid = params.createCharacterization(context);
482 SkASSERT(valid.isValid());
483
484 SkSurfaceCharacterization inval1, inval2;
485 SkASSERT(!inval1.isValid() && !inval2.isValid());
486
487 REPORTER_ASSERT(reporter, inval1 != inval2);
488 REPORTER_ASSERT(reporter, valid != inval1);
489 REPORTER_ASSERT(reporter, inval1 != valid);
490 }
491}
492
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400493////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500494// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400495DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500496 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500497 GrGpu* gpu = context->priv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500498
Robert Phillips9e441ee2018-02-01 15:14:55 -0500499 // Create a bitmap that we can readback into
500 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
501 kPremul_SkAlphaType);
502 SkBitmap bitmap;
503 bitmap.allocPixels(imageInfo);
504
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500505 std::unique_ptr<SkDeferredDisplayList> ddl;
506
507 // First, create a DDL using the stock SkSurface parameters
508 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500509 SurfaceParameters params(context->backend());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500510
Robert Phillipse8fabb22018-02-04 14:33:21 -0500511 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500512 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500513
514 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400515 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500516 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500517 if (!s) {
518 return;
519 }
520
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500521 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500522 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400523 context->flush();
524 gpu->testingOnly_flushGpuAndSync();
525 s = nullptr;
526 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500527 }
528
529 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
530 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500531 SurfaceParameters params(context->backend());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500532 params.modify(i);
533
Robert Phillipsbe77a022018-04-03 17:17:05 -0400534 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500535 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500536 if (!s) {
537 continue;
538 }
539
540 if (SurfaceParameters::kSampleCount == i) {
541 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
542
Robert Phillips9da87e02019-02-04 13:26:26 -0500543 int supportedSampleCount = context->priv().caps()->getRenderTargetSampleCount(
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400544 params.sampleCount(),
545 gpuSurf->getDevice()
546 ->accessRenderTargetContext()
547 ->asRenderTargetProxy()
548 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500549 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500550 // If changing the sample count won't result in a different
551 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400552 s = nullptr;
553 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500554 continue;
555 }
556 }
557
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400558 if (SurfaceParameters::kMipMipCount == i &&
Robert Phillips9da87e02019-02-04 13:26:26 -0500559 !context->priv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400560 // If changing the mipmap setting won't result in a different surface characterization,
561 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400562 s = nullptr;
563 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500564 continue;
565 }
566
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500567 if (SurfaceParameters::kFBO0Count == i && context->backend() != GrBackendApi::kOpenGL) {
568 // FBO0 only affects the surface characterization when using OpenGL
569 s = nullptr;
570 params.cleanUpBackEnd(context, backend);
571 continue;
572 }
573
Robert Phillipse8fabb22018-02-04 14:33:21 -0500574 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
575 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400576
577 context->flush();
578 gpu->testingOnly_flushGpuAndSync();
579 s = nullptr;
580 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500581 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500582
583 // Next test the compatibility of resource cache parameters
584 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500585 const SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400586 GrBackendTexture backend;
587
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500588 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500589
590 int maxResourceCount;
591 size_t maxResourceBytes;
592 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
593
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500594 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
595 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
596
Robert Phillips9e441ee2018-02-01 15:14:55 -0500597 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
598 // For now, DDLs are drawn once.
599#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500600 // resource limits >= those at characterization time are accepted
601 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
602 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500603 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500604
605 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
606 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500607 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500608
609 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
610 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500611 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
612#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400613
614 context->flush();
615 gpu->testingOnly_flushGpuAndSync();
616 s = nullptr;
617 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500618 }
619
Robert Phillipse8fabb22018-02-04 14:33:21 -0500620 // Test that the textureability of the DDL characterization can block a DDL draw
621 {
622 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500623 SurfaceParameters params(context->backend());
624 params.setTextureable(false);
625
626 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500627 if (s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500628 REPORTER_ASSERT(reporter, !s->draw(ddl.get())); // bc the DDL was made w/ textureability
Robert Phillipse8fabb22018-02-04 14:33:21 -0500629
Robert Phillipsbe77a022018-04-03 17:17:05 -0400630 context->flush();
631 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500632 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500633 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500634 }
635 }
636
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500637 // Make sure non-GPU-backed surfaces fail characterization
638 {
639 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
640
641 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
642 SkSurfaceCharacterization c;
643 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
644 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500645
646 // Exercise the createResized method
647 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500648 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400649 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500650
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500651 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500652 if (!s) {
653 return;
654 }
655
656 SkSurfaceCharacterization char0;
657 SkAssertResult(s->characterize(&char0));
658
659 // Too small
660 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
661 REPORTER_ASSERT(reporter, !char1.isValid());
662
663 // Too large
664 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
665 REPORTER_ASSERT(reporter, !char2.isValid());
666
667 // Just right
668 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
669 REPORTER_ASSERT(reporter, char3.isValid());
670 REPORTER_ASSERT(reporter, 32 == char3.width());
671 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400672
673 s = nullptr;
674 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500675 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500676}
677
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500678// Test that a DDL created w/o textureability can be replayed into both a textureable and
679// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
680// textureable DDL cannot be played into a non-textureable destination but can be replayed
681// into a textureable destination.
682DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) {
683 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500684 GrGpu* gpu = context->priv().getGpu();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500685
686 // Create a bitmap that we can readback into
687 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
688 kPremul_SkAlphaType);
689 SkBitmap bitmap;
690 bitmap.allocPixels(imageInfo);
691
692 for (bool textureability : { true, false }) {
693 std::unique_ptr<SkDeferredDisplayList> ddl;
694
695 // First, create a DDL w/o textureability. TODO: once we have reusable DDLs, move this
696 // outside of the loop.
697 {
698 SurfaceParameters params(context->backend());
699 params.setTextureable(false);
700
701 ddl = params.createDDL(context);
702 SkAssertResult(ddl);
703 }
704
705 // Then verify it can draw into either flavor of destination
706 SurfaceParameters params(context->backend());
707 params.setTextureable(textureability);
708
709 GrBackendTexture backend;
710 sk_sp<SkSurface> s = params.make(context, &backend);
711 if (!s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500712 continue;
713 }
714
715 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
716 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
717 context->flush();
718 gpu->testingOnly_flushGpuAndSync();
719 s = nullptr;
720 params.cleanUpBackEnd(context, backend);
721 }
722
723}
724
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400725////////////////////////////////////////////////////////////////////////////////
726// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
727// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400728DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400729 GrContext* context = ctxInfo.grContext();
730
731 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500732 SurfaceParameters params(context->backend());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400733 params.modify(i);
734
735 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400736 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400737
Robert Phillipsbe77a022018-04-03 17:17:05 -0400738 if (!c.isValid()) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500739 sk_sp<SkSurface> tmp = params.make(context, &backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400740
741 // If we couldn't characterize the surface we shouldn't be able to create it either
742 REPORTER_ASSERT(reporter, !tmp);
743 if (tmp) {
744 tmp = nullptr;
745 params.cleanUpBackEnd(context, backend);
746 }
747 continue;
748 }
749
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500750 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400751 if (!s) {
752 REPORTER_ASSERT(reporter, !c.isValid());
753 continue;
754 }
755
756 REPORTER_ASSERT(reporter, c.isValid());
757
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500758 if (SurfaceParameters::kFBO0Count == i) {
759 // MakeRenderTarget doesn't support FBO0
760 params.cleanUpBackEnd(context, backend);
761 continue;
762 }
763
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400764 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
765 REPORTER_ASSERT(reporter, s);
766
767 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
768 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400769
770 s = nullptr;
771 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400772 }
773}
774
775////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500776static constexpr int kSize = 8;
777
778struct TextureReleaseChecker {
779 TextureReleaseChecker() : fReleaseCount(0) {}
780 int fReleaseCount;
781 static void Release(void* self) {
782 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
783 }
784};
785
786enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
787
788// This tests the ability to create and use wrapped textures in a DDL world
789DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
790 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500791 GrGpu* gpu = context->priv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500792 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400793 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500794 if (!backendTex.isValid()) {
795 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500796 }
Brian Salomonf7778972018-03-08 10:13:17 -0500797
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500798 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400799 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500800
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500801 sk_sp<SkSurface> s = params.make(context, &backend);
Brian Salomonf7778972018-03-08 10:13:17 -0500802 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500803 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500804 return;
805 }
806
807 SkSurfaceCharacterization c;
808 SkAssertResult(s->characterize(&c));
809
810 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
811
812 SkCanvas* canvas = recorder->getCanvas();
813 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400814 s = nullptr;
815 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500816 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500817 return;
818 }
819
820 GrContext* deferredContext = canvas->getGrContext();
821 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400822 s = nullptr;
823 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500824 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500825 return;
826 }
827
828 // Wrapped Backend Textures are not supported in DDL
829 sk_sp<SkImage> image =
830 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
831 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
832 REPORTER_ASSERT(reporter, !image);
833
834 TextureReleaseChecker releaseChecker;
835 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
836 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
837 TextureReleaseChecker::Release, &releaseChecker);
838 REPORTER_ASSERT(reporter, !image);
839
Brian Salomon26102cb2018-03-09 09:33:19 -0500840 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400841
842 s = nullptr;
843 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500844}
845
Brian Salomon59ef8c32019-01-30 12:20:56 -0500846static sk_sp<SkPromiseImageTexture> dummy_fulfill_proc(void*) {
847 SkASSERT(0);
848 return nullptr;
849}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400850static void dummy_release_proc(void*) { SkASSERT(0); }
Brian Salomon59ef8c32019-01-30 12:20:56 -0500851static void dummy_done_proc(void*) {}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400852
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400853////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400854// Test out the behavior of an invalid DDLRecorder
855DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
856 GrContext* context = ctxInfo.grContext();
857
858 {
859 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
860 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
861
862 SkSurfaceCharacterization characterization;
863 SkAssertResult(s->characterize(&characterization));
864
865 // never calling getCanvas means the backing surface is never allocated
866 SkDeferredDisplayListRecorder recorder(characterization);
867 }
868
869 {
870 SkSurfaceCharacterization invalid;
871
872 SkDeferredDisplayListRecorder recorder(invalid);
873
874 const SkSurfaceCharacterization c = recorder.characterization();
875 REPORTER_ASSERT(reporter, !c.isValid());
876 REPORTER_ASSERT(reporter, !recorder.getCanvas());
877 REPORTER_ASSERT(reporter, !recorder.detach());
878
Robert Phillipsbe77a022018-04-03 17:17:05 -0400879 GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType,
Brian Osman37f99882018-08-09 10:26:57 -0400880 kRGBA_8888_GrPixelConfig);
Brian Salomonf55e8d52019-01-30 17:28:20 -0500881 sk_sp<SkImage> image = recorder.makePromiseTexture(
882 format, 32, 32, GrMipMapped::kNo,
883 kTopLeft_GrSurfaceOrigin,
884 kRGBA_8888_SkColorType,
885 kPremul_SkAlphaType, nullptr,
886 dummy_fulfill_proc,
887 dummy_release_proc,
888 dummy_done_proc,
889 nullptr,
890 SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400891 REPORTER_ASSERT(reporter, !image);
892 }
893
894}
895
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400896////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400897// Ensure that flushing while DDL recording doesn't cause a crash
898DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
899 GrContext* context = ctxInfo.grContext();
900
901 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
902 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
903
904 SkSurfaceCharacterization characterization;
905 SkAssertResult(s->characterize(&characterization));
906
907 SkDeferredDisplayListRecorder recorder(characterization);
908 SkCanvas* canvas = recorder.getCanvas();
909
910 canvas->flush();
911 canvas->getGrContext()->flush();
912}
Greg Danielf2336e42018-01-23 16:38:14 -0500913
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400914////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -0500915// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
916DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
917 GrContext* context = ctxInfo.grContext();
918
919 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
920 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
921
922 SkBitmap bitmap;
923 bitmap.allocPixels(ii);
924
925 SkSurfaceCharacterization characterization;
926 SkAssertResult(s->characterize(&characterization));
927
928 SkDeferredDisplayListRecorder recorder(characterization);
929
930 SkCanvas* canvas1 = recorder.getCanvas();
931
932 canvas1->clear(SK_ColorRED);
933
934 canvas1->save();
935 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
936
937 std::unique_ptr<SkDeferredDisplayList> ddl1 = recorder.detach();
938
939 SkCanvas* canvas2 = recorder.getCanvas();
940
941 SkPaint p;
942 p.setColor(SK_ColorGREEN);
943 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
944
945 std::unique_ptr<SkDeferredDisplayList> ddl2 = recorder.detach();
946
947 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
948 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
949
950 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
951 // lazy proxy are all different between the two DDLs
952 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
953
954 s->draw(ddl1.get());
955 s->draw(ddl2.get());
956
957 // Make sure the clipRect from DDL1 didn't percolate into DDL2
958 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
959 for (int y = 0; y < 32; ++y) {
960 for (int x = 0; x < 32; ++x) {
961 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
962 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
963 return; // we only really need to report the error once
964 }
965 }
966 }
967}
968
969////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -0400970// Check that the texture-specific flags (i.e., for external & rectangle textures) work
971// for promise images. As such, this is a GL-only test.
972DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
973 GrContext* context = ctxInfo.grContext();
974
975 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
976 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
977
978 SkSurfaceCharacterization characterization;
979 SkAssertResult(s->characterize(&characterization));
980
981 SkDeferredDisplayListRecorder recorder(characterization);
982
983 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Greg Daniel09c94002018-06-08 22:11:51 +0000984 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
985 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400986
Brian Salomonf55e8d52019-01-30 17:28:20 -0500987 sk_sp<SkImage> image = recorder.makePromiseTexture(
988 format, 32, 32, mipMapped,
989 kTopLeft_GrSurfaceOrigin,
990 kRGBA_8888_SkColorType,
991 kPremul_SkAlphaType, nullptr,
992 dummy_fulfill_proc,
993 dummy_release_proc,
994 dummy_done_proc,
995 nullptr,
996 SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo);
Greg Daniel09c94002018-06-08 22:11:51 +0000997 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipMapped::kYes) {
998 REPORTER_ASSERT(reporter, !image);
999 continue;
1000 }
1001 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001002
Jim Van Verth21bd60d2018-10-12 15:00:20 -04001003 GrTextureProxy* backingProxy = ((SkImage_GpuBase*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001004
Greg Daniel09c94002018-06-08 22:11:51 +00001005 REPORTER_ASSERT(reporter, backingProxy->mipMapped() == mipMapped);
1006 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001007 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001008 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001009 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001010 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001011 }
1012 }
Robert Phillipsbe77a022018-04-03 17:17:05 -04001013}
1014
1015////////////////////////////////////////////////////////////////////////////////
1016
Robert Phillips646f6372018-09-25 09:31:10 -04001017// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -04001018DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
1019 GrContext* context = ctxInfo.grContext();
1020
1021 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1022 SkColorType colorType = static_cast<SkColorType>(ct);
1023
Robert Phillips646f6372018-09-25 09:31:10 -04001024 for (int config = 0; config < kPrivateConfig1_GrPixelConfig; ++config) {
Robert Phillipsbe77a022018-04-03 17:17:05 -04001025 GrPixelConfig pixelConfig = static_cast<GrPixelConfig>(config);
1026
Robert Phillipsb45f47d2019-02-03 17:17:54 -05001027 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -04001028 params.setColorType(colorType);
1029 params.setConfig(pixelConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001030 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001031
1032 SkSurfaceCharacterization c = params.createCharacterization(context);
1033 GrBackendTexture backend;
1034
1035 if (!c.isValid()) {
1036 // TODO: this would be cool to enable but there is, currently, too much crossover
1037 // allowed internally (e.g., kAlpha_8_SkColorType/kGray_8_as_Red_GrPixelConfig
1038 // is permitted on GL).
1039#if 0
1040 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
1041
1042 // If we couldn't characterize the surface we shouldn't be able to create it either
1043 REPORTER_ASSERT(reporter, !tmp);
1044 if (tmp) {
1045 tmp = nullptr;
1046 params.cleanUpBackEnd(context, backend);
1047 }
1048#endif
1049 continue;
1050 }
1051
Robert Phillipsb45f47d2019-02-03 17:17:54 -05001052 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001053 REPORTER_ASSERT(reporter, s);
1054 if (!s) {
1055 s = nullptr;
1056 params.cleanUpBackEnd(context, backend);
1057 continue;
1058 }
1059
1060 SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
1061 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
1062
1063 s = nullptr;
1064 params.cleanUpBackEnd(context, backend);
1065
1066 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
1067 REPORTER_ASSERT(reporter, s);
1068 if (!s) {
1069 continue;
1070 }
1071
1072 gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
1073 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
1074 }
1075 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001076
1077}