blob: 9347748fac8ab567dc51d9ddbf3cbdbf6563b066 [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()) {
Greg Danielbdf12ad2018-10-12 09:31:11 -040057 case GrBackendApi::kOpenGL: {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040058 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(caps);
Robert Phillipsbe77a022018-04-03 17:17:05 -040059 GrGLStandard standard = glCaps->standard();
60
61 switch (ct) {
62 case kUnknown_SkColorType:
63 return GrBackendFormat();
64 case kAlpha_8_SkColorType:
65 if (kAlpha_8_as_Alpha_GrPixelConfig == config) {
66 return GrBackendFormat::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D);
67 } else if (kAlpha_8_GrPixelConfig == config ||
68 kAlpha_8_as_Red_GrPixelConfig == config) {
69 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
70 }
71 break;
72 case kRGB_565_SkColorType:
73 if (kRGB_565_GrPixelConfig == config) {
74 return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D);
75 }
76 break;
77 case kARGB_4444_SkColorType:
78 if (kRGBA_4444_GrPixelConfig == config) {
79 return GrBackendFormat::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D);
80 }
81 break;
82 case kRGBA_8888_SkColorType:
83 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -040084 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
Robert Phillipsbe77a022018-04-03 17:17:05 -040085 }
86 break;
87 case kRGB_888x_SkColorType:
88 if (kRGB_888_GrPixelConfig == config) {
89 return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D);
90 }
91 break;
92 case kBGRA_8888_SkColorType:
93 if (kBGRA_8888_GrPixelConfig == config) {
94 if (kGL_GrGLStandard == standard) {
95 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
96 } else if (kGLES_GrGLStandard == standard) {
97 return GrBackendFormat::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D);
98 }
Robert Phillipsbe77a022018-04-03 17:17:05 -040099 }
100 break;
101 case kRGBA_1010102_SkColorType:
102 if (kRGBA_1010102_GrPixelConfig == config) {
103 return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D);
104 }
105 break;
106 case kRGB_101010x_SkColorType:
107 return GrBackendFormat();
108 case kGray_8_SkColorType:
109 if (kGray_8_as_Lum_GrPixelConfig == config) {
110 return GrBackendFormat::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D);
111 } else if (kGray_8_GrPixelConfig == config ||
112 kGray_8_as_Red_GrPixelConfig == config) {
113 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
114 }
115 break;
116 case kRGBA_F16_SkColorType:
117 if (kRGBA_half_GrPixelConfig == config) {
118 return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D);
119 }
120 break;
Mike Klein37854712018-06-26 11:43:06 -0400121 case kRGBA_F32_SkColorType:
122 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500123 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400124 }
125 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500126#ifdef SK_VULKAN
Greg Danielbdf12ad2018-10-12 09:31:11 -0400127 case GrBackendApi::kVulkan:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400128 switch (ct) {
129 case kUnknown_SkColorType:
130 return GrBackendFormat();
131 case kAlpha_8_SkColorType:
132 // TODO: what about kAlpha_8_GrPixelConfig and kAlpha_8_as_Alpha_GrPixelConfig
133 if (kAlpha_8_as_Red_GrPixelConfig == config) {
134 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
135 }
136 break;
137 case kRGB_565_SkColorType:
138 if (kRGB_565_GrPixelConfig == config) {
139 return GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16);
140 }
141 break;
142 case kARGB_4444_SkColorType:
143 if (kRGBA_4444_GrPixelConfig == config) {
144 return GrBackendFormat::MakeVk(VK_FORMAT_B4G4R4A4_UNORM_PACK16);
145 }
146 break;
147 case kRGBA_8888_SkColorType:
148 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400149 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400150 }
151 break;
152 case kRGB_888x_SkColorType:
153 if (kRGB_888_GrPixelConfig == config) {
154 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM);
155 }
156 break;
157 case kBGRA_8888_SkColorType:
158 if (kBGRA_8888_GrPixelConfig == config) {
159 return GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400160 }
161 break;
162 case kRGBA_1010102_SkColorType:
163 if (kRGBA_1010102_GrPixelConfig == config) {
164 return GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
165 }
166 break;
167 case kRGB_101010x_SkColorType:
168 return GrBackendFormat();
169 case kGray_8_SkColorType:
170 // TODO: what about kAlpha_8_GrPixelConfig and kGray_8_as_Lum_GrPixelConfig?
171 if (kGray_8_as_Red_GrPixelConfig == config) {
172 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
173 }
174 break;
175 case kRGBA_F16_SkColorType:
176 if (kRGBA_half_GrPixelConfig == config) {
177 return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
178 }
179 break;
Mike Klein37854712018-06-26 11:43:06 -0400180 case kRGBA_F32_SkColorType:
181 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500182 }
183 break;
184#endif
Greg Danielbdf12ad2018-10-12 09:31:11 -0400185 case GrBackendApi::kMock:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400186 switch (ct) {
187 case kUnknown_SkColorType:
188 return GrBackendFormat();
189 case kAlpha_8_SkColorType:
190 if (kAlpha_8_GrPixelConfig == config ||
191 kAlpha_8_as_Alpha_GrPixelConfig == config ||
192 kAlpha_8_as_Red_GrPixelConfig == config) {
193 return GrBackendFormat::MakeMock(config);
194 }
195 break;
196 case kRGB_565_SkColorType:
197 if (kRGB_565_GrPixelConfig == config) {
198 return GrBackendFormat::MakeMock(config);
199 }
200 break;
201 case kARGB_4444_SkColorType:
202 if (kRGBA_4444_GrPixelConfig == config) {
203 return GrBackendFormat::MakeMock(config);
204 }
205 break;
206 case kRGBA_8888_SkColorType:
207 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400208 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400209 }
210 break;
211 case kRGB_888x_SkColorType:
212 if (kRGB_888_GrPixelConfig == config) {
213 return GrBackendFormat::MakeMock(config);
214 }
215 break;
216 case kBGRA_8888_SkColorType:
217 if (kBGRA_8888_GrPixelConfig == config) {
218 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400219 }
220 break;
221 case kRGBA_1010102_SkColorType:
222 if (kRGBA_1010102_GrPixelConfig == config) {
223 return GrBackendFormat::MakeMock(config);
224 }
225 break;
226 case kRGB_101010x_SkColorType:
227 return GrBackendFormat();
228 case kGray_8_SkColorType:
229 if (kGray_8_GrPixelConfig == config ||
230 kGray_8_as_Lum_GrPixelConfig == config ||
231 kGray_8_as_Red_GrPixelConfig == config) {
232 return GrBackendFormat::MakeMock(config);
233 }
234 break;
235 case kRGBA_F16_SkColorType:
236 if (kRGBA_half_GrPixelConfig == config) {
237 return GrBackendFormat::MakeMock(config);
238 }
239 break;
Mike Klein37854712018-06-26 11:43:06 -0400240 case kRGBA_F32_SkColorType:
241 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500242 }
243 break;
244 default:
245 return GrBackendFormat(); // return an invalid format
246 }
247
248 return GrBackendFormat(); // return an invalid format
249}
250
251
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500252class SurfaceParameters {
253public:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500254 static const int kNumParams = 11;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500255 static const int kSampleCount = 5;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500256 static const int kMipMipCount = 8;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500257 static const int kFBO0Count = 9;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500258
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500259 SurfaceParameters(GrBackendApi backend)
260 : fBackend(backend)
261 , fWidth(64)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500262 , fHeight(64)
263 , fOrigin(kTopLeft_GrSurfaceOrigin)
264 , fColorType(kRGBA_8888_SkColorType)
Brian Osman37f99882018-08-09 10:26:57 -0400265 , fConfig(kRGBA_8888_GrPixelConfig)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500266 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -0500267 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -0500268 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500269 , fShouldCreateMipMaps(true)
270 , fUsesGLFBO0(false)
271 , fIsTextureable(true) {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500272 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500273
274 int sampleCount() const { return fSampleCount; }
275
Robert Phillipsbe77a022018-04-03 17:17:05 -0400276 void setColorType(SkColorType ct) { fColorType = ct; }
277 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
278 void setConfig(GrPixelConfig config) { fConfig = config; }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500279 void setTextureable(bool isTextureable) { fIsTextureable = isTextureable; }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400280
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500281 // Modify the SurfaceParameters in just one way
282 void modify(int i) {
283 switch (i) {
284 case 0:
285 fWidth = 63;
286 break;
287 case 1:
288 fHeight = 63;
289 break;
290 case 2:
291 fOrigin = kBottomLeft_GrSurfaceOrigin;
292 break;
293 case 3:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400294 // The color type and config need to be changed together.
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500295 fColorType = kRGBA_F16_SkColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400296 fConfig = kRGBA_half_GrPixelConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500297 break;
298 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400299 // This just needs to be a colorSpace different from that returned by MakeSRGB().
300 // In this case we just change the gamut.
Brian Osman82ebe042019-01-04 17:03:00 -0500301 fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500302 break;
303 case kSampleCount:
304 fSampleCount = 4;
305 break;
306 case 6:
307 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
308 break;
309 case 7:
310 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
311 kUnknown_SkPixelGeometry);
312 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500313 case 8:
314 fShouldCreateMipMaps = false;
315 break;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500316 case 9:
317 if (GrBackendApi::kOpenGL == fBackend) {
318 fUsesGLFBO0 = true;
319 fIsTextureable = false;
320 }
321 break;
322 case 10:
323 fIsTextureable = false;
324 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500325 }
326 }
327
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400328 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500329 int maxResourceCount;
330 size_t maxResourceBytes;
331 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
332
333 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
334 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
335 kPremul_SkAlphaType, fColorSpace);
336
Brian Osman37f99882018-08-09 10:26:57 -0400337 GrBackendFormat backendFormat = create_backend_format(context, fColorType, fConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400338 if (!backendFormat.isValid()) {
339 return SkSurfaceCharacterization();
340 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500341
342 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
343 maxResourceBytes, ii, backendFormat, fSampleCount,
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500344 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
345 fUsesGLFBO0, fIsTextureable);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400346 return c;
347 }
348
349 // Create a DDL whose characterization captures the current settings
350 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
351 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500352 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500353
354 SkDeferredDisplayListRecorder r(c);
355 SkCanvas* canvas = r.getCanvas();
356 if (!canvas) {
357 return nullptr;
358 }
359
360 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
361 return r.detach();
362 }
363
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500364 // Create the surface with the current set of parameters
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500365 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend) const {
Robert Phillips9da87e02019-02-04 13:26:26 -0500366 GrGpu* gpu = context->priv().getGpu();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500367
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500368 GrMipMapped mipmapped = !fIsTextureable
Robert Phillipsbe77a022018-04-03 17:17:05 -0400369 ? GrMipMapped::kNo
370 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500371
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500372 if (fUsesGLFBO0) {
373 if (GrBackendApi::kOpenGL != context->backend()) {
374 return nullptr;
375 }
376
377 GrGLFramebufferInfo fboInfo;
378 fboInfo.fFBOID = 0;
379 fboInfo.fFormat = GR_GL_RGBA8;
380 static constexpr int kStencilBits = 8;
381 GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo);
382 backendRT.setPixelConfig(fConfig);
383
384 if (!backendRT.isValid()) {
385 return nullptr;
386 }
387
388 return SkSurface::MakeFromBackendRenderTarget(context, backendRT, fOrigin,
389 fColorType, fColorSpace, &fSurfaceProps);
390 }
391
Robert Phillipse8fabb22018-02-04 14:33:21 -0500392 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillips646f6372018-09-25 09:31:10 -0400393 fColorType, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500394 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
395 return nullptr;
396 }
397
Robert Phillipsbe77a022018-04-03 17:17:05 -0400398 sk_sp<SkSurface> surface;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500399 if (!fIsTextureable) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400400 // Create a surface w/ the current parameters but make it non-textureable
401 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
402 context, *backend, fOrigin, fSampleCount, fColorType,
403 fColorSpace, &fSurfaceProps);
404 } else {
405 surface = SkSurface::MakeFromBackendTexture(
406 context, *backend, fOrigin, fSampleCount, fColorType,
407 fColorSpace, &fSurfaceProps);
408 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500409
410 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500411 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500412 return nullptr;
413 }
414
415 return surface;
416 }
417
Brian Salomon26102cb2018-03-09 09:33:19 -0500418 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500419 if (!backend.isValid()) {
420 return;
421 }
422
Robert Phillips9da87e02019-02-04 13:26:26 -0500423 GrGpu* gpu = context->priv().getGpu();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500424
425 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500426 }
427
428private:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500429 GrBackendApi fBackend;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500430 int fWidth;
431 int fHeight;
432 GrSurfaceOrigin fOrigin;
433 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400434 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500435 sk_sp<SkColorSpace> fColorSpace;
436 int fSampleCount;
437 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500438 bool fShouldCreateMipMaps;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500439 bool fUsesGLFBO0;
440 bool fIsTextureable;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500441};
442
Robert Phillipsc1267c62018-04-04 11:12:39 -0400443// Test out operator== && operator!=
444DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
445 GrContext* context = ctxInfo.grContext();
446
447 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500448 SurfaceParameters params1(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400449 params1.modify(i);
450
451 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
452 if (!char1.isValid()) {
453 continue; // can happen on some platforms (ChromeOS)
454 }
455
456 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500457 SurfaceParameters params2(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400458 params2.modify(j);
459
460 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
461 if (!char2.isValid()) {
462 continue; // can happen on some platforms (ChromeOS)
463 }
464
465 if (i == j) {
466 REPORTER_ASSERT(reporter, char1 == char2);
467 } else {
468 REPORTER_ASSERT(reporter, char1 != char2);
469 }
470
471 }
472 }
473
474 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500475 SurfaceParameters params(context->backend());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400476
477 SkSurfaceCharacterization valid = params.createCharacterization(context);
478 SkASSERT(valid.isValid());
479
480 SkSurfaceCharacterization inval1, inval2;
481 SkASSERT(!inval1.isValid() && !inval2.isValid());
482
483 REPORTER_ASSERT(reporter, inval1 != inval2);
484 REPORTER_ASSERT(reporter, valid != inval1);
485 REPORTER_ASSERT(reporter, inval1 != valid);
486 }
487}
488
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400489////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500490// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400491DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500492 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500493 GrGpu* gpu = context->priv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500494
Robert Phillips9e441ee2018-02-01 15:14:55 -0500495 // Create a bitmap that we can readback into
496 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
497 kPremul_SkAlphaType);
498 SkBitmap bitmap;
499 bitmap.allocPixels(imageInfo);
500
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500501 std::unique_ptr<SkDeferredDisplayList> ddl;
502
503 // First, create a DDL using the stock SkSurface parameters
504 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500505 SurfaceParameters params(context->backend());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500506
Robert Phillipse8fabb22018-02-04 14:33:21 -0500507 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500508 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500509
510 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400511 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500512 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500513 if (!s) {
514 return;
515 }
516
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500517 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500518 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400519 context->flush();
520 gpu->testingOnly_flushGpuAndSync();
521 s = nullptr;
522 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500523 }
524
525 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
526 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500527 SurfaceParameters params(context->backend());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500528 params.modify(i);
529
Robert Phillipsbe77a022018-04-03 17:17:05 -0400530 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500531 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500532 if (!s) {
533 continue;
534 }
535
536 if (SurfaceParameters::kSampleCount == i) {
537 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
538
Robert Phillips9da87e02019-02-04 13:26:26 -0500539 int supportedSampleCount = context->priv().caps()->getRenderTargetSampleCount(
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400540 params.sampleCount(),
541 gpuSurf->getDevice()
542 ->accessRenderTargetContext()
543 ->asRenderTargetProxy()
544 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500545 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500546 // If changing the sample count won't result in a different
547 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400548 s = nullptr;
549 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500550 continue;
551 }
552 }
553
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400554 if (SurfaceParameters::kMipMipCount == i &&
Robert Phillips9da87e02019-02-04 13:26:26 -0500555 !context->priv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400556 // If changing the mipmap setting won't result in a different surface characterization,
557 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400558 s = nullptr;
559 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500560 continue;
561 }
562
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500563 if (SurfaceParameters::kFBO0Count == i && context->backend() != GrBackendApi::kOpenGL) {
564 // FBO0 only affects the surface characterization when using OpenGL
565 s = nullptr;
566 params.cleanUpBackEnd(context, backend);
567 continue;
568 }
569
Robert Phillipse8fabb22018-02-04 14:33:21 -0500570 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
571 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400572
573 context->flush();
574 gpu->testingOnly_flushGpuAndSync();
575 s = nullptr;
576 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500577 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500578
579 // Next test the compatibility of resource cache parameters
580 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500581 const SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400582 GrBackendTexture backend;
583
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500584 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500585
586 int maxResourceCount;
587 size_t maxResourceBytes;
588 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
589
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500590 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
591 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
592
Robert Phillips9e441ee2018-02-01 15:14:55 -0500593 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
594 // For now, DDLs are drawn once.
595#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500596 // resource limits >= those at characterization time are accepted
597 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
598 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500599 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500600
601 context->setResourceCacheLimits(maxResourceCount, 2*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, 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);
608#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400609
610 context->flush();
611 gpu->testingOnly_flushGpuAndSync();
612 s = nullptr;
613 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500614 }
615
Robert Phillipse8fabb22018-02-04 14:33:21 -0500616 // Test that the textureability of the DDL characterization can block a DDL draw
617 {
618 GrBackendTexture backend;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500619 SurfaceParameters params(context->backend());
620 params.setTextureable(false);
621
622 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500623 if (s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500624 REPORTER_ASSERT(reporter, !s->draw(ddl.get())); // bc the DDL was made w/ textureability
Robert Phillipse8fabb22018-02-04 14:33:21 -0500625
Robert Phillipsbe77a022018-04-03 17:17:05 -0400626 context->flush();
627 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500628 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500629 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500630 }
631 }
632
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500633 // Make sure non-GPU-backed surfaces fail characterization
634 {
635 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
636
637 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
638 SkSurfaceCharacterization c;
639 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
640 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500641
642 // Exercise the createResized method
643 {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500644 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400645 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500646
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500647 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500648 if (!s) {
649 return;
650 }
651
652 SkSurfaceCharacterization char0;
653 SkAssertResult(s->characterize(&char0));
654
655 // Too small
656 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
657 REPORTER_ASSERT(reporter, !char1.isValid());
658
659 // Too large
660 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
661 REPORTER_ASSERT(reporter, !char2.isValid());
662
663 // Just right
664 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
665 REPORTER_ASSERT(reporter, char3.isValid());
666 REPORTER_ASSERT(reporter, 32 == char3.width());
667 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400668
669 s = nullptr;
670 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500671 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500672}
673
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500674// Test that a DDL created w/o textureability can be replayed into both a textureable and
675// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
676// textureable DDL cannot be played into a non-textureable destination but can be replayed
677// into a textureable destination.
678DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) {
679 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500680 GrGpu* gpu = context->priv().getGpu();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500681
682 // Create a bitmap that we can readback into
683 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
684 kPremul_SkAlphaType);
685 SkBitmap bitmap;
686 bitmap.allocPixels(imageInfo);
687
688 for (bool textureability : { true, false }) {
689 std::unique_ptr<SkDeferredDisplayList> ddl;
690
691 // First, create a DDL w/o textureability. TODO: once we have reusable DDLs, move this
692 // outside of the loop.
693 {
694 SurfaceParameters params(context->backend());
695 params.setTextureable(false);
696
697 ddl = params.createDDL(context);
698 SkAssertResult(ddl);
699 }
700
701 // Then verify it can draw into either flavor of destination
702 SurfaceParameters params(context->backend());
703 params.setTextureable(textureability);
704
705 GrBackendTexture backend;
706 sk_sp<SkSurface> s = params.make(context, &backend);
707 if (!s) {
708 params.cleanUpBackEnd(context, backend);
709 continue;
710 }
711
712 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
713 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
714 context->flush();
715 gpu->testingOnly_flushGpuAndSync();
716 s = nullptr;
717 params.cleanUpBackEnd(context, backend);
718 }
719
720}
721
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400722////////////////////////////////////////////////////////////////////////////////
723// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
724// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400725DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400726 GrContext* context = ctxInfo.grContext();
727
728 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500729 SurfaceParameters params(context->backend());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400730 params.modify(i);
731
732 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400733 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400734
Robert Phillipsbe77a022018-04-03 17:17:05 -0400735 if (!c.isValid()) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500736 sk_sp<SkSurface> tmp = params.make(context, &backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400737
738 // If we couldn't characterize the surface we shouldn't be able to create it either
739 REPORTER_ASSERT(reporter, !tmp);
740 if (tmp) {
741 tmp = nullptr;
742 params.cleanUpBackEnd(context, backend);
743 }
744 continue;
745 }
746
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500747 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400748 if (!s) {
749 REPORTER_ASSERT(reporter, !c.isValid());
750 continue;
751 }
752
753 REPORTER_ASSERT(reporter, c.isValid());
754
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500755 if (SurfaceParameters::kFBO0Count == i) {
756 // MakeRenderTarget doesn't support FBO0
757 params.cleanUpBackEnd(context, backend);
758 continue;
759 }
760
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400761 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
762 REPORTER_ASSERT(reporter, s);
763
764 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
765 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400766
767 s = nullptr;
768 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400769 }
770}
771
772////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500773static constexpr int kSize = 8;
774
775struct TextureReleaseChecker {
776 TextureReleaseChecker() : fReleaseCount(0) {}
777 int fReleaseCount;
778 static void Release(void* self) {
779 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
780 }
781};
782
783enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
784
785// This tests the ability to create and use wrapped textures in a DDL world
786DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
787 GrContext* context = ctxInfo.grContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500788 GrGpu* gpu = context->priv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500789 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400790 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500791 if (!backendTex.isValid()) {
792 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500793 }
Brian Salomonf7778972018-03-08 10:13:17 -0500794
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500795 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400796 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500797
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500798 sk_sp<SkSurface> s = params.make(context, &backend);
Brian Salomonf7778972018-03-08 10:13:17 -0500799 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500800 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500801 return;
802 }
803
804 SkSurfaceCharacterization c;
805 SkAssertResult(s->characterize(&c));
806
807 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
808
809 SkCanvas* canvas = recorder->getCanvas();
810 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400811 s = nullptr;
812 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500813 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500814 return;
815 }
816
817 GrContext* deferredContext = canvas->getGrContext();
818 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400819 s = nullptr;
820 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500821 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500822 return;
823 }
824
825 // Wrapped Backend Textures are not supported in DDL
826 sk_sp<SkImage> image =
827 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
828 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
829 REPORTER_ASSERT(reporter, !image);
830
831 TextureReleaseChecker releaseChecker;
832 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
833 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
834 TextureReleaseChecker::Release, &releaseChecker);
835 REPORTER_ASSERT(reporter, !image);
836
Brian Salomon26102cb2018-03-09 09:33:19 -0500837 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400838
839 s = nullptr;
840 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500841}
842
Brian Salomon59ef8c32019-01-30 12:20:56 -0500843static sk_sp<SkPromiseImageTexture> dummy_fulfill_proc(void*) {
844 SkASSERT(0);
845 return nullptr;
846}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400847static void dummy_release_proc(void*) { SkASSERT(0); }
Brian Salomon59ef8c32019-01-30 12:20:56 -0500848static void dummy_done_proc(void*) {}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400849
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400850////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400851// Test out the behavior of an invalid DDLRecorder
852DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
853 GrContext* context = ctxInfo.grContext();
854
855 {
856 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
857 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
858
859 SkSurfaceCharacterization characterization;
860 SkAssertResult(s->characterize(&characterization));
861
862 // never calling getCanvas means the backing surface is never allocated
863 SkDeferredDisplayListRecorder recorder(characterization);
864 }
865
866 {
867 SkSurfaceCharacterization invalid;
868
869 SkDeferredDisplayListRecorder recorder(invalid);
870
871 const SkSurfaceCharacterization c = recorder.characterization();
872 REPORTER_ASSERT(reporter, !c.isValid());
873 REPORTER_ASSERT(reporter, !recorder.getCanvas());
874 REPORTER_ASSERT(reporter, !recorder.detach());
875
Robert Phillipsbe77a022018-04-03 17:17:05 -0400876 GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType,
Brian Osman37f99882018-08-09 10:26:57 -0400877 kRGBA_8888_GrPixelConfig);
Brian Salomonf55e8d52019-01-30 17:28:20 -0500878 sk_sp<SkImage> image = recorder.makePromiseTexture(
879 format, 32, 32, GrMipMapped::kNo,
880 kTopLeft_GrSurfaceOrigin,
881 kRGBA_8888_SkColorType,
882 kPremul_SkAlphaType, nullptr,
883 dummy_fulfill_proc,
884 dummy_release_proc,
885 dummy_done_proc,
886 nullptr,
887 SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400888 REPORTER_ASSERT(reporter, !image);
889 }
890
891}
892
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400893////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400894// Ensure that flushing while DDL recording doesn't cause a crash
895DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
896 GrContext* context = ctxInfo.grContext();
897
898 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
899 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
900
901 SkSurfaceCharacterization characterization;
902 SkAssertResult(s->characterize(&characterization));
903
904 SkDeferredDisplayListRecorder recorder(characterization);
905 SkCanvas* canvas = recorder.getCanvas();
906
907 canvas->flush();
908 canvas->getGrContext()->flush();
909}
Greg Danielf2336e42018-01-23 16:38:14 -0500910
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400911////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -0500912// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
913DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
914 GrContext* context = ctxInfo.grContext();
915
916 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
917 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
918
919 SkBitmap bitmap;
920 bitmap.allocPixels(ii);
921
922 SkSurfaceCharacterization characterization;
923 SkAssertResult(s->characterize(&characterization));
924
925 SkDeferredDisplayListRecorder recorder(characterization);
926
927 SkCanvas* canvas1 = recorder.getCanvas();
928
929 canvas1->clear(SK_ColorRED);
930
931 canvas1->save();
932 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
933
934 std::unique_ptr<SkDeferredDisplayList> ddl1 = recorder.detach();
935
936 SkCanvas* canvas2 = recorder.getCanvas();
937
938 SkPaint p;
939 p.setColor(SK_ColorGREEN);
940 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
941
942 std::unique_ptr<SkDeferredDisplayList> ddl2 = recorder.detach();
943
944 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
945 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
946
947 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
948 // lazy proxy are all different between the two DDLs
949 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
950
951 s->draw(ddl1.get());
952 s->draw(ddl2.get());
953
954 // Make sure the clipRect from DDL1 didn't percolate into DDL2
955 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
956 for (int y = 0; y < 32; ++y) {
957 for (int x = 0; x < 32; ++x) {
958 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
959 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
960 return; // we only really need to report the error once
961 }
962 }
963 }
964}
965
966////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -0400967// Check that the texture-specific flags (i.e., for external & rectangle textures) work
968// for promise images. As such, this is a GL-only test.
969DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
970 GrContext* context = ctxInfo.grContext();
971
972 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
973 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
974
975 SkSurfaceCharacterization characterization;
976 SkAssertResult(s->characterize(&characterization));
977
978 SkDeferredDisplayListRecorder recorder(characterization);
979
980 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Greg Daniel09c94002018-06-08 22:11:51 +0000981 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
982 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400983
Brian Salomonf55e8d52019-01-30 17:28:20 -0500984 sk_sp<SkImage> image = recorder.makePromiseTexture(
985 format, 32, 32, mipMapped,
986 kTopLeft_GrSurfaceOrigin,
987 kRGBA_8888_SkColorType,
988 kPremul_SkAlphaType, nullptr,
989 dummy_fulfill_proc,
990 dummy_release_proc,
991 dummy_done_proc,
992 nullptr,
993 SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo);
Greg Daniel09c94002018-06-08 22:11:51 +0000994 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipMapped::kYes) {
995 REPORTER_ASSERT(reporter, !image);
996 continue;
997 }
998 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400999
Jim Van Verth21bd60d2018-10-12 15:00:20 -04001000 GrTextureProxy* backingProxy = ((SkImage_GpuBase*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001001
Greg Daniel09c94002018-06-08 22:11:51 +00001002 REPORTER_ASSERT(reporter, backingProxy->mipMapped() == mipMapped);
1003 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001004 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001005 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001006 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001007 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001008 }
1009 }
Robert Phillipsbe77a022018-04-03 17:17:05 -04001010}
1011
1012////////////////////////////////////////////////////////////////////////////////
1013
Robert Phillips646f6372018-09-25 09:31:10 -04001014// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -04001015DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
1016 GrContext* context = ctxInfo.grContext();
1017
1018 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1019 SkColorType colorType = static_cast<SkColorType>(ct);
1020
Robert Phillips646f6372018-09-25 09:31:10 -04001021 for (int config = 0; config < kPrivateConfig1_GrPixelConfig; ++config) {
Robert Phillipsbe77a022018-04-03 17:17:05 -04001022 GrPixelConfig pixelConfig = static_cast<GrPixelConfig>(config);
1023
Robert Phillipsb45f47d2019-02-03 17:17:54 -05001024 SurfaceParameters params(context->backend());
Robert Phillipsbe77a022018-04-03 17:17:05 -04001025 params.setColorType(colorType);
1026 params.setConfig(pixelConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001027 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001028
1029 SkSurfaceCharacterization c = params.createCharacterization(context);
1030 GrBackendTexture backend;
1031
1032 if (!c.isValid()) {
1033 // TODO: this would be cool to enable but there is, currently, too much crossover
1034 // allowed internally (e.g., kAlpha_8_SkColorType/kGray_8_as_Red_GrPixelConfig
1035 // is permitted on GL).
1036#if 0
1037 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
1038
1039 // If we couldn't characterize the surface we shouldn't be able to create it either
1040 REPORTER_ASSERT(reporter, !tmp);
1041 if (tmp) {
1042 tmp = nullptr;
1043 params.cleanUpBackEnd(context, backend);
1044 }
1045#endif
1046 continue;
1047 }
1048
Robert Phillipsb45f47d2019-02-03 17:17:54 -05001049 sk_sp<SkSurface> s = params.make(context, &backend);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001050 REPORTER_ASSERT(reporter, s);
1051 if (!s) {
1052 s = nullptr;
1053 params.cleanUpBackEnd(context, backend);
1054 continue;
1055 }
1056
1057 SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
1058 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
1059
1060 s = nullptr;
1061 params.cleanUpBackEnd(context, backend);
1062
1063 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
1064 REPORTER_ASSERT(reporter, s);
1065 if (!s) {
1066 continue;
1067 }
1068
1069 gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
1070 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
1071 }
1072 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001073
1074}