blob: 697f00328f7c81453395ab8800c15f79a76cf7c6 [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 Phillips7ffbcf92017-12-04 12:52:46 -050026#include "SkDeferredDisplayListRecorder.h"
27#include "SkGpuDevice.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040028#include "SkImage.h"
29#include "SkImageInfo.h"
Robert Phillipsabf7b762018-03-21 12:13:37 -040030#include "SkImage_Gpu.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040031#include "SkPaint.h"
32#include "SkRect.h"
33#include "SkRefCnt.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050034#include "SkSurface.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050035#include "SkSurfaceCharacterization.h"
36#include "SkSurfaceProps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040037#include "SkSurface_Gpu.h"
Robert Phillips7ffbcf92017-12-04 12:52:46 -050038#include "Test.h"
Robert Phillipsbe77a022018-04-03 17:17:05 -040039#include "gl/GrGLCaps.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -040040#include "gl/GrGLDefines.h"
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040041#include "gl/GrGLTypes.h"
42
Robert Phillipsfc711a22018-02-13 17:03:00 -050043#ifdef SK_VULKAN
44#include "vk/GrVkDefines.h"
45#endif
46
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040047#include <initializer_list>
48#include <memory>
49#include <utility>
50
Robert Phillipsbe77a022018-04-03 17:17:05 -040051// Try to create a backend format from the provided colorType and config. Return an invalid
52// backend format if the combination is infeasible.
53static GrBackendFormat create_backend_format(GrContext* context,
54 SkColorType ct, SkColorSpace* cs,
55 GrPixelConfig config) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040056 const GrCaps* caps = context->contextPriv().caps();
Robert Phillipsfc711a22018-02-13 17:03:00 -050057
Robert Phillipsbe77a022018-04-03 17:17:05 -040058 // TODO: what should be done if we have a colorspace that doesn't have a gammaCloseToSRGB?
59
Robert Phillipsfc711a22018-02-13 17:03:00 -050060 switch (context->contextPriv().getBackend()) {
Robert Phillipsbe77a022018-04-03 17:17:05 -040061 case kOpenGL_GrBackend: {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040062 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(caps);
Robert Phillipsbe77a022018-04-03 17:17:05 -040063 GrGLStandard standard = glCaps->standard();
64
65 switch (ct) {
66 case kUnknown_SkColorType:
67 return GrBackendFormat();
68 case kAlpha_8_SkColorType:
69 if (kAlpha_8_as_Alpha_GrPixelConfig == config) {
70 return GrBackendFormat::MakeGL(GR_GL_ALPHA8, GR_GL_TEXTURE_2D);
71 } else if (kAlpha_8_GrPixelConfig == config ||
72 kAlpha_8_as_Red_GrPixelConfig == config) {
73 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
74 }
75 break;
76 case kRGB_565_SkColorType:
77 if (kRGB_565_GrPixelConfig == config) {
78 return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_2D);
79 }
80 break;
81 case kARGB_4444_SkColorType:
82 if (kRGBA_4444_GrPixelConfig == config) {
83 return GrBackendFormat::MakeGL(GR_GL_RGBA4, GR_GL_TEXTURE_2D);
84 }
85 break;
86 case kRGBA_8888_SkColorType:
87 if (kRGBA_8888_GrPixelConfig == config) {
88 if (!cs || (cs->gammaCloseToSRGB() && !caps->srgbSupport())) {
89 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
90 }
91 } else if (kSRGBA_8888_GrPixelConfig == config) {
92 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
93 return GrBackendFormat::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D);
94 }
95 }
96 break;
97 case kRGB_888x_SkColorType:
98 if (kRGB_888_GrPixelConfig == config) {
99 return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_2D);
100 }
101 break;
102 case kBGRA_8888_SkColorType:
103 if (kBGRA_8888_GrPixelConfig == config) {
104 if (kGL_GrGLStandard == standard) {
105 return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
106 } else if (kGLES_GrGLStandard == standard) {
107 return GrBackendFormat::MakeGL(GR_GL_BGRA8, GR_GL_TEXTURE_2D);
108 }
109 } else if (kSBGRA_8888_GrPixelConfig == config) {
110 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
111 return GrBackendFormat::MakeGL(GR_GL_SRGB8_ALPHA8, GR_GL_TEXTURE_2D);
112 }
113 }
114 break;
115 case kRGBA_1010102_SkColorType:
116 if (kRGBA_1010102_GrPixelConfig == config) {
117 return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_2D);
118 }
119 break;
120 case kRGB_101010x_SkColorType:
121 return GrBackendFormat();
122 case kGray_8_SkColorType:
123 if (kGray_8_as_Lum_GrPixelConfig == config) {
124 return GrBackendFormat::MakeGL(GR_GL_LUMINANCE8, GR_GL_TEXTURE_2D);
125 } else if (kGray_8_GrPixelConfig == config ||
126 kGray_8_as_Red_GrPixelConfig == config) {
127 return GrBackendFormat::MakeGL(GR_GL_R8, GR_GL_TEXTURE_2D);
128 }
129 break;
130 case kRGBA_F16_SkColorType:
131 if (kRGBA_half_GrPixelConfig == config) {
132 return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D);
133 }
134 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500135 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400136 }
137 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500138#ifdef SK_VULKAN
139 case kVulkan_GrBackend:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400140 switch (ct) {
141 case kUnknown_SkColorType:
142 return GrBackendFormat();
143 case kAlpha_8_SkColorType:
144 // TODO: what about kAlpha_8_GrPixelConfig and kAlpha_8_as_Alpha_GrPixelConfig
145 if (kAlpha_8_as_Red_GrPixelConfig == config) {
146 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
147 }
148 break;
149 case kRGB_565_SkColorType:
150 if (kRGB_565_GrPixelConfig == config) {
151 return GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16);
152 }
153 break;
154 case kARGB_4444_SkColorType:
155 if (kRGBA_4444_GrPixelConfig == config) {
156 return GrBackendFormat::MakeVk(VK_FORMAT_B4G4R4A4_UNORM_PACK16);
157 }
158 break;
159 case kRGBA_8888_SkColorType:
160 if (kRGBA_8888_GrPixelConfig == config) {
161 if (!cs || (cs->gammaCloseToSRGB() && !caps->srgbSupport())) {
162 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
163 }
164 } else if (kSRGBA_8888_GrPixelConfig == config) {
165 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
166 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_SRGB);
167 }
168 }
169 break;
170 case kRGB_888x_SkColorType:
171 if (kRGB_888_GrPixelConfig == config) {
172 return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM);
173 }
174 break;
175 case kBGRA_8888_SkColorType:
176 if (kBGRA_8888_GrPixelConfig == config) {
177 return GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_UNORM);
178 } else if (kSBGRA_8888_GrPixelConfig == config) {
179 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
180 return GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_SRGB);
181 }
182 }
183 break;
184 case kRGBA_1010102_SkColorType:
185 if (kRGBA_1010102_GrPixelConfig == config) {
186 return GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
187 }
188 break;
189 case kRGB_101010x_SkColorType:
190 return GrBackendFormat();
191 case kGray_8_SkColorType:
192 // TODO: what about kAlpha_8_GrPixelConfig and kGray_8_as_Lum_GrPixelConfig?
193 if (kGray_8_as_Red_GrPixelConfig == config) {
194 return GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM);
195 }
196 break;
197 case kRGBA_F16_SkColorType:
198 if (kRGBA_half_GrPixelConfig == config) {
199 return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
200 }
201 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500202 }
203 break;
204#endif
205 case kMock_GrBackend:
Robert Phillipsbe77a022018-04-03 17:17:05 -0400206 switch (ct) {
207 case kUnknown_SkColorType:
208 return GrBackendFormat();
209 case kAlpha_8_SkColorType:
210 if (kAlpha_8_GrPixelConfig == config ||
211 kAlpha_8_as_Alpha_GrPixelConfig == config ||
212 kAlpha_8_as_Red_GrPixelConfig == config) {
213 return GrBackendFormat::MakeMock(config);
214 }
215 break;
216 case kRGB_565_SkColorType:
217 if (kRGB_565_GrPixelConfig == config) {
218 return GrBackendFormat::MakeMock(config);
219 }
220 break;
221 case kARGB_4444_SkColorType:
222 if (kRGBA_4444_GrPixelConfig == config) {
223 return GrBackendFormat::MakeMock(config);
224 }
225 break;
226 case kRGBA_8888_SkColorType:
227 if (kRGBA_8888_GrPixelConfig == config) {
228 if (!cs || (cs->gammaCloseToSRGB() && !caps->srgbSupport())) {
229 return GrBackendFormat::MakeMock(config);
230 }
231 } else if (kSRGBA_8888_GrPixelConfig == config) {
232 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
233 return GrBackendFormat::MakeMock(config);
234 }
235 }
236 break;
237 case kRGB_888x_SkColorType:
238 if (kRGB_888_GrPixelConfig == config) {
239 return GrBackendFormat::MakeMock(config);
240 }
241 break;
242 case kBGRA_8888_SkColorType:
243 if (kBGRA_8888_GrPixelConfig == config) {
244 return GrBackendFormat::MakeMock(config);
245 } else if (kSBGRA_8888_GrPixelConfig == config) {
246 if (caps->srgbSupport() && cs && cs->gammaCloseToSRGB()) {
247 return GrBackendFormat::MakeMock(config);
248 }
249 }
250 break;
251 case kRGBA_1010102_SkColorType:
252 if (kRGBA_1010102_GrPixelConfig == config) {
253 return GrBackendFormat::MakeMock(config);
254 }
255 break;
256 case kRGB_101010x_SkColorType:
257 return GrBackendFormat();
258 case kGray_8_SkColorType:
259 if (kGray_8_GrPixelConfig == config ||
260 kGray_8_as_Lum_GrPixelConfig == config ||
261 kGray_8_as_Red_GrPixelConfig == config) {
262 return GrBackendFormat::MakeMock(config);
263 }
264 break;
265 case kRGBA_F16_SkColorType:
266 if (kRGBA_half_GrPixelConfig == config) {
267 return GrBackendFormat::MakeMock(config);
268 }
269 break;
Robert Phillipsfc711a22018-02-13 17:03:00 -0500270 }
271 break;
272 default:
273 return GrBackendFormat(); // return an invalid format
274 }
275
276 return GrBackendFormat(); // return an invalid format
277}
278
279
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500280class SurfaceParameters {
281public:
Robert Phillipse8fabb22018-02-04 14:33:21 -0500282 static const int kNumParams = 9;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500283 static const int kSampleCount = 5;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500284 static const int kMipMipCount = 8;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500285
Robert Phillipsbe77a022018-04-03 17:17:05 -0400286 SurfaceParameters(const GrCaps* caps)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500287 : fWidth(64)
288 , fHeight(64)
289 , fOrigin(kTopLeft_GrSurfaceOrigin)
290 , fColorType(kRGBA_8888_SkColorType)
Robert Phillipsbe77a022018-04-03 17:17:05 -0400291 , fConfig(caps->srgbSupport() ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig)
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500292 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -0500293 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -0500294 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
295 , fShouldCreateMipMaps(true) {
296 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500297
298 int sampleCount() const { return fSampleCount; }
299
Robert Phillipsbe77a022018-04-03 17:17:05 -0400300 void setColorType(SkColorType ct) { fColorType = ct; }
301 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
302 void setConfig(GrPixelConfig config) { fConfig = config; }
303
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500304 // Modify the SurfaceParameters in just one way
305 void modify(int i) {
306 switch (i) {
307 case 0:
308 fWidth = 63;
309 break;
310 case 1:
311 fHeight = 63;
312 break;
313 case 2:
314 fOrigin = kBottomLeft_GrSurfaceOrigin;
315 break;
316 case 3:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400317 // The color type and config need to be changed together.
318 // The original SRGB color space no longer makes sense for F16
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500319 fColorType = kRGBA_F16_SkColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400320 fConfig = kRGBA_half_GrPixelConfig;
321 fColorSpace = SkColorSpace::MakeSRGBLinear();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500322 break;
323 case 4:
Robert Phillipsc1267c62018-04-04 11:12:39 -0400324 // This just needs to be a colorSpace different from that returned by MakeSRGB()
325 // but still be considered SRGB. In this case we just change the gamut.
326 fColorSpace = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
327 SkColorSpace::kAdobeRGB_Gamut);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500328 break;
329 case kSampleCount:
330 fSampleCount = 4;
331 break;
332 case 6:
333 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
334 break;
335 case 7:
336 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
337 kUnknown_SkPixelGeometry);
338 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500339 case 8:
340 fShouldCreateMipMaps = false;
341 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500342 }
343 }
344
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400345 SkSurfaceCharacterization createCharacterization(GrContext* context) const {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500346 int maxResourceCount;
347 size_t maxResourceBytes;
348 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
349
350 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
351 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
352 kPremul_SkAlphaType, fColorSpace);
353
Robert Phillipsbe77a022018-04-03 17:17:05 -0400354 GrBackendFormat backendFormat = create_backend_format(context, fColorType,
355 fColorSpace.get(), fConfig);
356 if (!backendFormat.isValid()) {
357 return SkSurfaceCharacterization();
358 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500359
360 SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
361 maxResourceBytes, ii, backendFormat, fSampleCount,
362 fOrigin, fSurfaceProps, fShouldCreateMipMaps);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400363 return c;
364 }
365
366 // Create a DDL whose characterization captures the current settings
367 std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
368 SkSurfaceCharacterization c = this->createCharacterization(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500369 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500370
371 SkDeferredDisplayListRecorder r(c);
372 SkCanvas* canvas = r.getCanvas();
373 if (!canvas) {
374 return nullptr;
375 }
376
377 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
378 return r.detach();
379 }
380
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500381 // Create the surface with the current set of parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400382 sk_sp<SkSurface> make(GrContext* context, GrBackendTexture* backend,
383 bool nonTextureable) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500384 GrGpu* gpu = context->contextPriv().getGpu();
385
Robert Phillipsbe77a022018-04-03 17:17:05 -0400386 GrMipMapped mipmapped = nonTextureable
387 ? GrMipMapped::kNo
388 : GrMipMapped(fShouldCreateMipMaps);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500389
390 *backend = gpu->createTestingOnlyBackendTexture(nullptr, fWidth, fHeight,
Robert Phillipsbe77a022018-04-03 17:17:05 -0400391 fConfig, true, mipmapped);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500392 if (!backend->isValid() || !gpu->isTestingOnlyBackendTexture(*backend)) {
393 return nullptr;
394 }
395
Robert Phillipsbe77a022018-04-03 17:17:05 -0400396 sk_sp<SkSurface> surface;
397 if (nonTextureable) {
398 // Create a surface w/ the current parameters but make it non-textureable
399 surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
400 context, *backend, fOrigin, fSampleCount, fColorType,
401 fColorSpace, &fSurfaceProps);
402 } else {
403 surface = SkSurface::MakeFromBackendTexture(
404 context, *backend, fOrigin, fSampleCount, fColorType,
405 fColorSpace, &fSurfaceProps);
406 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500407
408 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500409 gpu->deleteTestingOnlyBackendTexture(*backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500410 return nullptr;
411 }
412
413 return surface;
414 }
415
Brian Salomon26102cb2018-03-09 09:33:19 -0500416 void cleanUpBackEnd(GrContext* context, const GrBackendTexture& backend) const {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500417 GrGpu* gpu = context->contextPriv().getGpu();
418
419 gpu->deleteTestingOnlyBackendTexture(backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500420 }
421
422private:
423 int fWidth;
424 int fHeight;
425 GrSurfaceOrigin fOrigin;
426 SkColorType fColorType;
Robert Phillipsbe77a022018-04-03 17:17:05 -0400427 GrPixelConfig fConfig;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500428 sk_sp<SkColorSpace> fColorSpace;
429 int fSampleCount;
430 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500431 bool fShouldCreateMipMaps;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500432};
433
Robert Phillipsc1267c62018-04-04 11:12:39 -0400434// Test out operator== && operator!=
435DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
436 GrContext* context = ctxInfo.grContext();
437
438 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400439 SurfaceParameters params1(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400440 params1.modify(i);
441
442 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
443 if (!char1.isValid()) {
444 continue; // can happen on some platforms (ChromeOS)
445 }
446
447 for (int j = 0; j < SurfaceParameters::kNumParams; ++j) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400448 SurfaceParameters params2(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400449 params2.modify(j);
450
451 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
452 if (!char2.isValid()) {
453 continue; // can happen on some platforms (ChromeOS)
454 }
455
456 if (i == j) {
457 REPORTER_ASSERT(reporter, char1 == char2);
458 } else {
459 REPORTER_ASSERT(reporter, char1 != char2);
460 }
461
462 }
463 }
464
465 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400466 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsc1267c62018-04-04 11:12:39 -0400467
468 SkSurfaceCharacterization valid = params.createCharacterization(context);
469 SkASSERT(valid.isValid());
470
471 SkSurfaceCharacterization inval1, inval2;
472 SkASSERT(!inval1.isValid() && !inval2.isValid());
473
474 REPORTER_ASSERT(reporter, inval1 != inval2);
475 REPORTER_ASSERT(reporter, valid != inval1);
476 REPORTER_ASSERT(reporter, inval1 != valid);
477 }
478}
479
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400480////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500481// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsbe77a022018-04-03 17:17:05 -0400482DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500483 GrContext* context = ctxInfo.grContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -0400484 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500485
Robert Phillips9e441ee2018-02-01 15:14:55 -0500486 // Create a bitmap that we can readback into
487 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
488 kPremul_SkAlphaType);
489 SkBitmap bitmap;
490 bitmap.allocPixels(imageInfo);
491
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500492 std::unique_ptr<SkDeferredDisplayList> ddl;
493
494 // First, create a DDL using the stock SkSurface parameters
495 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400496 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500497
Robert Phillipse8fabb22018-02-04 14:33:21 -0500498 ddl = params.createDDL(context);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500499 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500500
501 // The DDL should draw into an SkSurface created with the same parameters
Robert Phillipsbe77a022018-04-03 17:17:05 -0400502 GrBackendTexture backend;
503 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500504 if (!s) {
505 return;
506 }
507
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500508 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500509 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400510 context->flush();
511 gpu->testingOnly_flushGpuAndSync();
512 s = nullptr;
513 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500514 }
515
516 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
517 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400518 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500519 params.modify(i);
520
Robert Phillipsbe77a022018-04-03 17:17:05 -0400521 GrBackendTexture backend;
522 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500523 if (!s) {
524 continue;
525 }
526
527 if (SurfaceParameters::kSampleCount == i) {
528 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
529
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400530 int supportedSampleCount = context->contextPriv().caps()->getRenderTargetSampleCount(
531 params.sampleCount(),
532 gpuSurf->getDevice()
533 ->accessRenderTargetContext()
534 ->asRenderTargetProxy()
535 ->config());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500536 if (1 == supportedSampleCount) {
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500537 // If changing the sample count won't result in a different
538 // surface characterization, skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400539 s = nullptr;
540 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500541 continue;
542 }
543 }
544
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400545 if (SurfaceParameters::kMipMipCount == i &&
546 !context->contextPriv().caps()->mipMapSupport()) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400547 // If changing the mipmap setting won't result in a different surface characterization,
548 // skip this step
Robert Phillipsbe77a022018-04-03 17:17:05 -0400549 s = nullptr;
550 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500551 continue;
552 }
553
554 REPORTER_ASSERT(reporter, !s->draw(ddl.get()),
555 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400556
557 context->flush();
558 gpu->testingOnly_flushGpuAndSync();
559 s = nullptr;
560 params.cleanUpBackEnd(context, backend);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500561 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500562
563 // Next test the compatibility of resource cache parameters
564 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400565 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400566 GrBackendTexture backend;
567
568 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500569
570 int maxResourceCount;
571 size_t maxResourceBytes;
572 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
573
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500574 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
575 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
576
Robert Phillips9e441ee2018-02-01 15:14:55 -0500577 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
578 // For now, DDLs are drawn once.
579#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500580 // resource limits >= those at characterization time are accepted
581 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
582 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500583 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500584
585 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
586 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500587 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500588
589 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
590 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500591 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
592#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400593
594 context->flush();
595 gpu->testingOnly_flushGpuAndSync();
596 s = nullptr;
597 params.cleanUpBackEnd(context, backend);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500598 }
599
Robert Phillipse8fabb22018-02-04 14:33:21 -0500600 // Test that the textureability of the DDL characterization can block a DDL draw
601 {
602 GrBackendTexture backend;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400603 const SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400604 sk_sp<SkSurface> s = params.make(context, &backend, true);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500605 if (s) {
606 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
607
Robert Phillipsbe77a022018-04-03 17:17:05 -0400608 context->flush();
609 gpu->testingOnly_flushGpuAndSync();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500610 s = nullptr;
Brian Salomon26102cb2018-03-09 09:33:19 -0500611 params.cleanUpBackEnd(context, backend);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500612 }
613 }
614
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500615 // Make sure non-GPU-backed surfaces fail characterization
616 {
617 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
618
619 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
620 SkSurfaceCharacterization c;
621 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
622 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500623
624 // Exercise the createResized method
625 {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400626 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400627 GrBackendTexture backend;
Robert Phillips94458ee2018-03-06 13:41:51 -0500628
Robert Phillipsbe77a022018-04-03 17:17:05 -0400629 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips94458ee2018-03-06 13:41:51 -0500630 if (!s) {
631 return;
632 }
633
634 SkSurfaceCharacterization char0;
635 SkAssertResult(s->characterize(&char0));
636
637 // Too small
638 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
639 REPORTER_ASSERT(reporter, !char1.isValid());
640
641 // Too large
642 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
643 REPORTER_ASSERT(reporter, !char2.isValid());
644
645 // Just right
646 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
647 REPORTER_ASSERT(reporter, char3.isValid());
648 REPORTER_ASSERT(reporter, 32 == char3.width());
649 REPORTER_ASSERT(reporter, 32 == char3.height());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400650
651 s = nullptr;
652 params.cleanUpBackEnd(context, backend);
Robert Phillips94458ee2018-03-06 13:41:51 -0500653 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500654}
655
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400656////////////////////////////////////////////////////////////////////////////////
657// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
658// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
Robert Phillipsbe77a022018-04-03 17:17:05 -0400659DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400660 GrContext* context = ctxInfo.grContext();
661
662 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400663 SurfaceParameters params(context->contextPriv().caps());
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400664 params.modify(i);
665
666 SkSurfaceCharacterization c = params.createCharacterization(context);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400667 GrBackendTexture backend;
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400668
Robert Phillipsbe77a022018-04-03 17:17:05 -0400669 if (!c.isValid()) {
670 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
671
672 // If we couldn't characterize the surface we shouldn't be able to create it either
673 REPORTER_ASSERT(reporter, !tmp);
674 if (tmp) {
675 tmp = nullptr;
676 params.cleanUpBackEnd(context, backend);
677 }
678 continue;
679 }
680
681 sk_sp<SkSurface> s = params.make(context, &backend, false);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400682 if (!s) {
683 REPORTER_ASSERT(reporter, !c.isValid());
684 continue;
685 }
686
687 REPORTER_ASSERT(reporter, c.isValid());
688
689 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
690 REPORTER_ASSERT(reporter, s);
691
692 SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
693 REPORTER_ASSERT(reporter, g->isCompatible(c));
Robert Phillipsbe77a022018-04-03 17:17:05 -0400694
695 s = nullptr;
696 params.cleanUpBackEnd(context, backend);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400697 }
698}
699
700////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500701static constexpr int kSize = 8;
702
703struct TextureReleaseChecker {
704 TextureReleaseChecker() : fReleaseCount(0) {}
705 int fReleaseCount;
706 static void Release(void* self) {
707 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
708 }
709};
710
711enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
712
713// This tests the ability to create and use wrapped textures in a DDL world
714DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
715 GrContext* context = ctxInfo.grContext();
716 GrGpu* gpu = context->contextPriv().getGpu();
Brian Salomonf7778972018-03-08 10:13:17 -0500717 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
718 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo);
719 if (!backendTex.isValid()) {
720 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500721 }
Brian Salomonf7778972018-03-08 10:13:17 -0500722
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400723 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400724 GrBackendTexture backend;
Brian Salomonf7778972018-03-08 10:13:17 -0500725
Robert Phillipsbe77a022018-04-03 17:17:05 -0400726 sk_sp<SkSurface> s = params.make(context, &backend, false);
Brian Salomonf7778972018-03-08 10:13:17 -0500727 if (!s) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500728 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500729 return;
730 }
731
732 SkSurfaceCharacterization c;
733 SkAssertResult(s->characterize(&c));
734
735 std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
736
737 SkCanvas* canvas = recorder->getCanvas();
738 if (!canvas) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400739 s = nullptr;
740 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500741 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500742 return;
743 }
744
745 GrContext* deferredContext = canvas->getGrContext();
746 if (!deferredContext) {
Robert Phillipsbe77a022018-04-03 17:17:05 -0400747 s = nullptr;
748 params.cleanUpBackEnd(context, backend);
Brian Salomon26102cb2018-03-09 09:33:19 -0500749 gpu->deleteTestingOnlyBackendTexture(backendTex);
Brian Salomonf7778972018-03-08 10:13:17 -0500750 return;
751 }
752
753 // Wrapped Backend Textures are not supported in DDL
754 sk_sp<SkImage> image =
755 SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
756 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
757 REPORTER_ASSERT(reporter, !image);
758
759 TextureReleaseChecker releaseChecker;
760 image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
761 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
762 TextureReleaseChecker::Release, &releaseChecker);
763 REPORTER_ASSERT(reporter, !image);
764
Brian Salomon26102cb2018-03-09 09:33:19 -0500765 gpu->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400766
767 s = nullptr;
768 params.cleanUpBackEnd(context, backend);
Greg Danielf2336e42018-01-23 16:38:14 -0500769}
770
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400771static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); }
772static void dummy_release_proc(void*) { SkASSERT(0); }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400773static void dummy_done_proc(void*) { }
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400774
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400775////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400776// Test out the behavior of an invalid DDLRecorder
777DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
778 GrContext* context = ctxInfo.grContext();
779
780 {
781 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
782 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
783
784 SkSurfaceCharacterization characterization;
785 SkAssertResult(s->characterize(&characterization));
786
787 // never calling getCanvas means the backing surface is never allocated
788 SkDeferredDisplayListRecorder recorder(characterization);
789 }
790
791 {
792 SkSurfaceCharacterization invalid;
793
794 SkDeferredDisplayListRecorder recorder(invalid);
795
796 const SkSurfaceCharacterization c = recorder.characterization();
797 REPORTER_ASSERT(reporter, !c.isValid());
798 REPORTER_ASSERT(reporter, !recorder.getCanvas());
799 REPORTER_ASSERT(reporter, !recorder.detach());
800
Robert Phillipsbe77a022018-04-03 17:17:05 -0400801 GrBackendFormat format = create_backend_format(context, kRGBA_8888_SkColorType,
802 nullptr, kRGBA_8888_GrPixelConfig);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400803 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo,
804 kTopLeft_GrSurfaceOrigin,
805 kRGBA_8888_SkColorType,
806 kPremul_SkAlphaType, nullptr,
807 dummy_fulfill_proc,
808 dummy_release_proc,
Greg Daniel7278d682018-03-16 14:57:21 -0400809 dummy_done_proc,
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400810 nullptr);
811 REPORTER_ASSERT(reporter, !image);
812 }
813
814}
815
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400816////////////////////////////////////////////////////////////////////////////////
Robert Phillips874b5352018-03-16 08:48:24 -0400817// Ensure that flushing while DDL recording doesn't cause a crash
818DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
819 GrContext* context = ctxInfo.grContext();
820
821 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
822 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
823
824 SkSurfaceCharacterization characterization;
825 SkAssertResult(s->characterize(&characterization));
826
827 SkDeferredDisplayListRecorder recorder(characterization);
828 SkCanvas* canvas = recorder.getCanvas();
829
830 canvas->flush();
831 canvas->getGrContext()->flush();
832}
Greg Danielf2336e42018-01-23 16:38:14 -0500833
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400834////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -0400835// Check that the texture-specific flags (i.e., for external & rectangle textures) work
836// for promise images. As such, this is a GL-only test.
837DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
838 GrContext* context = ctxInfo.grContext();
839
840 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
841 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
842
843 SkSurfaceCharacterization characterization;
844 SkAssertResult(s->characterize(&characterization));
845
846 SkDeferredDisplayListRecorder recorder(characterization);
847
848 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Greg Daniel09c94002018-06-08 22:11:51 +0000849 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
850 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400851
Greg Daniel09c94002018-06-08 22:11:51 +0000852 sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, mipMapped,
853 kTopLeft_GrSurfaceOrigin,
854 kRGBA_8888_SkColorType,
855 kPremul_SkAlphaType, nullptr,
856 dummy_fulfill_proc,
857 dummy_release_proc,
858 dummy_done_proc,
859 nullptr);
860 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipMapped::kYes) {
861 REPORTER_ASSERT(reporter, !image);
862 continue;
863 }
864 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -0400865
Greg Daniel09c94002018-06-08 22:11:51 +0000866 GrTextureProxy* backingProxy = ((SkImage_Gpu*) image.get())->peekProxy();
Robert Phillipsabf7b762018-03-21 12:13:37 -0400867
Greg Daniel09c94002018-06-08 22:11:51 +0000868 REPORTER_ASSERT(reporter, backingProxy->mipMapped() == mipMapped);
869 if (GR_GL_TEXTURE_2D == target) {
870 REPORTER_ASSERT(reporter, !backingProxy->texPriv().isClampOnly());
871 } else {
872 REPORTER_ASSERT(reporter, backingProxy->texPriv().isClampOnly());
873 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400874 }
875 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400876}
877
878////////////////////////////////////////////////////////////////////////////////
879
880// Exhaustively test colorType and pixelConfig compatibility.
881DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
882 GrContext* context = ctxInfo.grContext();
883
884 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
885 SkColorType colorType = static_cast<SkColorType>(ct);
886
887 for (int config = 0; config < kGrPixelConfigCnt; ++config) {
888 GrPixelConfig pixelConfig = static_cast<GrPixelConfig>(config);
889
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400890 SurfaceParameters params(context->contextPriv().caps());
Robert Phillipsbe77a022018-04-03 17:17:05 -0400891 params.setColorType(colorType);
892 params.setConfig(pixelConfig);
893
894 params.setColorSpace(nullptr);
895 if (kSRGBA_8888_GrPixelConfig == pixelConfig ||
896 kSBGRA_8888_GrPixelConfig == pixelConfig) {
897 params.setColorSpace(SkColorSpace::MakeSRGB());
898 }
899
900 SkSurfaceCharacterization c = params.createCharacterization(context);
901 GrBackendTexture backend;
902
903 if (!c.isValid()) {
904 // TODO: this would be cool to enable but there is, currently, too much crossover
905 // allowed internally (e.g., kAlpha_8_SkColorType/kGray_8_as_Red_GrPixelConfig
906 // is permitted on GL).
907#if 0
908 sk_sp<SkSurface> tmp = params.make(context, &backend, false);
909
910 // If we couldn't characterize the surface we shouldn't be able to create it either
911 REPORTER_ASSERT(reporter, !tmp);
912 if (tmp) {
913 tmp = nullptr;
914 params.cleanUpBackEnd(context, backend);
915 }
916#endif
917 continue;
918 }
919
920 sk_sp<SkSurface> s = params.make(context, &backend, false);
921 REPORTER_ASSERT(reporter, s);
922 if (!s) {
923 s = nullptr;
924 params.cleanUpBackEnd(context, backend);
925 continue;
926 }
927
928 SkSurface_Gpu* gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
929 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
930
931 s = nullptr;
932 params.cleanUpBackEnd(context, backend);
933
934 s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
935 REPORTER_ASSERT(reporter, s);
936 if (!s) {
937 continue;
938 }
939
940 gpuSurface = static_cast<SkSurface_Gpu*>(s.get());
941 REPORTER_ASSERT(reporter, gpuSurface->isCompatible(c));
942 }
943 }
Robert Phillipsabf7b762018-03-21 12:13:37 -0400944
945}