blob: e20bc82f21ebcb6dce94cc7ad6f2068e265407a4 [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) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040054 const GrCaps* caps = context->contextPriv().caps();
Robert Phillipsfc711a22018-02-13 17:03:00 -050055
56 switch (context->contextPriv().getBackend()) {
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 Phillipse8fabb22018-02-04 14:33:21 -0500254 static const int kNumParams = 9;
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 Phillips7ffbcf92017-12-04 12:52:46 -0500257
Robert Phillipsbe77a022018-04-03 17:17:05 -0400258 SurfaceParameters(const GrCaps* caps)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500259 : fWidth(64)
260 , fHeight(64)
261 , fOrigin(kTopLeft_GrSurfaceOrigin)
262 , fColorType(kRGBA_8888_SkColorType)
Brian Osman37f99882018-08-09 10:26:57 -0400263 , fConfig(kRGBA_8888_GrPixelConfig)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500264 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -0500265 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -0500266 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
267 , fShouldCreateMipMaps(true) {
268 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500269
270 int sampleCount() const { return fSampleCount; }
271
Robert Phillipsbe77a022018-04-03 17:17:05 -0400272 void setColorType(SkColorType ct) { fColorType = ct; }
273 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
274 void setConfig(GrPixelConfig config) { fConfig = config; }
275
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500276 // Modify the SurfaceParameters in just one way
277 void modify(int i) {
278 switch (i) {
279 case 0:
280 fWidth = 63;
281 break;
282 case 1:
283 fHeight = 63;
284 break;
285 case 2:
286 fOrigin = kBottomLeft_GrSurfaceOrigin;
287 break;
288 case 3:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400289 // The color type and config need to be changed together.
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500290 fColorType = kRGBA_F16_SkColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400291 fConfig = kRGBA_half_GrPixelConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500292 break;
293 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400294 // This just needs to be a colorSpace different from that returned by MakeSRGB().
295 // In this case we just change the gamut.
Brian Osman82ebe042019-01-04 17:03:00 -0500296 fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500297 break;
298 case kSampleCount:
299 fSampleCount = 4;
300 break;
301 case 6:
302 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
303 break;
304 case 7:
305 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
306 kUnknown_SkPixelGeometry);
307 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500308 case 8:
309 fShouldCreateMipMaps = false;
310 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500311 }
312 }
313
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400314 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500315 int maxResourceCount;
316 size_t maxResourceBytes;
317 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
318
319 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
320 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
321 kPremul_SkAlphaType, fColorSpace);
322
Brian Osman37f99882018-08-09 10:26:57 -0400323 GrBackendFormat backendFormat = create_backend_format(context, fColorType, fConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400324 if (!backendFormat.isValid()) {
325 return SkSurfaceCharacterization();
326 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500327
328 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
329 maxResourceBytes, ii, backendFormat, fSampleCount,
330 fOrigin, fSurfaceProps, fShouldCreateMipMaps);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400331 return c;
332 }
333
334 // Create a DDL whose characterization captures the current settings
335 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
336 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500337 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500338
339 SkDeferredDisplayListRecorder r(c);
340 SkCanvas* canvas = r.getCanvas();
341 if (!canvas) {
342 return nullptr;
343 }
344
345 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
346 return r.detach();
347 }
348
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500349 // Create the surface with the current set of parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400350 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend,
351 bool nonTextureable) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500352 GrGpu* gpu = context->contextPriv().getGpu();
353
Robert Phillipsbe77a022018-04-03 17:17:05 -0400354 GrMipMapped mipmapped = nonTextureable
355 ? GrMipMapped::kNo
356 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500357
358 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillips646f6372018-09-25 09:31:10 -0400359 fColorType, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500360 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
361 return nullptr;
362 }
363
Robert Phillipsbe77a022018-04-03 17:17:05 -0400364 sk_sp<SkSurface> surface;
365 if (nonTextureable) {
366 // Create a surface w/ the current parameters but make it non-textureable
367 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
368 context, *backend, fOrigin, fSampleCount, fColorType,
369 fColorSpace, &fSurfaceProps);
370 } else {
371 surface = SkSurface::MakeFromBackendTexture(
372 context, *backend, fOrigin, fSampleCount, fColorType,
373 fColorSpace, &fSurfaceProps);
374 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500375
376 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500377 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500378 return nullptr;
379 }
380
381 return surface;
382 }
383
Brian Salomon26102cb2018-03-09 09:33:19 -0500384 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500385 GrGpu* gpu = context->contextPriv().getGpu();
386
387 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500388 }
389
390private:
391 int fWidth;
392 int fHeight;
393 GrSurfaceOrigin fOrigin;
394 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400395 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500396 sk_sp<SkColorSpace> fColorSpace;
397 int fSampleCount;
398 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500399 bool fShouldCreateMipMaps;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500400};
401
Robert Phillipsc1267c62018-04-04 11:12:39 -0400402// Test out operator== && operator!=
403DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
404 GrContext* context = ctxInfo.grContext();
405
406 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400407 SurfaceParameters params1(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400408 params1.modify(i);
409
410 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
411 if (!char1.isValid()) {
412 continue; // can happen on some platforms (ChromeOS)
413 }
414
415 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400416 SurfaceParameters params2(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400417 params2.modify(j);
418
419 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
420 if (!char2.isValid()) {
421 continue; // can happen on some platforms (ChromeOS)
422 }
423
424 if (i == j) {
425 REPORTER_ASSERT(reporter, char1 == char2);
426 } else {
427 REPORTER_ASSERT(reporter, char1 != char2);
428 }
429
430 }
431 }
432
433 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400434 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400435
436 SkSurfaceCharacterization valid = params.createCharacterization(context);
437 SkASSERT(valid.isValid());
438
439 SkSurfaceCharacterization inval1, inval2;
440 SkASSERT(!inval1.isValid() && !inval2.isValid());
441
442 REPORTER_ASSERT(reporter, inval1 != inval2);
443 REPORTER_ASSERT(reporter, valid != inval1);
444 REPORTER_ASSERT(reporter, inval1 != valid);
445 }
446}
447
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400448////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500449// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400450DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500451 GrContext* context = ctxInfo.grContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400452 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500453
Robert Phillips9e441ee2018-02-01 15:14:55 -0500454 // Create a bitmap that we can readback into
455 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
456 kPremul_SkAlphaType);
457 SkBitmap bitmap;
458 bitmap.allocPixels(imageInfo);
459
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500460 std::unique_ptr<SkDeferredDisplayList> ddl;
461
462 // First, create a DDL using the stock SkSurface parameters
463 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400464 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500465
Robert Phillipse8fabb22018-02-04 14:33:21 -0500466 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500467 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500468
469 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400470 GrBackendTexture backend;
471 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500472 if (!s) {
473 return;
474 }
475
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500476 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500477 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400478 context->flush();
479 gpu->testingOnly_flushGpuAndSync();
480 s = nullptr;
481 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500482 }
483
484 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
485 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400486 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500487 params.modify(i);
488
Robert Phillipsbe77a022018-04-03 17:17:05 -0400489 GrBackendTexture backend;
490 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500491 if (!s) {
492 continue;
493 }
494
495 if (SurfaceParameters::kSampleCount == i) {
496 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
497
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400498 int supportedSampleCount = context->contextPriv().caps()->getRenderTargetSampleCount(
499 params.sampleCount(),
500 gpuSurf->getDevice()
501 ->accessRenderTargetContext()
502 ->asRenderTargetProxy()
503 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500504 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500505 // If changing the sample count won't result in a different
506 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400507 s = nullptr;
508 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500509 continue;
510 }
511 }
512
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400513 if (SurfaceParameters::kMipMipCount == i &&
514 !context->contextPriv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400515 // If changing the mipmap setting won't result in a different surface characterization,
516 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400517 s = nullptr;
518 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500519 continue;
520 }
521
522 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
523 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400524
525 context->flush();
526 gpu->testingOnly_flushGpuAndSync();
527 s = nullptr;
528 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500529 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500530
531 // Next test the compatibility of resource cache parameters
532 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400533 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400534 GrBackendTexture backend;
535
536 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500537
538 int maxResourceCount;
539 size_t maxResourceBytes;
540 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
541
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500542 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
543 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
544
Robert Phillips9e441ee2018-02-01 15:14:55 -0500545 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
546 // For now, DDLs are drawn once.
547#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500548 // resource limits >= those at characterization time are accepted
549 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
550 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500551 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500552
553 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
554 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500555 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500556
557 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
558 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500559 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
560#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400561
562 context->flush();
563 gpu->testingOnly_flushGpuAndSync();
564 s = nullptr;
565 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500566 }
567
Robert Phillipse8fabb22018-02-04 14:33:21 -0500568 // Test that the textureability of the DDL characterization can block a DDL draw
569 {
570 GrBackendTexture backend;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400571 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400572 sk_sp<SkSurface> s = params.make(context, &backend, true);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500573 if (s) {
574 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
575
Robert Phillipsbe77a022018-04-03 17:17:05 -0400576 context->flush();
577 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500578 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500579 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500580 }
581 }
582
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500583 // Make sure non-GPU-backed surfaces fail characterization
584 {
585 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
586
587 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
588 SkSurfaceCharacterization c;
589 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
590 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500591
592 // Exercise the createResized method
593 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400594 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400595 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500596
Robert Phillipsbe77a022018-04-03 17:17:05 -0400597 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips94458ee2018-03-06 13:41:51 -0500598 if (!s) {
599 return;
600 }
601
602 SkSurfaceCharacterization char0;
603 SkAssertResult(s->characterize(&char0));
604
605 // Too small
606 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
607 REPORTER_ASSERT(reporter, !char1.isValid());
608
609 // Too large
610 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
611 REPORTER_ASSERT(reporter, !char2.isValid());
612
613 // Just right
614 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
615 REPORTER_ASSERT(reporter, char3.isValid());
616 REPORTER_ASSERT(reporter, 32 == char3.width());
617 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400618
619 s = nullptr;
620 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500621 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500622}
623
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400624////////////////////////////////////////////////////////////////////////////////
625// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
626// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400627DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400628 GrContext* context = ctxInfo.grContext();
629
630 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400631 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400632 params.modify(i);
633
634 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400635 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400636
Robert Phillipsbe77a022018-04-03 17:17:05 -0400637 if (!c.isValid()) {
638 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
639
640 // If we couldn't characterize the surface we shouldn't be able to create it either
641 REPORTER_ASSERT(reporter, !tmp);
642 if (tmp) {
643 tmp = nullptr;
644 params.cleanUpBackEnd(context, backend);
645 }
646 continue;
647 }
648
649 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400650 if (!s) {
651 REPORTER_ASSERT(reporter, !c.isValid());
652 continue;
653 }
654
655 REPORTER_ASSERT(reporter, c.isValid());
656
657 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
658 REPORTER_ASSERT(reporter, s);
659
660 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
661 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400662
663 s = nullptr;
664 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400665 }
666}
667
668////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500669static constexpr int kSize = 8;
670
671struct TextureReleaseChecker {
672 TextureReleaseChecker() : fReleaseCount(0) {}
673 int fReleaseCount;
674 static void Release(void* self) {
675 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
676 }
677};
678
679enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
680
681// This tests the ability to create and use wrapped textures in a DDL world
682DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
683 GrContext* context = ctxInfo.grContext();
684 GrGpu* gpu = context->contextPriv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500685 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400686 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500687 if (!backendTex.isValid()) {
688 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500689 }
Brian Salomonf7778972018-03-08 10:13:17 -0500690
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400691 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400692 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500693
Robert Phillipsbe77a022018-04-03 17:17:05 -0400694 sk_sp<SkSurface> s = params.make(context, &backend, false);
Brian Salomonf7778972018-03-08 10:13:17 -0500695 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500696 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500697 return;
698 }
699
700 SkSurfaceCharacterization c;
701 SkAssertResult(s->characterize(&c));
702
703 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
704
705 SkCanvas* canvas = recorder->getCanvas();
706 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400707 s = nullptr;
708 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500709 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500710 return;
711 }
712
713 GrContext* deferredContext = canvas->getGrContext();
714 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400715 s = nullptr;
716 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500717 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500718 return;
719 }
720
721 // Wrapped Backend Textures are not supported in DDL
722 sk_sp<SkImage> image =
723 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
724 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
725 REPORTER_ASSERT(reporter, !image);
726
727 TextureReleaseChecker releaseChecker;
728 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
729 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
730 TextureReleaseChecker::Release, &releaseChecker);
731 REPORTER_ASSERT(reporter, !image);
732
Brian Salomon26102cb2018-03-09 09:33:19 -0500733 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400734
735 s = nullptr;
736 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500737}
738
Brian Salomon59ef8c32019-01-30 12:20:56 -0500739static sk_sp<SkPromiseImageTexture> dummy_fulfill_proc(void*) {
740 SkASSERT(0);
741 return nullptr;
742}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400743static void dummy_release_proc(void*) { SkASSERT(0); }
Brian Salomon59ef8c32019-01-30 12:20:56 -0500744static void dummy_done_proc(void*) {}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400745
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400746////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400747// Test out the behavior of an invalid DDLRecorder
748DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
749 GrContext* context = ctxInfo.grContext();
750
751 {
752 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
753 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
754
755 SkSurfaceCharacterization characterization;
756 SkAssertResult(s->characterize(&characterization));
757
758 // never calling getCanvas means the backing surface is never allocated
759 SkDeferredDisplayListRecorder recorder(characterization);
760 }
761
762 {
763 SkSurfaceCharacterization invalid;
764
765 SkDeferredDisplayListRecorder recorder(invalid);
766
767 const SkSurfaceCharacterization c = recorder.characterization();
768 REPORTER_ASSERT(reporter, !c.isValid());
769 REPORTER_ASSERT(reporter, !recorder.getCanvas());
770 REPORTER_ASSERT(reporter, !recorder.detach());
771
Robert Phillipsbe77a022018-04-03 17:17:05 -0400772 GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType,
Brian Osman37f99882018-08-09 10:26:57 -0400773 kRGBA_8888_GrPixelConfig);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400774 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo,
775 kTopLeft_GrSurfaceOrigin,
776 kRGBA_8888_SkColorType,
777 kPremul_SkAlphaType, nullptr,
778 dummy_fulfill_proc,
779 dummy_release_proc,
Greg Daniel7278d682018-03-16 14:57:21 -0400780 dummy_done_proc,
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400781 nullptr);
782 REPORTER_ASSERT(reporter, !image);
783 }
784
785}
786
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400787////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400788// Ensure that flushing while DDL recording doesn't cause a crash
789DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
790 GrContext* context = ctxInfo.grContext();
791
792 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
793 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
794
795 SkSurfaceCharacterization characterization;
796 SkAssertResult(s->characterize(&characterization));
797
798 SkDeferredDisplayListRecorder recorder(characterization);
799 SkCanvas* canvas = recorder.getCanvas();
800
801 canvas->flush();
802 canvas->getGrContext()->flush();
803}
Greg Danielf2336e42018-01-23 16:38:14 -0500804
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400805////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -0500806// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
807DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
808 GrContext* context = ctxInfo.grContext();
809
810 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
811 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
812
813 SkBitmap bitmap;
814 bitmap.allocPixels(ii);
815
816 SkSurfaceCharacterization characterization;
817 SkAssertResult(s->characterize(&characterization));
818
819 SkDeferredDisplayListRecorder recorder(characterization);
820
821 SkCanvas* canvas1 = recorder.getCanvas();
822
823 canvas1->clear(SK_ColorRED);
824
825 canvas1->save();
826 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
827
828 std::unique_ptr<SkDeferredDisplayList> ddl1 = recorder.detach();
829
830 SkCanvas* canvas2 = recorder.getCanvas();
831
832 SkPaint p;
833 p.setColor(SK_ColorGREEN);
834 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
835
836 std::unique_ptr<SkDeferredDisplayList> ddl2 = recorder.detach();
837
838 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
839 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
840
841 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
842 // lazy proxy are all different between the two DDLs
843 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
844
845 s->draw(ddl1.get());
846 s->draw(ddl2.get());
847
848 // Make sure the clipRect from DDL1 didn't percolate into DDL2
849 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
850 for (int y = 0; y < 32; ++y) {
851 for (int x = 0; x < 32; ++x) {
852 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
853 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
854 return; // we only really need to report the error once
855 }
856 }
857 }
858}
859
860////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -0400861// Check that the texture-specific flags (i.e., for external & rectangle textures) work
862// for promise images. As such, this is a GL-only test.
863DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
864 GrContext* context = ctxInfo.grContext();
865
866 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
867 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
868
869 SkSurfaceCharacterization characterization;
870 SkAssertResult(s->characterize(&characterization));
871
872 SkDeferredDisplayListRecorder recorder(characterization);
873
874 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Greg Daniel09c94002018-06-08 22:11:51 +0000875 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
876 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400877
Greg Daniel09c94002018-06-08 22:11:51 +0000878 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, mipMapped,
879 kTopLeft_GrSurfaceOrigin,
880 kRGBA_8888_SkColorType,
881 kPremul_SkAlphaType, nullptr,
882 dummy_fulfill_proc,
883 dummy_release_proc,
884 dummy_done_proc,
885 nullptr);
886 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipMapped::kYes) {
887 REPORTER_ASSERT(reporter, !image);
888 continue;
889 }
890 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400891
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400892 GrTextureProxy* backingProxy = ((SkImage_GpuBase*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -0400893
Greg Daniel09c94002018-06-08 22:11:51 +0000894 REPORTER_ASSERT(reporter, backingProxy->mipMapped() == mipMapped);
895 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400896 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +0000897 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400898 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +0000899 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400900 }
901 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400902}
903
904////////////////////////////////////////////////////////////////////////////////
905
Robert Phillips646f6372018-09-25 09:31:10 -0400906// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400907DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
908 GrContext* context = ctxInfo.grContext();
909
910 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
911 SkColorType colorType = static_cast<SkColorType>(ct);
912
Robert Phillips646f6372018-09-25 09:31:10 -0400913 for (int config = 0; config < kPrivateConfig1_GrPixelConfig; ++config) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400914 GrPixelConfig pixelConfig = static_cast<GrPixelConfig>(config);
915
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400916 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400917 params.setColorType(colorType);
918 params.setConfig(pixelConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400919 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400920
921 SkSurfaceCharacterization c = params.createCharacterization(context);
922 GrBackendTexture backend;
923
924 if (!c.isValid()) {
925 // TODO: this would be cool to enable but there is, currently, too much crossover
926 // allowed internally (e.g., kAlpha_8_SkColorType/kGray_8_as_Red_GrPixelConfig
927 // is permitted on GL).
928#if 0
929 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
930
931 // If we couldn't characterize the surface we shouldn't be able to create it either
932 REPORTER_ASSERT(reporter, !tmp);
933 if (tmp) {
934 tmp = nullptr;
935 params.cleanUpBackEnd(context, backend);
936 }
937#endif
938 continue;
939 }
940
941 sk_sp<SkSurface> s = params.make(context, &backend, false);
942 REPORTER_ASSERT(reporter, s);
943 if (!s) {
944 s = nullptr;
945 params.cleanUpBackEnd(context, backend);
946 continue;
947 }
948
949 SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
950 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
951
952 s = nullptr;
953 params.cleanUpBackEnd(context, backend);
954
955 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
956 REPORTER_ASSERT(reporter, s);
957 if (!s) {
958 continue;
959 }
960
961 gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
962 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
963 }
964 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400965
966}