blob: 8e49446408391a5dd9f33b835acc35b6f7ec54d2 [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.
Brian Osman82ebe042019-01-04 17:03:00 -0500299 fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500300 break;
301 case kSampleCount:
302 fSampleCount = 4;
303 break;
304 case 6:
305 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
306 break;
307 case 7:
308 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
309 kUnknown_SkPixelGeometry);
310 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500311 case 8:
312 fShouldCreateMipMaps = false;
313 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500314 }
315 }
316
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400317 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500318 int maxResourceCount;
319 size_t maxResourceBytes;
320 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
321
322 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
323 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
324 kPremul_SkAlphaType, fColorSpace);
325
Brian Osman37f99882018-08-09 10:26:57 -0400326 GrBackendFormat backendFormat = create_backend_format(context, fColorType, fConfig);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400327 if (!backendFormat.isValid()) {
328 return SkSurfaceCharacterization();
329 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500330
331 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
332 maxResourceBytes, ii, backendFormat, fSampleCount,
333 fOrigin, fSurfaceProps, fShouldCreateMipMaps);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400334 return c;
335 }
336
337 // Create a DDL whose characterization captures the current settings
338 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
339 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500340 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500341
342 SkDeferredDisplayListRecorder r(c);
343 SkCanvas* canvas = r.getCanvas();
344 if (!canvas) {
345 return nullptr;
346 }
347
348 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
349 return r.detach();
350 }
351
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500352 // Create the surface with the current set of parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400353 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend,
354 bool nonTextureable) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500355 GrGpu* gpu = context->contextPriv().getGpu();
356
Robert Phillipsbe77a022018-04-03 17:17:05 -0400357 GrMipMapped mipmapped = nonTextureable
358 ? GrMipMapped::kNo
359 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500360
361 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillips646f6372018-09-25 09:31:10 -0400362 fColorType, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500363 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
364 return nullptr;
365 }
366
Robert Phillipsbe77a022018-04-03 17:17:05 -0400367 sk_sp<SkSurface> surface;
368 if (nonTextureable) {
369 // Create a surface w/ the current parameters but make it non-textureable
370 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
371 context, *backend, fOrigin, fSampleCount, fColorType,
372 fColorSpace, &fSurfaceProps);
373 } else {
374 surface = SkSurface::MakeFromBackendTexture(
375 context, *backend, fOrigin, fSampleCount, fColorType,
376 fColorSpace, &fSurfaceProps);
377 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500378
379 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500380 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500381 return nullptr;
382 }
383
384 return surface;
385 }
386
Brian Salomon26102cb2018-03-09 09:33:19 -0500387 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500388 GrGpu* gpu = context->contextPriv().getGpu();
389
390 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500391 }
392
393private:
394 int fWidth;
395 int fHeight;
396 GrSurfaceOrigin fOrigin;
397 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400398 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500399 sk_sp<SkColorSpace> fColorSpace;
400 int fSampleCount;
401 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500402 bool fShouldCreateMipMaps;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500403};
404
Robert Phillipsc1267c62018-04-04 11:12:39 -0400405// Test out operator== && operator!=
406DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
407 GrContext* context = ctxInfo.grContext();
408
409 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400410 SurfaceParameters params1(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400411 params1.modify(i);
412
413 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
414 if (!char1.isValid()) {
415 continue; // can happen on some platforms (ChromeOS)
416 }
417
418 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400419 SurfaceParameters params2(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400420 params2.modify(j);
421
422 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
423 if (!char2.isValid()) {
424 continue; // can happen on some platforms (ChromeOS)
425 }
426
427 if (i == j) {
428 REPORTER_ASSERT(reporter, char1 == char2);
429 } else {
430 REPORTER_ASSERT(reporter, char1 != char2);
431 }
432
433 }
434 }
435
436 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400437 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400438
439 SkSurfaceCharacterization valid = params.createCharacterization(context);
440 SkASSERT(valid.isValid());
441
442 SkSurfaceCharacterization inval1, inval2;
443 SkASSERT(!inval1.isValid() && !inval2.isValid());
444
445 REPORTER_ASSERT(reporter, inval1 != inval2);
446 REPORTER_ASSERT(reporter, valid != inval1);
447 REPORTER_ASSERT(reporter, inval1 != valid);
448 }
449}
450
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400451////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500452// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400453DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500454 GrContext* context = ctxInfo.grContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400455 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500456
Robert Phillips9e441ee2018-02-01 15:14:55 -0500457 // Create a bitmap that we can readback into
458 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
459 kPremul_SkAlphaType);
460 SkBitmap bitmap;
461 bitmap.allocPixels(imageInfo);
462
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500463 std::unique_ptr<SkDeferredDisplayList> ddl;
464
465 // First, create a DDL using the stock SkSurface parameters
466 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400467 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500468
Robert Phillipse8fabb22018-02-04 14:33:21 -0500469 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500470 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500471
472 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400473 GrBackendTexture backend;
474 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500475 if (!s) {
476 return;
477 }
478
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500479 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500480 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400481 context->flush();
482 gpu->testingOnly_flushGpuAndSync();
483 s = nullptr;
484 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500485 }
486
487 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
488 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400489 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500490 params.modify(i);
491
Robert Phillipsbe77a022018-04-03 17:17:05 -0400492 GrBackendTexture backend;
493 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500494 if (!s) {
495 continue;
496 }
497
498 if (SurfaceParameters::kSampleCount == i) {
499 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
500
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400501 int supportedSampleCount = context->contextPriv().caps()->getRenderTargetSampleCount(
502 params.sampleCount(),
503 gpuSurf->getDevice()
504 ->accessRenderTargetContext()
505 ->asRenderTargetProxy()
506 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500507 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500508 // If changing the sample count won't result in a different
509 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400510 s = nullptr;
511 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500512 continue;
513 }
514 }
515
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400516 if (SurfaceParameters::kMipMipCount == i &&
517 !context->contextPriv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400518 // If changing the mipmap setting won't result in a different surface characterization,
519 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400520 s = nullptr;
521 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500522 continue;
523 }
524
525 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
526 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400527
528 context->flush();
529 gpu->testingOnly_flushGpuAndSync();
530 s = nullptr;
531 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500532 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500533
534 // Next test the compatibility of resource cache parameters
535 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400536 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400537 GrBackendTexture backend;
538
539 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500540
541 int maxResourceCount;
542 size_t maxResourceBytes;
543 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
544
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500545 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
546 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
547
Robert Phillips9e441ee2018-02-01 15:14:55 -0500548 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
549 // For now, DDLs are drawn once.
550#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500551 // resource limits >= those at characterization time are accepted
552 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
553 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500554 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500555
556 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
557 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500558 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500559
560 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
561 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500562 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
563#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400564
565 context->flush();
566 gpu->testingOnly_flushGpuAndSync();
567 s = nullptr;
568 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500569 }
570
Robert Phillipse8fabb22018-02-04 14:33:21 -0500571 // Test that the textureability of the DDL characterization can block a DDL draw
572 {
573 GrBackendTexture backend;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400574 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400575 sk_sp<SkSurface> s = params.make(context, &backend, true);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500576 if (s) {
577 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
578
Robert Phillipsbe77a022018-04-03 17:17:05 -0400579 context->flush();
580 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500581 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500582 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500583 }
584 }
585
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500586 // Make sure non-GPU-backed surfaces fail characterization
587 {
588 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
589
590 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
591 SkSurfaceCharacterization c;
592 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
593 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500594
595 // Exercise the createResized method
596 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400597 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400598 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500599
Robert Phillipsbe77a022018-04-03 17:17:05 -0400600 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips94458ee2018-03-06 13:41:51 -0500601 if (!s) {
602 return;
603 }
604
605 SkSurfaceCharacterization char0;
606 SkAssertResult(s->characterize(&char0));
607
608 // Too small
609 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
610 REPORTER_ASSERT(reporter, !char1.isValid());
611
612 // Too large
613 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
614 REPORTER_ASSERT(reporter, !char2.isValid());
615
616 // Just right
617 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
618 REPORTER_ASSERT(reporter, char3.isValid());
619 REPORTER_ASSERT(reporter, 32 == char3.width());
620 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400621
622 s = nullptr;
623 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500624 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500625}
626
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400627////////////////////////////////////////////////////////////////////////////////
628// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
629// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400630DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400631 GrContext* context = ctxInfo.grContext();
632
633 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400634 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400635 params.modify(i);
636
637 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400638 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400639
Robert Phillipsbe77a022018-04-03 17:17:05 -0400640 if (!c.isValid()) {
641 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
642
643 // If we couldn't characterize the surface we shouldn't be able to create it either
644 REPORTER_ASSERT(reporter, !tmp);
645 if (tmp) {
646 tmp = nullptr;
647 params.cleanUpBackEnd(context, backend);
648 }
649 continue;
650 }
651
652 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400653 if (!s) {
654 REPORTER_ASSERT(reporter, !c.isValid());
655 continue;
656 }
657
658 REPORTER_ASSERT(reporter, c.isValid());
659
660 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
661 REPORTER_ASSERT(reporter, s);
662
663 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
664 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400665
666 s = nullptr;
667 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400668 }
669}
670
671////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500672static constexpr int kSize = 8;
673
674struct TextureReleaseChecker {
675 TextureReleaseChecker() : fReleaseCount(0) {}
676 int fReleaseCount;
677 static void Release(void* self) {
678 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
679 }
680};
681
682enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
683
684// This tests the ability to create and use wrapped textures in a DDL world
685DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
686 GrContext* context = ctxInfo.grContext();
687 GrGpu* gpu = context->contextPriv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500688 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400689 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Brian Salomonf7778972018-03-08 10:13:17 -0500690 if (!backendTex.isValid()) {
691 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500692 }
Brian Salomonf7778972018-03-08 10:13:17 -0500693
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400694 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400695 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500696
Robert Phillipsbe77a022018-04-03 17:17:05 -0400697 sk_sp<SkSurface> s = params.make(context, &backend, false);
Brian Salomonf7778972018-03-08 10:13:17 -0500698 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500699 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500700 return;
701 }
702
703 SkSurfaceCharacterization c;
704 SkAssertResult(s->characterize(&c));
705
706 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
707
708 SkCanvas* canvas = recorder->getCanvas();
709 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400710 s = nullptr;
711 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500712 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500713 return;
714 }
715
716 GrContext* deferredContext = canvas->getGrContext();
717 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400718 s = nullptr;
719 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500720 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500721 return;
722 }
723
724 // Wrapped Backend Textures are not supported in DDL
725 sk_sp<SkImage> image =
726 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
727 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
728 REPORTER_ASSERT(reporter, !image);
729
730 TextureReleaseChecker releaseChecker;
731 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
732 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
733 TextureReleaseChecker::Release, &releaseChecker);
734 REPORTER_ASSERT(reporter, !image);
735
Brian Salomon26102cb2018-03-09 09:33:19 -0500736 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400737
738 s = nullptr;
739 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500740}
741
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400742static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); }
743static void dummy_release_proc(void*) { SkASSERT(0); }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400744static 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}