blob: 3f03ae10698fadcec2d5d9b4ad7993b67b79c272 [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
8#include "SkTypes.h"
9
Greg Danielf2336e42018-01-23 16:38:14 -050010#include "GrBackendSurface.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040011#include "GrCaps.h"
12#include "GrContext.h"
13#include "GrContextFactory.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040014#include "GrContextPriv.h"
Greg Danielf2336e42018-01-23 16:38:14 -050015#include "GrGpu.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040016#include "GrRenderTargetContext.h"
17#include "GrRenderTargetProxy.h"
18#include "GrTextureProxy.h"
Robert Phillipsabf7b762018-03-21 12:13:37 -040019#include "GrTextureProxyPriv.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040020#include "GrTypes.h"
21#include "GrTypesPriv.h"
22#include "SkBitmap.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050023#include "SkCanvas.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040024#include "SkColorSpace.h"
25#include "SkDeferredDisplayList.h"
Robert Phillipsf54883c2018-12-18 08:29:09 -050026#include "SkDeferredDisplayListPriv.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050027#include "SkDeferredDisplayListRecorder.h"
28#include "SkGpuDevice.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040029#include "SkImage.h"
30#include "SkImageInfo.h"
Robert Phillipsabf7b762018-03-21 12:13:37 -040031#include "SkImage_Gpu.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040032#include "SkPaint.h"
33#include "SkRect.h"
34#include "SkRefCnt.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050035#include "SkSurface.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050036#include "SkSurfaceCharacterization.h"
37#include "SkSurfaceProps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040038#include "SkSurface_Gpu.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050039#include "Test.h"
Robert Phillipsbe77a022018-04-03 17:17:05 -040040#include "gl/GrGLCaps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040041#include "gl/GrGLDefines.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040042#include "gl/GrGLTypes.h"
43
Robert Phillipsfc711a22018-02-13 17:03:00 -050044#ifdef SK_VULKAN
Greg Daniel54bfb182018-11-20 17:12:36 -050045#include <vulkan/vulkan_core.h>
Robert Phillipsfc711a22018-02-13 17:03:00 -050046#endif
47
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040048#include <initializer_list>
49#include <memory>
50#include <utility>
51
Robert Phillipsbe77a022018-04-03 17:17:05 -040052// Try to create a backend format from the provided colorType and config. Return an invalid
53// backend format if the combination is infeasible.
54static GrBackendFormat create_backend_format(GrContext* context,
Brian Osman37f99882018-08-09 10:26:57 -040055 SkColorType ct,
Robert Phillipsbe77a022018-04-03 17:17:05 -040056 GrPixelConfig config) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040057 const GrCaps* caps = context->contextPriv().caps();
Robert Phillipsfc711a22018-02-13 17:03:00 -050058
59 switch (context->contextPriv().getBackend()) {
Greg Danielbdf12ad2018-10-12 09:31:11 -040060 case GrBackendApi::kOpenGL: {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040061 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(caps);
Robert Phillipsbe77a022018-04-03 17:17:05 -040062 GrGLStandard standard = glCaps->standard();
63
64 switch (ct) {
65 case kUnknown_SkColorType:
66 return GrBackendFormat();
67 case kAlpha_8_SkColorType:
68 if (kAlpha_8_as_Alpha_GrPixelConfig == config) {
69 return GrBackendFormat::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D);
70 } else if (kAlpha_8_GrPixelConfig == config ||
71 kAlpha_8_as_Red_GrPixelConfig == config) {
72 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
73 }
74 break;
75 case kRGB_565_SkColorType:
76 if (kRGB_565_GrPixelConfig == config) {
77 return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D);
78 }
79 break;
80 case kARGB_4444_SkColorType:
81 if (kRGBA_4444_GrPixelConfig == config) {
82 return GrBackendFormat::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D);
83 }
84 break;
85 case kRGBA_8888_SkColorType:
86 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -040087 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
Robert Phillipsbe77a022018-04-03 17:17:05 -040088 }
89 break;
90 case kRGB_888x_SkColorType:
91 if (kRGB_888_GrPixelConfig == config) {
92 return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D);
93 }
94 break;
95 case kBGRA_8888_SkColorType:
96 if (kBGRA_8888_GrPixelConfig == config) {
97 if (kGL_GrGLStandard == standard) {
98 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
99 } else if (kGLES_GrGLStandard == standard) {
100 return GrBackendFormat::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D);
101 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400102 }
103 break;
104 case kRGBA_1010102_SkColorType:
105 if (kRGBA_1010102_GrPixelConfig == config) {
106 return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D);
107 }
108 break;
109 case kRGB_101010x_SkColorType:
110 return GrBackendFormat();
111 case kGray_8_SkColorType:
112 if (kGray_8_as_Lum_GrPixelConfig == config) {
113 return GrBackendFormat::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D);
114 } else if (kGray_8_GrPixelConfig == config ||
115 kGray_8_as_Red_GrPixelConfig == config) {
116 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
117 }
118 break;
119 case kRGBA_F16_SkColorType:
120 if (kRGBA_half_GrPixelConfig == config) {
121 return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D);
122 }
123 break;
Mike Klein37854712018-06-26 11:43:06 -0400124 case kRGBA_F32_SkColorType:
125 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500126 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400127 }
128 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500129#ifdef SK_VULKAN
Greg Danielbdf12ad2018-10-12 09:31:11 -0400130 case GrBackendApi::kVulkan:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400131 switch (ct) {
132 case kUnknown_SkColorType:
133 return GrBackendFormat();
134 case kAlpha_8_SkColorType:
135 // TODO: what about kAlpha_8_GrPixelConfig and kAlpha_8_as_Alpha_GrPixelConfig
136 if (kAlpha_8_as_Red_GrPixelConfig == config) {
137 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
138 }
139 break;
140 case kRGB_565_SkColorType:
141 if (kRGB_565_GrPixelConfig == config) {
142 return GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16);
143 }
144 break;
145 case kARGB_4444_SkColorType:
146 if (kRGBA_4444_GrPixelConfig == config) {
147 return GrBackendFormat::MakeVk(VK_FORMAT_B4G4R4A4_UNORM_PACK16);
148 }
149 break;
150 case kRGBA_8888_SkColorType:
151 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400152 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400153 }
154 break;
155 case kRGB_888x_SkColorType:
156 if (kRGB_888_GrPixelConfig == config) {
157 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM);
158 }
159 break;
160 case kBGRA_8888_SkColorType:
161 if (kBGRA_8888_GrPixelConfig == config) {
162 return GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_UNORM);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400163 }
164 break;
165 case kRGBA_1010102_SkColorType:
166 if (kRGBA_1010102_GrPixelConfig == config) {
167 return GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
168 }
169 break;
170 case kRGB_101010x_SkColorType:
171 return GrBackendFormat();
172 case kGray_8_SkColorType:
173 // TODO: what about kAlpha_8_GrPixelConfig and kGray_8_as_Lum_GrPixelConfig?
174 if (kGray_8_as_Red_GrPixelConfig == config) {
175 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
176 }
177 break;
178 case kRGBA_F16_SkColorType:
179 if (kRGBA_half_GrPixelConfig == config) {
180 return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
181 }
182 break;
Mike Klein37854712018-06-26 11:43:06 -0400183 case kRGBA_F32_SkColorType:
184 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500185 }
186 break;
187#endif
Greg Danielbdf12ad2018-10-12 09:31:11 -0400188 case GrBackendApi::kMock:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400189 switch (ct) {
190 case kUnknown_SkColorType:
191 return GrBackendFormat();
192 case kAlpha_8_SkColorType:
193 if (kAlpha_8_GrPixelConfig == config ||
194 kAlpha_8_as_Alpha_GrPixelConfig == config ||
195 kAlpha_8_as_Red_GrPixelConfig == config) {
196 return GrBackendFormat::MakeMock(config);
197 }
198 break;
199 case kRGB_565_SkColorType:
200 if (kRGB_565_GrPixelConfig == config) {
201 return GrBackendFormat::MakeMock(config);
202 }
203 break;
204 case kARGB_4444_SkColorType:
205 if (kRGBA_4444_GrPixelConfig == config) {
206 return GrBackendFormat::MakeMock(config);
207 }
208 break;
209 case kRGBA_8888_SkColorType:
210 if (kRGBA_8888_GrPixelConfig == config) {
Brian Osman37f99882018-08-09 10:26:57 -0400211 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400212 }
213 break;
214 case kRGB_888x_SkColorType:
215 if (kRGB_888_GrPixelConfig == config) {
216 return GrBackendFormat::MakeMock(config);
217 }
218 break;
219 case kBGRA_8888_SkColorType:
220 if (kBGRA_8888_GrPixelConfig == config) {
221 return GrBackendFormat::MakeMock(config);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400222 }
223 break;
224 case kRGBA_1010102_SkColorType:
225 if (kRGBA_1010102_GrPixelConfig == config) {
226 return GrBackendFormat::MakeMock(config);
227 }
228 break;
229 case kRGB_101010x_SkColorType:
230 return GrBackendFormat();
231 case kGray_8_SkColorType:
232 if (kGray_8_GrPixelConfig == config ||
233 kGray_8_as_Lum_GrPixelConfig == config ||
234 kGray_8_as_Red_GrPixelConfig == config) {
235 return GrBackendFormat::MakeMock(config);
236 }
237 break;
238 case kRGBA_F16_SkColorType:
239 if (kRGBA_half_GrPixelConfig == config) {
240 return GrBackendFormat::MakeMock(config);
241 }
242 break;
Mike Klein37854712018-06-26 11:43:06 -0400243 case kRGBA_F32_SkColorType:
244 return GrBackendFormat();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500245 }
246 break;
247 default:
248 return GrBackendFormat(); // return an invalid format
249 }
250
251 return GrBackendFormat(); // return an invalid format
252}
253
254
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500255class SurfaceParameters {
256public:
Robert Phillipse8fabb22018-02-04 14:33:21 -0500257 static const int kNumParams = 9;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500258 static const int kSampleCount = 5;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500259 static const int kMipMipCount = 8;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500260
Robert Phillipsbe77a022018-04-03 17:17:05 -0400261 SurfaceParameters(const GrCaps* caps)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500262 : fWidth(64)
263 , fHeight(64)
264 , fOrigin(kTopLeft_GrSurfaceOrigin)
265 , fColorType(kRGBA_8888_SkColorType)
Brian Osman37f99882018-08-09 10:26:57 -0400266 , fConfig(kRGBA_8888_GrPixelConfig)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500267 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -0500268 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -0500269 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
270 , fShouldCreateMipMaps(true) {
271 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500272
273 int sampleCount() const { return fSampleCount; }
274
Robert Phillipsbe77a022018-04-03 17:17:05 -0400275 void setColorType(SkColorType ct) { fColorType = ct; }
276 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
277 void setConfig(GrPixelConfig config) { fConfig = config; }
278
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500279 // Modify the SurfaceParameters in just one way
280 void modify(int i) {
281 switch (i) {
282 case 0:
283 fWidth = 63;
284 break;
285 case 1:
286 fHeight = 63;
287 break;
288 case 2:
289 fOrigin = kBottomLeft_GrSurfaceOrigin;
290 break;
291 case 3:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400292 // The color type and config need to be changed together.
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500293 fColorType = kRGBA_F16_SkColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400294 fConfig = kRGBA_half_GrPixelConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500295 break;
296 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400297 // This just needs to be a colorSpace different from that returned by MakeSRGB().
298 // In this case we just change the gamut.
Robert Phillipsc1267c62018-04-04 11:12:39 -0400299 fColorSpace = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
300 SkColorSpace::kAdobeRGB_Gamut);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500301 break;
302 case kSampleCount:
303 fSampleCount = 4;
304 break;
305 case 6:
306 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
307 break;
308 case 7:
309 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
310 kUnknown_SkPixelGeometry);
311 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500312 case 8:
313 fShouldCreateMipMaps = false;
314 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500315 }
316 }
317
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400318 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500319 int maxResourceCount;
320 size_t maxResourceBytes;
321 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
322
323 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
324 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
325 kPremul_SkAlphaType, fColorSpace);
326
Brian Osman37f99882018-08-09 10:26:57 -0400327 GrBackendFormat backendFormat = create_backend_format(context, fColorType, fConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400328 if (!backendFormat.isValid()) {
329 return SkSurfaceCharacterization();
330 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500331
332 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
333 maxResourceBytes, ii, backendFormat, fSampleCount,
334 fOrigin, fSurfaceProps, fShouldCreateMipMaps);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400335 return c;
336 }
337
338 // Create a DDL whose characterization captures the current settings
339 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
340 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500341 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500342
343 SkDeferredDisplayListRecorder r(c);
344 SkCanvas* canvas = r.getCanvas();
345 if (!canvas) {
346 return nullptr;
347 }
348
349 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
350 return r.detach();
351 }
352
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500353 // Create the surface with the current set of parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400354 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend,
355 bool nonTextureable) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500356 GrGpu* gpu = context->contextPriv().getGpu();
357
Robert Phillipsbe77a022018-04-03 17:17:05 -0400358 GrMipMapped mipmapped = nonTextureable
359 ? GrMipMapped::kNo
360 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500361
362 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillips646f6372018-09-25 09:31:10 -0400363 fColorType, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500364 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
365 return nullptr;
366 }
367
Robert Phillipsbe77a022018-04-03 17:17:05 -0400368 sk_sp<SkSurface> surface;
369 if (nonTextureable) {
370 // Create a surface w/ the current parameters but make it non-textureable
371 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
372 context, *backend, fOrigin, fSampleCount, fColorType,
373 fColorSpace, &fSurfaceProps);
374 } else {
375 surface = SkSurface::MakeFromBackendTexture(
376 context, *backend, fOrigin, fSampleCount, fColorType,
377 fColorSpace, &fSurfaceProps);
378 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500379
380 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500381 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500382 return nullptr;
383 }
384
385 return surface;
386 }
387
Brian Salomon26102cb2018-03-09 09:33:19 -0500388 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500389 GrGpu* gpu = context->contextPriv().getGpu();
390
391 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500392 }
393
394private:
395 int fWidth;
396 int fHeight;
397 GrSurfaceOrigin fOrigin;
398 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400399 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500400 sk_sp<SkColorSpace> fColorSpace;
401 int fSampleCount;
402 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500403 bool fShouldCreateMipMaps;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500404};
405
Robert Phillipsc1267c62018-04-04 11:12:39 -0400406// Test out operator== && operator!=
407DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
408 GrContext* context = ctxInfo.grContext();
409
410 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400411 SurfaceParameters params1(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400412 params1.modify(i);
413
414 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
415 if (!char1.isValid()) {
416 continue; // can happen on some platforms (ChromeOS)
417 }
418
419 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400420 SurfaceParameters params2(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400421 params2.modify(j);
422
423 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
424 if (!char2.isValid()) {
425 continue; // can happen on some platforms (ChromeOS)
426 }
427
428 if (i == j) {
429 REPORTER_ASSERT(reporter, char1 == char2);
430 } else {
431 REPORTER_ASSERT(reporter, char1 != char2);
432 }
433
434 }
435 }
436
437 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400438 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400439
440 SkSurfaceCharacterization valid = params.createCharacterization(context);
441 SkASSERT(valid.isValid());
442
443 SkSurfaceCharacterization inval1, inval2;
444 SkASSERT(!inval1.isValid() && !inval2.isValid());
445
446 REPORTER_ASSERT(reporter, inval1 != inval2);
447 REPORTER_ASSERT(reporter, valid != inval1);
448 REPORTER_ASSERT(reporter, inval1 != valid);
449 }
450}
451
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400452////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500453// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400454DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500455 GrContext* context = ctxInfo.grContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400456 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500457
Robert Phillips9e441ee2018-02-01 15:14:55 -0500458 // Create a bitmap that we can readback into
459 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
460 kPremul_SkAlphaType);
461 SkBitmap bitmap;
462 bitmap.allocPixels(imageInfo);
463
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500464 std::unique_ptr<SkDeferredDisplayList> ddl;
465
466 // First, create a DDL using the stock SkSurface parameters
467 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400468 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500469
Robert Phillipse8fabb22018-02-04 14:33:21 -0500470 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500471 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500472
473 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400474 GrBackendTexture backend;
475 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500476 if (!s) {
477 return;
478 }
479
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500480 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500481 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400482 context->flush();
483 gpu->testingOnly_flushGpuAndSync();
484 s = nullptr;
485 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500486 }
487
488 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
489 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400490 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500491 params.modify(i);
492
Robert Phillipsbe77a022018-04-03 17:17:05 -0400493 GrBackendTexture backend;
494 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500495 if (!s) {
496 continue;
497 }
498
499 if (SurfaceParameters::kSampleCount == i) {
500 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
501
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400502 int supportedSampleCount = context->contextPriv().caps()->getRenderTargetSampleCount(
503 params.sampleCount(),
504 gpuSurf->getDevice()
505 ->accessRenderTargetContext()
506 ->asRenderTargetProxy()
507 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500508 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500509 // If changing the sample count won't result in a different
510 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400511 s = nullptr;
512 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500513 continue;
514 }
515 }
516
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400517 if (SurfaceParameters::kMipMipCount == i &&
518 !context->contextPriv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400519 // If changing the mipmap setting won't result in a different surface characterization,
520 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400521 s = nullptr;
522 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500523 continue;
524 }
525
526 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
527 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400528
529 context->flush();
530 gpu->testingOnly_flushGpuAndSync();
531 s = nullptr;
532 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500533 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500534
535 // Next test the compatibility of resource cache parameters
536 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400537 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400538 GrBackendTexture backend;
539
540 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500541
542 int maxResourceCount;
543 size_t maxResourceBytes;
544 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
545
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500546 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
547 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
548
Robert Phillips9e441ee2018-02-01 15:14:55 -0500549 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
550 // For now, DDLs are drawn once.
551#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500552 // resource limits >= those at characterization time are accepted
553 context->setResourceCacheLimits(2*maxResourceCount, 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, 2*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);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500560
561 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
562 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500563 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
564#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400565
566 context->flush();
567 gpu->testingOnly_flushGpuAndSync();
568 s = nullptr;
569 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500570 }
571
Robert Phillipse8fabb22018-02-04 14:33:21 -0500572 // Test that the textureability of the DDL characterization can block a DDL draw
573 {
574 GrBackendTexture backend;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400575 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400576 sk_sp<SkSurface> s = params.make(context, &backend, true);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500577 if (s) {
578 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
579
Robert Phillipsbe77a022018-04-03 17:17:05 -0400580 context->flush();
581 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500582 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500583 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500584 }
585 }
586
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500587 // Make sure non-GPU-backed surfaces fail characterization
588 {
589 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
590
591 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
592 SkSurfaceCharacterization c;
593 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
594 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500595
596 // Exercise the createResized method
597 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400598 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400599 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500600
Robert Phillipsbe77a022018-04-03 17:17:05 -0400601 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips94458ee2018-03-06 13:41:51 -0500602 if (!s) {
603 return;
604 }
605
606 SkSurfaceCharacterization char0;
607 SkAssertResult(s->characterize(&char0));
608
609 // Too small
610 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
611 REPORTER_ASSERT(reporter, !char1.isValid());
612
613 // Too large
614 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
615 REPORTER_ASSERT(reporter, !char2.isValid());
616
617 // Just right
618 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
619 REPORTER_ASSERT(reporter, char3.isValid());
620 REPORTER_ASSERT(reporter, 32 == char3.width());
621 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400622
623 s = nullptr;
624 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500625 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500626}
627
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400628////////////////////////////////////////////////////////////////////////////////
629// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
630// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400631DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400632 GrContext* context = ctxInfo.grContext();
633
634 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400635 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400636 params.modify(i);
637
638 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400639 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400640
Robert Phillipsbe77a022018-04-03 17:17:05 -0400641 if (!c.isValid()) {
642 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
643
644 // If we couldn't characterize the surface we shouldn't be able to create it either
645 REPORTER_ASSERT(reporter, !tmp);
646 if (tmp) {
647 tmp = nullptr;
648 params.cleanUpBackEnd(context, backend);
649 }
650 continue;
651 }
652
653 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400654 if (!s) {
655 REPORTER_ASSERT(reporter, !c.isValid());
656 continue;
657 }
658
659 REPORTER_ASSERT(reporter, c.isValid());
660
661 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
662 REPORTER_ASSERT(reporter, s);
663
664 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
665 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400666
667 s = nullptr;
668 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400669 }
670}
671
672////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500673static constexpr int kSize = 8;
674
675struct TextureReleaseChecker {
676 TextureReleaseChecker() : fReleaseCount(0) {}
677 int fReleaseCount;
678 static void Release(void* self) {
679 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
680 }
681};
682
683enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
684
685// This tests the ability to create and use wrapped textures in a DDL world
686DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
687 GrContext* context = ctxInfo.grContext();
688 GrGpu* gpu = context->contextPriv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500689 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400690 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500691 if (!backendTex.isValid()) {
692 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500693 }
Brian Salomonf7778972018-03-08 10:13:17 -0500694
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400695 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400696 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500697
Robert Phillipsbe77a022018-04-03 17:17:05 -0400698 sk_sp<SkSurface> s = params.make(context, &backend, false);
Brian Salomonf7778972018-03-08 10:13:17 -0500699 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500700 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500701 return;
702 }
703
704 SkSurfaceCharacterization c;
705 SkAssertResult(s->characterize(&c));
706
707 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
708
709 SkCanvas* canvas = recorder->getCanvas();
710 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400711 s = nullptr;
712 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500713 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500714 return;
715 }
716
717 GrContext* deferredContext = canvas->getGrContext();
718 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400719 s = nullptr;
720 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500721 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500722 return;
723 }
724
725 // Wrapped Backend Textures are not supported in DDL
726 sk_sp<SkImage> image =
727 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
728 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
729 REPORTER_ASSERT(reporter, !image);
730
731 TextureReleaseChecker releaseChecker;
732 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
733 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
734 TextureReleaseChecker::Release, &releaseChecker);
735 REPORTER_ASSERT(reporter, !image);
736
Brian Salomon26102cb2018-03-09 09:33:19 -0500737 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400738
739 s = nullptr;
740 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500741}
742
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400743static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); }
744static void dummy_release_proc(void*) { SkASSERT(0); }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400745static void dummy_done_proc(void*) { }
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400746
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400747////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400748// Test out the behavior of an invalid DDLRecorder
749DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
750 GrContext* context = ctxInfo.grContext();
751
752 {
753 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
754 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
755
756 SkSurfaceCharacterization characterization;
757 SkAssertResult(s->characterize(&characterization));
758
759 // never calling getCanvas means the backing surface is never allocated
760 SkDeferredDisplayListRecorder recorder(characterization);
761 }
762
763 {
764 SkSurfaceCharacterization invalid;
765
766 SkDeferredDisplayListRecorder recorder(invalid);
767
768 const SkSurfaceCharacterization c = recorder.characterization();
769 REPORTER_ASSERT(reporter, !c.isValid());
770 REPORTER_ASSERT(reporter, !recorder.getCanvas());
771 REPORTER_ASSERT(reporter, !recorder.detach());
772
Robert Phillipsbe77a022018-04-03 17:17:05 -0400773 GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType,
Brian Osman37f99882018-08-09 10:26:57 -0400774 kRGBA_8888_GrPixelConfig);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400775 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo,
776 kTopLeft_GrSurfaceOrigin,
777 kRGBA_8888_SkColorType,
778 kPremul_SkAlphaType, nullptr,
779 dummy_fulfill_proc,
780 dummy_release_proc,
Greg Daniel7278d682018-03-16 14:57:21 -0400781 dummy_done_proc,
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400782 nullptr);
783 REPORTER_ASSERT(reporter, !image);
784 }
785
786}
787
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400788////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400789// Ensure that flushing while DDL recording doesn't cause a crash
790DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
791 GrContext* context = ctxInfo.grContext();
792
793 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
794 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
795
796 SkSurfaceCharacterization characterization;
797 SkAssertResult(s->characterize(&characterization));
798
799 SkDeferredDisplayListRecorder recorder(characterization);
800 SkCanvas* canvas = recorder.getCanvas();
801
802 canvas->flush();
803 canvas->getGrContext()->flush();
804}
Greg Danielf2336e42018-01-23 16:38:14 -0500805
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400806////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -0500807// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
808DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
809 GrContext* context = ctxInfo.grContext();
810
811 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
812 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
813
814 SkBitmap bitmap;
815 bitmap.allocPixels(ii);
816
817 SkSurfaceCharacterization characterization;
818 SkAssertResult(s->characterize(&characterization));
819
820 SkDeferredDisplayListRecorder recorder(characterization);
821
822 SkCanvas* canvas1 = recorder.getCanvas();
823
824 canvas1->clear(SK_ColorRED);
825
826 canvas1->save();
827 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
828
829 std::unique_ptr<SkDeferredDisplayList> ddl1 = recorder.detach();
830
831 SkCanvas* canvas2 = recorder.getCanvas();
832
833 SkPaint p;
834 p.setColor(SK_ColorGREEN);
835 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
836
837 std::unique_ptr<SkDeferredDisplayList> ddl2 = recorder.detach();
838
839 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
840 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
841
842 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
843 // lazy proxy are all different between the two DDLs
844 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
845
846 s->draw(ddl1.get());
847 s->draw(ddl2.get());
848
849 // Make sure the clipRect from DDL1 didn't percolate into DDL2
850 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
851 for (int y = 0; y < 32; ++y) {
852 for (int x = 0; x < 32; ++x) {
853 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
854 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
855 return; // we only really need to report the error once
856 }
857 }
858 }
859}
860
861////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -0400862// Check that the texture-specific flags (i.e., for external & rectangle textures) work
863// for promise images. As such, this is a GL-only test.
864DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
865 GrContext* context = ctxInfo.grContext();
866
867 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
868 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
869
870 SkSurfaceCharacterization characterization;
871 SkAssertResult(s->characterize(&characterization));
872
873 SkDeferredDisplayListRecorder recorder(characterization);
874
875 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Greg Daniel09c94002018-06-08 22:11:51 +0000876 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
877 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400878
Greg Daniel09c94002018-06-08 22:11:51 +0000879 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, mipMapped,
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 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipMapped::kYes) {
888 REPORTER_ASSERT(reporter, !image);
889 continue;
890 }
891 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400892
Jim Van Verth21bd60d2018-10-12 15:00:20 -0400893 GrTextureProxy* backingProxy = ((SkImage_GpuBase*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -0400894
Greg Daniel09c94002018-06-08 22:11:51 +0000895 REPORTER_ASSERT(reporter, backingProxy->mipMapped() == mipMapped);
896 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400897 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +0000898 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400899 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +0000900 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400901 }
902 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400903}
904
905////////////////////////////////////////////////////////////////////////////////
906
Robert Phillips646f6372018-09-25 09:31:10 -0400907// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400908DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
909 GrContext* context = ctxInfo.grContext();
910
911 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
912 SkColorType colorType = static_cast<SkColorType>(ct);
913
Robert Phillips646f6372018-09-25 09:31:10 -0400914 for (int config = 0; config < kPrivateConfig1_GrPixelConfig; ++config) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400915 GrPixelConfig pixelConfig = static_cast<GrPixelConfig>(config);
916
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400917 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400918 params.setColorType(colorType);
919 params.setConfig(pixelConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400920 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400921
922 SkSurfaceCharacterization c = params.createCharacterization(context);
923 GrBackendTexture backend;
924
925 if (!c.isValid()) {
926 // TODO: this would be cool to enable but there is, currently, too much crossover
927 // allowed internally (e.g., kAlpha_8_SkColorType/kGray_8_as_Red_GrPixelConfig
928 // is permitted on GL).
929#if 0
930 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
931
932 // If we couldn't characterize the surface we shouldn't be able to create it either
933 REPORTER_ASSERT(reporter, !tmp);
934 if (tmp) {
935 tmp = nullptr;
936 params.cleanUpBackEnd(context, backend);
937 }
938#endif
939 continue;
940 }
941
942 sk_sp<SkSurface> s = params.make(context, &backend, false);
943 REPORTER_ASSERT(reporter, s);
944 if (!s) {
945 s = nullptr;
946 params.cleanUpBackEnd(context, backend);
947 continue;
948 }
949
950 SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
951 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
952
953 s = nullptr;
954 params.cleanUpBackEnd(context, backend);
955
956 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
957 REPORTER_ASSERT(reporter, s);
958 if (!s) {
959 continue;
960 }
961
962 gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
963 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
964 }
965 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400966
967}