blob: d4c16d302e7971f17292e7a68de8eb701e35b825 [file] [log] [blame]
Robert Phillips0c6daf02019-05-16 12:43:11 -04001/*
2 * Copyright 2019 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
Robert Phillipse19babf2020-04-06 13:57:30 -04008#include "include/core/SkCanvas.h"
Mike Kleinfe0aeb32019-05-20 10:55:11 -05009#include "include/core/SkSurface.h"
Robert Phillips02dc0302019-07-02 17:58:27 -040010#include "include/core/SkSurfaceCharacterization.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050011#include "include/gpu/GrContext.h"
Robert Phillips459b2952019-05-23 09:38:27 -040012#include "src/core/SkAutoPixmapStorage.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050013#include "src/gpu/GrContextPriv.h"
Robert Phillipsefb9f142019-05-17 14:19:44 -040014#include "src/image/SkImage_Base.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040015#include "tests/Test.h"
Robert Phillipse3b6fe42019-09-11 11:26:46 -040016#include "tests/TestUtils.h"
17#include "tools/ToolUtils.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040018
Robert Phillips27eb5252019-06-03 12:59:40 -040019#ifdef SK_GL
Robert Phillipsee946932019-12-18 11:16:17 -050020#include "src/gpu/gl/GrGLCaps.h"
21#include "src/gpu/gl/GrGLDefines.h"
Robert Phillips27eb5252019-06-03 12:59:40 -040022#include "src/gpu/gl/GrGLGpu.h"
23#include "src/gpu/gl/GrGLUtil.h"
24#endif
25
Robert Phillips7f367982019-09-26 14:01:36 -040026#ifdef SK_METAL
27#include "include/gpu/mtl/GrMtlTypes.h"
28#include "src/gpu/mtl/GrMtlCppUtil.h"
29#endif
30
Greg Danielb2365d82020-05-13 15:32:04 -040031static void wait_on_backend_work_to_finish(GrContext* context, bool* finishedCreate) {
Greg Danielb5776552020-06-19 20:21:08 -040032 context->submit();
Greg Danielc1ad77c2020-05-06 11:40:03 -040033 while (finishedCreate && !(*finishedCreate)) {
34 context->checkAsyncWorkCompletion();
35 }
36 if (finishedCreate) {
37 // The same boolean (pointed to by finishedCreate) is often used multiply and sequentially
38 // throughout our tests to create different backend textures.
39 // Reset it here so that it can be use to signal a future backend texture's creation
40 *finishedCreate = false;
41 }
Greg Danielb2365d82020-05-13 15:32:04 -040042}
43
44static void delete_backend_texture(GrContext* context, const GrBackendTexture& backendTexture,
45 bool* finishedCreate) {
46 wait_on_backend_work_to_finish(context, finishedCreate);
Greg Danielc1ad77c2020-05-06 11:40:03 -040047 context->deleteBackendTexture(backendTexture);
48}
49
Greg Danielb2365d82020-05-13 15:32:04 -040050static void mark_signaled(void* context) {
51 *(bool*)context = true;
52}
53
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040054// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillips0c6daf02019-05-16 12:43:11 -040055void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040056 std::function<GrBackendTexture (GrContext*,
57 GrMipMapped,
58 GrRenderable)> create,
Greg Danielc1ad77c2020-05-06 11:40:03 -040059 GrColorType grColorType, GrMipMapped mipMapped, GrRenderable renderable,
60 bool* finishedBECreate) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040061 GrResourceCache* cache = context->priv().getResourceCache();
62
63 const int initialCount = cache->getResourceCount();
64
Robert Phillipsefb9f142019-05-17 14:19:44 -040065 GrBackendTexture backendTex = create(context, mipMapped, renderable);
66 if (!backendTex.isValid()) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040067 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
68 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040069 GrRenderable::kYes == renderable ? "yes" : "no");
70 return;
71 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040072
Robert Phillips0c6daf02019-05-16 12:43:11 -040073 // Skia proper should know nothing about the new backend object
74 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
75
Robert Phillipsb7f95d12019-07-26 11:13:19 -040076 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
77
78 // Wrapping a backendTexture in an image requires an SkColorType
79 if (kUnknown_SkColorType == skColorType) {
Greg Danielc1ad77c2020-05-06 11:40:03 -040080 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillipsb04b6942019-05-21 17:24:31 -040081 return;
82 }
83
Robert Phillipsd470e1b2019-09-04 15:05:35 -040084 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040085 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040086 backendTex,
87 kTopLeft_GrSurfaceOrigin,
88 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040089 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040090 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040091 if (!surf) {
Robert Phillips9a30ee02020-04-29 08:58:39 -040092 ERRORF(reporter, "Couldn't make surface from backendTexture for %s\n",
93 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -040094 } else {
95 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040096 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040097 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040098
Robert Phillipsb04b6942019-05-21 17:24:31 -040099 {
100 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -0400101 backendTex,
102 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400103 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -0400104 kPremul_SkAlphaType,
105 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400106 if (!img) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400107 ERRORF(reporter, "Couldn't make image from backendTexture for %s\n",
108 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -0400109 } else {
110 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400111
Robert Phillipsb04b6942019-05-21 17:24:31 -0400112 GrTextureProxy* proxy = ib->peekProxy();
113 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400114
Robert Phillipsb04b6942019-05-21 17:24:31 -0400115 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
116 REPORTER_ASSERT(reporter, proxy->isInstantiated());
117 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -0400118
Robert Phillipsb04b6942019-05-21 17:24:31 -0400119 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400120 }
121 }
122
123 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
124
Greg Danielc1ad77c2020-05-06 11:40:03 -0400125 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400126}
127
Robert Phillips9a30ee02020-04-29 08:58:39 -0400128static bool isBGRA8(const GrBackendFormat& format) {
Robert Phillips7f367982019-09-26 14:01:36 -0400129 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400130 case GrBackendApi::kOpenGL:
131#ifdef SK_GL
132 return format.asGLFormat() == GrGLFormat::kBGRA8;
133#else
134 return false;
135#endif
136 case GrBackendApi::kVulkan: {
137#ifdef SK_VULKAN
138 VkFormat vkFormat;
139 format.asVkFormat(&vkFormat);
140 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
141#else
142 return false;
143#endif
144 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500145 case GrBackendApi::kMetal:
146#ifdef SK_METAL
Robert Phillips9a30ee02020-04-29 08:58:39 -0400147 return GrMtlFormatIsBGRA8(format.asMtlFormat());
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500148#else
149 return false;
150#endif
151 case GrBackendApi::kDirect3D:
152#ifdef SK_DIRECT3D
153 return false; // TODO
154#else
155 return false;
156#endif
157 case GrBackendApi::kDawn:
Stephen White36248742020-06-10 22:24:57 -0400158#ifdef SK_DAWN
159 wgpu::TextureFormat dawnFormat;
160 format.asDawnFormat(&dawnFormat);
161 return dawnFormat == wgpu::TextureFormat::BGRA8Unorm;
162#else
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500163 return false;
Stephen White36248742020-06-10 22:24:57 -0400164#endif
Robert Phillipsa27d6252019-12-10 14:48:36 -0500165 case GrBackendApi::kMock: {
166 SkImage::CompressionType compression = format.asMockCompressionType();
167 if (compression != SkImage::CompressionType::kNone) {
168 return false; // No compressed formats are BGRA
169 }
170
Robert Phillips7f367982019-09-26 14:01:36 -0400171 return format.asMockColorType() == GrColorType::kBGRA_8888;
Robert Phillipsa27d6252019-12-10 14:48:36 -0500172 }
Robert Phillips7f367982019-09-26 14:01:36 -0400173 }
174 SkUNREACHABLE;
175}
176
177static bool isRGB(const GrBackendFormat& format) {
178 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400179 case GrBackendApi::kOpenGL:
180#ifdef SK_GL
181 return format.asGLFormat() == GrGLFormat::kRGB8;
182#else
183 return false;
184#endif
185 case GrBackendApi::kVulkan: {
186#ifdef SK_VULKAN
187 VkFormat vkFormat;
188 format.asVkFormat(&vkFormat);
189 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
190#else
191 return false;
192#endif
193 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500194 case GrBackendApi::kMetal:
195 return false; // Metal doesn't even pretend to support this
196 case GrBackendApi::kDirect3D:
197 return false; // Not supported in Direct3D 12
198 case GrBackendApi::kDawn:
199 return false;
Robert Phillips7f367982019-09-26 14:01:36 -0400200 case GrBackendApi::kMock:
201 return false; // No GrColorType::kRGB_888
202 }
203 SkUNREACHABLE;
204}
205
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400206static void check_solid_pixmap(skiatest::Reporter* reporter,
207 const SkColor4f& expected, const SkPixmap& actual,
Robert Phillips7f367982019-09-26 14:01:36 -0400208 SkColorType ct, const char* label1, const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400209 // we need 0.001f across the board just for noise
210 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400211 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400212
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400213 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400214 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400215 SkASSERT(x >= 0 && y >= 0);
Robert Phillips7f367982019-09-26 14:01:36 -0400216 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
217 ToolUtils::colortype_name(ct), label1, label2, x, y,
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400218 diffs[0], diffs[1], diffs[2], diffs[3]);
219 });
220
Brian Salomon28a8f282019-10-24 20:07:39 -0400221 CheckSolidPixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400222}
223
Robert Phillips7f367982019-09-26 14:01:36 -0400224// What would raster do?
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400225static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
Robert Phillips7f367982019-09-26 14:01:36 -0400226 SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
227 : kPremul_SkAlphaType;
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400228
Robert Phillips7f367982019-09-26 14:01:36 -0400229 SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
230 SkAutoPixmapStorage pm;
231 pm.alloc(ii);
232 pm.erase(orig);
233 SkColor tmp = pm.getColor(0, 0);
234 return SkColor4f::FromColor(tmp);
Robert Phillips459b2952019-05-23 09:38:27 -0400235}
236
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400237static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
238 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400239 skiatest::Reporter* reporter, const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400240
Robert Phillips0ee10342019-09-25 09:55:16 -0400241static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
242 SkColorType skColorType, GrRenderable renderable,
Robert Phillips7f367982019-09-26 14:01:36 -0400243 const SkColor4f& color, skiatest::Reporter* reporter,
244 const char* label) {
245 if (isRGB(backendTex.getBackendFormat())) {
246 // readPixels is busted for the RGB backend format (skbug.com/8862)
247 // TODO: add a GrColorType::kRGB_888 to fix the situation
248 return;
249 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400250
251 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
252 : kPremul_SkAlphaType;
253
254 SkColor4f expectedColor = get_expected_color(color, skColorType);
255
256 SkAutoPixmapStorage actual;
257
258 {
259 SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400260 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400261
262 SkAssertResult(actual.tryAlloc(readBackII));
263 }
264
Robert Phillips0ee10342019-09-25 09:55:16 -0400265 {
266 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
267 backendTex,
268 kTopLeft_GrSurfaceOrigin,
269 skColorType,
270 at,
271 nullptr);
272 if (img) {
273 actual.erase(SkColors::kTransparent);
274 bool result = img->readPixels(actual, 0, 0);
275 if (!result) {
276 // TODO: we need a better way to tell a priori if readPixels will work for an
277 // arbitrary colorType
278#if 0
279 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n", colorType);
280#endif
281 } else {
282 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400283 label, "SkImage::readPixels");
Robert Phillips0ee10342019-09-25 09:55:16 -0400284 }
285 }
286 }
Robert Phillips7f367982019-09-26 14:01:36 -0400287
288 // This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
289 // backend texture) so it must be done last!
290 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
291 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
292 backendTex,
293 kTopLeft_GrSurfaceOrigin,
294 0,
295 skColorType,
296 nullptr, nullptr);
297 if (surf) {
298 actual.erase(SkColors::kTransparent);
299 bool result = surf->readPixels(actual, 0, 0);
300 REPORTER_ASSERT(reporter, result);
301
302 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
303 label, "SkSurface::readPixels");
304 }
305 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400306}
307
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400308// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillips459b2952019-05-23 09:38:27 -0400309void test_color_init(GrContext* context, skiatest::Reporter* reporter,
310 std::function<GrBackendTexture (GrContext*,
311 const SkColor4f&,
312 GrMipMapped,
313 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400314 GrColorType grColorType, const SkColor4f& color,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400315 GrMipMapped mipMapped, GrRenderable renderable, bool* finishedBECreate) {
Robert Phillips459b2952019-05-23 09:38:27 -0400316 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
317 if (!backendTex.isValid()) {
318 // errors here should be reported by the test_wrapping test
319 return;
320 }
321
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400322 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
323
324 // Can't wrap backend textures in images and surfaces w/o an SkColorType
325 if (kUnknown_SkColorType == skColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400326 // TODO: burrow in and scrappily check that data was uploaded!
Greg Danielc1ad77c2020-05-06 11:40:03 -0400327 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips459b2952019-05-23 09:38:27 -0400328 return;
329 }
330
Greg Danielb2365d82020-05-13 15:32:04 -0400331 auto checkBackendTexture = [&](const SkColor4f& testColor) {
332 if (mipMapped == GrMipMapped::kYes) {
333 SkColor4f expectedColor = get_expected_color(testColor, skColorType);
334 SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
335 expectedColor, expectedColor, expectedColor};
336 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
337 }
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400338
Greg Danielb2365d82020-05-13 15:32:04 -0400339 // The last step in this test will dirty the mipmaps so do it last
340 check_base_readbacks(context, backendTex, skColorType, renderable, testColor, reporter,
341 "colorinit");
342 };
343
344 checkBackendTexture(color);
345
346 // Make sure the initial create work has finished so we can test the update independently.
347 wait_on_backend_work_to_finish(context, finishedBECreate);
348
349 SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
350
351 // Reupload the new data and make sure everything still works. We test with an SkColorType so
352 // we may actually swizzle the input during the create path. The update does not do any swizzle
353 // of the passed in color. So we manually do it here so we get the same expected results.
354 SkColor4f swizzledColor = context->priv().caps()->getWriteSwizzle(
355 backendTex.getBackendFormat(), grColorType).applyTo(newColor);
356 context->updateBackendTexture(backendTex, swizzledColor, mark_signaled, finishedBECreate);
357
358 checkBackendTexture(newColor);
359
Greg Danielc1ad77c2020-05-06 11:40:03 -0400360 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips459b2952019-05-23 09:38:27 -0400361}
362
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400363// Draw the backend texture (wrapped in an SkImage) into an RGBA surface, attempting to access
364// all the mipMap levels.
365static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
366 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400367 skiatest::Reporter* reporter, const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400368
369#ifdef SK_GL
370 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
371 if (GrBackendApi::kOpenGL == context->backend()) {
372 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
373
374 if (kRGBA_F32_SkColorType == skColorType &&
375 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
376 return;
377 }
378 }
379#endif
380
Robert Phillips7f367982019-09-26 14:01:36 -0400381 if (isRGB(backendTex.getBackendFormat())) {
382 // readPixels is busted for the RGB backend format (skbug.com/8862)
383 // TODO: add a GrColorType::kRGB_888 to fix the situation
384 return;
385 }
386
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400387 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
388 : kPremul_SkAlphaType;
Robert Phillips7f367982019-09-26 14:01:36 -0400389
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400390 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
391 backendTex,
392 kTopLeft_GrSurfaceOrigin,
393 skColorType,
394 at,
395 nullptr);
396 if (!img) {
397 return;
398 }
399
Robert Phillips7f367982019-09-26 14:01:36 -0400400 SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
401 kPremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400402
403 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
404 SkBudgeted::kNo,
Robert Phillips7f367982019-09-26 14:01:36 -0400405 readbackSurfaceII, 1,
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400406 kTopLeft_GrSurfaceOrigin,
407 nullptr);
408 if (!surf) {
409 return;
410 }
411
412 SkCanvas* canvas = surf->getCanvas();
413
414 SkPaint p;
415 p.setFilterQuality(kHigh_SkFilterQuality);
416
417 int numMipLevels = 6;
418
419 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
420 SkASSERT(rectSize >= 1);
421
422 SkRect r = SkRect::MakeWH(rectSize, rectSize);
423 canvas->clear(SK_ColorTRANSPARENT);
424 canvas->drawImageRect(img, r, &p);
425
426 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
427 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400428 kUnpremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400429 SkAutoPixmapStorage actual2;
430 SkAssertResult(actual2.tryAlloc(readbackII));
431 actual2.erase(SkColors::kTransparent);
432
433 bool result = surf->readPixels(actual2, 0, 0);
434 REPORTER_ASSERT(reporter, result);
435
Robert Phillipsee946932019-12-18 11:16:17 -0500436 SkString str;
437 str.appendf("mip-level %d", i);
438
Robert Phillips7f367982019-09-26 14:01:36 -0400439 check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
Robert Phillipsee946932019-12-18 11:16:17 -0500440 label, str.c_str());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400441 }
442}
443
Robert Phillips7f367982019-09-26 14:01:36 -0400444static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
445 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
446 int levelSize = 32;
447 int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
448 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
449 : kPremul_SkAlphaType;
450 for (int level = 0; level < numMipLevels; ++level) {
451 SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
452 pixmaps[level].alloc(ii);
453 pixmaps[level].erase(colors[level]);
454 levelSize /= 2;
455 }
456 return numMipLevels;
457}
458
459// Test initialization of GrBackendObjects using SkPixmaps
460static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
461 std::function<GrBackendTexture (GrContext*,
462 const SkPixmap srcData[],
463 int numLevels,
464 GrRenderable)> create,
465 SkColorType skColorType, GrMipMapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400466 GrRenderable renderable, bool* finishedBECreate) {
Robert Phillips7f367982019-09-26 14:01:36 -0400467 SkAutoPixmapStorage pixmapMem[6];
468 SkColor4f colors[6] = {
469 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
470 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
471 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
472 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
473 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
474 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
475 };
476
477 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
478 SkASSERT(numMipLevels);
479
480 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
481 SkPixmap pixmaps[6];
482 for (int i = 0; i < numMipLevels; ++i) {
483 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
484 }
485
486 GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
487 if (!backendTex.isValid()) {
488 // errors here should be reported by the test_wrapping test
489 return;
490 }
491
Robert Phillips9a30ee02020-04-29 08:58:39 -0400492 if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(backendTex.getBackendFormat())) {
Robert Phillips7f367982019-09-26 14:01:36 -0400493 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
Greg Danielc1ad77c2020-05-06 11:40:03 -0400494 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips7f367982019-09-26 14:01:36 -0400495 return;
496 }
497
Greg Danielb2365d82020-05-13 15:32:04 -0400498 auto checkBackendTexture = [&](SkColor4f colors[6]) {
499 if (mipMapped == GrMipMapped::kYes) {
500 SkColor4f expectedColors[6] = {
501 get_expected_color(colors[0], skColorType),
502 get_expected_color(colors[1], skColorType),
503 get_expected_color(colors[2], skColorType),
504 get_expected_color(colors[3], skColorType),
505 get_expected_color(colors[4], skColorType),
506 get_expected_color(colors[5], skColorType),
507 };
Robert Phillips7f367982019-09-26 14:01:36 -0400508
Greg Danielb2365d82020-05-13 15:32:04 -0400509 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
510 }
511
512 // The last step in this test will dirty the mipmaps so do it last
513 check_base_readbacks(context, backendTex, skColorType, renderable, colors[0], reporter,
514 "pixmap");
515 };
516
517 checkBackendTexture(colors);
518
519 // Make sure the initial create work has finished so we can test the update independently.
520 wait_on_backend_work_to_finish(context, finishedBECreate);
521
522 SkColor4f colorsNew[6] = {
523 {1.0f, 1.0f, 0.0f, 0.2f}, // Y
524 {1.0f, 0.0f, 0.0f, 1.0f}, // R
525 {0.0f, 1.0f, 0.0f, 0.9f}, // G
526 {0.0f, 0.0f, 1.0f, 0.7f}, // B
527 {0.0f, 1.0f, 1.0f, 0.5f}, // C
528 {1.0f, 0.0f, 1.0f, 0.3f}, // M
529 };
530 make_pixmaps(skColorType, mipMapped, colorsNew, pixmapMem);
531 for (int i = 0; i < numMipLevels; ++i) {
532 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
Robert Phillips7f367982019-09-26 14:01:36 -0400533 }
534
Greg Danielb2365d82020-05-13 15:32:04 -0400535 // Upload new data and make sure everything still works
536 context->updateBackendTexture(backendTex, pixmaps, numMipLevels, mark_signaled,
537 finishedBECreate);
538
539 checkBackendTexture(colorsNew);
540
Greg Danielc1ad77c2020-05-06 11:40:03 -0400541 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips7f367982019-09-26 14:01:36 -0400542}
543
Robert Phillips02dc0302019-07-02 17:58:27 -0400544enum class VkLayout {
545 kUndefined,
546 kReadOnlyOptimal,
Robert Phillips02dc0302019-07-02 17:58:27 -0400547};
548
549void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
550#if defined(SK_VULKAN) && defined(SK_DEBUG)
551 VkImageLayout expected;
552
553 switch (layout) {
554 case VkLayout::kUndefined:
555 expected = VK_IMAGE_LAYOUT_UNDEFINED;
556 break;
557 case VkLayout::kReadOnlyOptimal:
558 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
559 break;
Robert Phillips02dc0302019-07-02 17:58:27 -0400560 default:
561 SkUNREACHABLE;
562 }
563
564 GrVkImageInfo vkII;
565
566 if (backendTex.getVkImageInfo(&vkII)) {
567 SkASSERT(expected == vkII.fImageLayout);
568 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
569 }
570#endif
571}
572
573///////////////////////////////////////////////////////////////////////////////
574// This test is a bit different from the others in this file. It is mainly checking that, for any
575// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
576// its characterization and then create a new surface that wraps that backend texture.
577DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
578 GrContext* context = ctxInfo.grContext();
579
580 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
581 SkColorType colorType = static_cast<SkColorType>(ct);
582
583 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
584
585 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
586 for (bool mipMaps : { true, false } ) {
587 for (int sampleCount : {1, 2}) {
588 SkSurfaceCharacterization c;
589
590 // Get a characterization, if possible
591 {
592 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
593 ii, sampleCount,
594 origin, nullptr, mipMaps);
595 if (!s) {
596 continue;
597 }
598
599 if (!s->characterize(&c)) {
600 continue;
601 }
602
603 REPORTER_ASSERT(reporter, s->isCompatible(c));
604 }
605
606 // Test out uninitialized path
607 {
608 GrBackendTexture backendTex = context->createBackendTexture(c);
609 check_vk_layout(backendTex, VkLayout::kUndefined);
610 REPORTER_ASSERT(reporter, backendTex.isValid());
611 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
612
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400613 {
614 GrBackendFormat format = context->defaultBackendFormat(
615 c.imageInfo().colorType(),
616 GrRenderable::kYes);
617 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
618 }
619
Robert Phillips02dc0302019-07-02 17:58:27 -0400620 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
621 backendTex);
622 REPORTER_ASSERT(reporter, s2);
623 REPORTER_ASSERT(reporter, s2->isCompatible(c));
624
625 s2 = nullptr;
626 context->deleteBackendTexture(backendTex);
627 }
628
629 // Test out color-initialized path
Greg Danielc1ad77c2020-05-06 11:40:03 -0400630
Robert Phillips02dc0302019-07-02 17:58:27 -0400631 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400632
633 bool finished = false;
Robert Phillips02dc0302019-07-02 17:58:27 -0400634 GrBackendTexture backendTex = context->createBackendTexture(c,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400635 SkColors::kRed,
636 mark_signaled,
637 &finished);
Greg Danieldddf7092020-05-06 11:52:37 -0400638 check_vk_layout(backendTex, VkLayout::kReadOnlyOptimal);
Robert Phillips02dc0302019-07-02 17:58:27 -0400639 REPORTER_ASSERT(reporter, backendTex.isValid());
640 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
641
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400642 {
643 GrBackendFormat format = context->defaultBackendFormat(
644 c.imageInfo().colorType(),
645 GrRenderable::kYes);
646 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
647 }
648
Robert Phillips02dc0302019-07-02 17:58:27 -0400649 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
650 backendTex);
651 REPORTER_ASSERT(reporter, s2);
652 REPORTER_ASSERT(reporter, s2->isCompatible(c));
653
654 s2 = nullptr;
Greg Danielc1ad77c2020-05-06 11:40:03 -0400655 delete_backend_texture(context, backendTex, &finished);
Robert Phillips02dc0302019-07-02 17:58:27 -0400656 }
657 }
658 }
659 }
660 }
661}
662
Robert Phillipsefb9f142019-05-17 14:19:44 -0400663///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400664DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
665 GrContext* context = ctxInfo.grContext();
666 const GrCaps* caps = context->priv().caps();
667
Robert Phillips459b2952019-05-23 09:38:27 -0400668 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400669 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400670
Robert Phillips0c6daf02019-05-16 12:43:11 -0400671 struct {
672 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400673 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400674 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400675 { kAlpha_8_SkColorType, kTransCol },
676 { kRGB_565_SkColorType, SkColors::kRed },
677 { kARGB_4444_SkColorType, SkColors::kGreen },
678 { kRGBA_8888_SkColorType, SkColors::kBlue },
679 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400680 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400681 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips9a30ee02020-04-29 08:58:39 -0400682 // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
683 { kRGBA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
684 { kBGRA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
685 // RGB/BGR 101010x have no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400686 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Mike Kleinf7eb0542020-02-11 12:19:08 -0600687 { kBGR_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400688 { kGray_8_SkColorType, kGrayCol },
689 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
690 { kRGBA_F16_SkColorType, SkColors::kYellow },
691 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400692 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400693 { kR16G16_unorm_SkColorType, SkColors::kGreen },
694 { kA16_unorm_SkColorType, kTransCol },
695 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400696 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400697 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400698 };
699
Brian Salomon4dea72a2019-12-18 10:43:10 -0500700 static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400701
702 for (auto combo : combinations) {
703 SkColorType colorType = combo.fColorType;
704
Robert Phillips0c6daf02019-05-16 12:43:11 -0400705 if (GrBackendApi::kMetal == context->backend()) {
706 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
707 if (kRGBA_F32_SkColorType == combo.fColorType) {
708 continue;
709 }
710 }
711
Robert Phillipsefb9f142019-05-17 14:19:44 -0400712 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
713 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
714 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400715 }
716
Robert Phillipsefb9f142019-05-17 14:19:44 -0400717 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400718 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
719 renderable).isValid()) {
720 continue;
721 }
Robert Phillips7f367982019-09-26 14:01:36 -0400722
Robert Phillipsefb9f142019-05-17 14:19:44 -0400723 if (GrRenderable::kYes == renderable) {
724 if (kRGB_888x_SkColorType == combo.fColorType) {
725 // Ganesh can't perform the blends correctly when rendering this format
726 continue;
727 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400728 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400729
Robert Phillipsb04b6942019-05-21 17:24:31 -0400730 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400731 auto uninitCreateMtd = [colorType](GrContext* context, GrMipMapped mipMapped,
Robert Phillipsb04b6942019-05-21 17:24:31 -0400732 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400733 auto result = context->createBackendTexture(32, 32, colorType,
734 mipMapped, renderable,
735 GrProtected::kNo);
736 check_vk_layout(result, VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400737
738#ifdef SK_DEBUG
739 {
740 GrBackendFormat format = context->defaultBackendFormat(colorType,
741 renderable);
742 SkASSERT(format == result.getBackendFormat());
743 }
744#endif
745
Robert Phillips02dc0302019-07-02 17:58:27 -0400746 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400747 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400748
Robert Phillipsb04b6942019-05-21 17:24:31 -0400749 test_wrapping(context, reporter, uninitCreateMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400750 SkColorTypeToGrColorType(colorType), mipMapped, renderable,
751 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400752 }
Robert Phillips459b2952019-05-23 09:38:27 -0400753
Greg Danielc1ad77c2020-05-06 11:40:03 -0400754 bool finishedBackendCreation = false;
755 bool* finishedPtr = &finishedBackendCreation;
756
Robert Phillips459b2952019-05-23 09:38:27 -0400757 {
Robert Phillips459b2952019-05-23 09:38:27 -0400758
Greg Danielc1ad77c2020-05-06 11:40:03 -0400759 auto createWithColorMtd = [colorType, finishedPtr](GrContext* context,
760 const SkColor4f& color,
761 GrMipMapped mipMapped,
762 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400763 auto result = context->createBackendTexture(32, 32, colorType, color,
764 mipMapped, renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400765 GrProtected::kNo,
766 mark_signaled,
767 finishedPtr);
Greg Danieldddf7092020-05-06 11:52:37 -0400768 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400769
770#ifdef SK_DEBUG
771 {
772 GrBackendFormat format = context->defaultBackendFormat(colorType,
773 renderable);
774 SkASSERT(format == result.getBackendFormat());
775 }
776#endif
777
Robert Phillips02dc0302019-07-02 17:58:27 -0400778 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400779 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500780 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
781 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
782 // the color passed to it. However, createBackendTexture() that takes a
783 // SkColor4f is color type / alpha type unaware and will simply compute
784 // luminance from the r, g, b, channels.
785 SkColor4f color = combo.fColor;
786 if (colorType == kGray_8_SkColorType) {
787 color = {color.fR * color.fA,
788 color.fG * color.fA,
789 color.fB * color.fA,
790 1.f};
791 }
Robert Phillips459b2952019-05-23 09:38:27 -0400792 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon85c3d682019-11-04 15:04:54 -0500793 SkColorTypeToGrColorType(colorType), color, mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400794 renderable, finishedPtr);
Robert Phillips459b2952019-05-23 09:38:27 -0400795 }
Robert Phillips7f367982019-09-26 14:01:36 -0400796
Robert Phillips9a30ee02020-04-29 08:58:39 -0400797 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400798 auto createWithSrcDataMtd = [finishedPtr](GrContext* context,
799 const SkPixmap srcData[],
800 int numLevels,
801 GrRenderable renderable) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400802 SkASSERT(srcData && numLevels);
803 auto result = context->createBackendTexture(srcData, numLevels, renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400804 GrProtected::kNo, mark_signaled,
805 finishedPtr);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400806 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400807#ifdef SK_DEBUG
Robert Phillips9a30ee02020-04-29 08:58:39 -0400808 {
809 auto format = context->defaultBackendFormat(srcData[0].colorType(),
810 renderable);
811 SkASSERT(format == result.getBackendFormat());
812 }
Robert Phillips7f367982019-09-26 14:01:36 -0400813#endif
Robert Phillips9a30ee02020-04-29 08:58:39 -0400814 return result;
815 };
Robert Phillips7f367982019-09-26 14:01:36 -0400816
Robert Phillips9a30ee02020-04-29 08:58:39 -0400817 test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType, mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400818 renderable, finishedPtr);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400819 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400820 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400821 }
822 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400823}
824
Robert Phillipsefb9f142019-05-17 14:19:44 -0400825///////////////////////////////////////////////////////////////////////////////
826#ifdef SK_GL
827
Robert Phillips0c6daf02019-05-16 12:43:11 -0400828DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
829 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
830 GrGLStandard standard = glCtx->gl()->fStandard;
831 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400832 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400833
Robert Phillips459b2952019-05-23 09:38:27 -0400834 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400835 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400836
Robert Phillips0c6daf02019-05-16 12:43:11 -0400837 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400838 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400839 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400840 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400841 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400842 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
843 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400844
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400845 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
846 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400847
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400848 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
849 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
850 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillips9a30ee02020-04-29 08:58:39 -0400851 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
852 { GrColorType::kBGRA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400853 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
854 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400855
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400856 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
857 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400858
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400859 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
860 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400861
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400862 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400863
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400864 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
865 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400866
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400867 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400868 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
869 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400870
Robert Phillips429f0d32019-09-11 17:03:28 -0400871 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400872 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400873
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400874 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
875 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400876 };
877
878 for (auto combo : combinations) {
Brian Salomon0f396992020-06-19 19:51:21 -0400879 for (GrGLenum target : {GR_GL_TEXTURE_2D, GR_GL_TEXTURE_RECTANGLE}) {
880 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, target);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400881
Brian Salomon0f396992020-06-19 19:51:21 -0400882 if (!glCaps->isFormatTexturable(format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400883 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400884 }
885
Brian Salomon0f396992020-06-19 19:51:21 -0400886 if (GrColorType::kBGRA_8888 == combo.fColorType ||
887 GrColorType::kBGRA_1010102 == combo.fColorType) {
888 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not
889 // ES
890 if (kGL_GrGLStandard != standard &&
891 (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
892 continue;
893 }
894 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400895
Brian Salomon0f396992020-06-19 19:51:21 -0400896 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
897 if (GrMipMapped::kYes == mipMapped &&
898 (!glCaps->mipMapSupport() || target == GR_GL_TEXTURE_RECTANGLE)) {
899 continue;
Robert Phillipsefb9f142019-05-17 14:19:44 -0400900 }
901
Brian Salomon0f396992020-06-19 19:51:21 -0400902 for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
903 if (GrRenderable::kYes == renderable) {
904 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
905 continue;
906 }
Robert Phillips459b2952019-05-23 09:38:27 -0400907 }
908
Brian Salomon0f396992020-06-19 19:51:21 -0400909 {
910 auto uninitCreateMtd = [format](GrContext* context, GrMipMapped mipMapped,
911 GrRenderable renderable) {
912 return context->createBackendTexture(32, 32, format, mipMapped,
913 renderable, GrProtected::kNo);
914 };
Greg Danielc1ad77c2020-05-06 11:40:03 -0400915
Brian Salomon0f396992020-06-19 19:51:21 -0400916 test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType,
917 mipMapped, renderable, nullptr);
Brian Salomon85c3d682019-11-04 15:04:54 -0500918 }
Robert Phillips459b2952019-05-23 09:38:27 -0400919
Brian Salomon0f396992020-06-19 19:51:21 -0400920 {
921 // We're creating backend textures without specifying a color type "view" of
922 // them at the public API level. Therefore, Ganesh will not apply any
923 // swizzles before writing the color to the texture. However, our validation
924 // code does rely on interpreting the texture contents via a SkColorType and
925 // therefore swizzles may be applied during the read step. Ideally we'd
926 // update our validation code to use a "raw" read that doesn't impose a
927 // color type but for now we just munge the data we upload to match the
928 // expectation.
929 GrSwizzle swizzle;
930 switch (combo.fColorType) {
931 case GrColorType::kAlpha_8:
932 swizzle = GrSwizzle("aaaa");
933 break;
934 case GrColorType::kAlpha_16:
935 swizzle = GrSwizzle("aaaa");
936 break;
937 case GrColorType::kAlpha_F16:
938 swizzle = GrSwizzle("aaaa");
939 break;
940 default:
941 break;
942 }
943
944 bool finishedBackendCreation = false;
945 bool* finishedPtr = &finishedBackendCreation;
946
947 auto createWithColorMtd = [format, swizzle, finishedPtr](
948 GrContext* context,
949 const SkColor4f& color,
950 GrMipMapped mipMapped,
951 GrRenderable renderable) {
952 auto swizzledColor = swizzle.applyTo(color);
953 return context->createBackendTexture(
954 32, 32, format, swizzledColor, mipMapped, renderable,
955 GrProtected::kNo, mark_signaled, finishedPtr);
956 };
957 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
958 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will
959 // premul the color passed to it. However, createBackendTexture() that takes
960 // a SkColor4f is color type/alpha type unaware and will simply compute
961 // luminance from the r, g, b, channels.
962 SkColor4f color = combo.fColor;
963 if (combo.fColorType == GrColorType::kGray_8) {
964 color = {color.fR * color.fA,
965 color.fG * color.fA,
966 color.fB * color.fA,
967 1.f};
968 }
969
970 test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
971 color, mipMapped, renderable, finishedPtr);
972 }
Robert Phillips459b2952019-05-23 09:38:27 -0400973 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400974 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400975 }
976 }
977}
978
Robert Phillipsefb9f142019-05-17 14:19:44 -0400979#endif
980
981///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400982
983#ifdef SK_VULKAN
984
985#include "src/gpu/vk/GrVkCaps.h"
986
987DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
988 GrContext* context = ctxInfo.grContext();
989 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
990
Robert Phillips459b2952019-05-23 09:38:27 -0400991 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400992 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400993
Robert Phillips0c6daf02019-05-16 12:43:11 -0400994 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400995 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400996 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400997 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400998 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400999 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
1000 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001001
Robert Phillipsbd1ef682019-05-31 12:48:49 -04001002 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
1003 // there is nothing to tell Skia to make the provided color opaque. Clients will need
1004 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001005 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
1006 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001007
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001008 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001009
Robert Phillips9a30ee02020-04-29 08:58:39 -04001010 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1011 { 0.25f, 0.5f, 0.75f, 1.0f }},
1012 { GrColorType::kBGRA_1010102, VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1013 { 0.25f, 0.5f, 0.75f, 1.0f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001014 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -04001015
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001016 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
1017 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -04001018
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001019 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -04001020 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
1021 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
1022 // the alpha channel of the color). Clients should, in general, fill all the channels
1023 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001024 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -04001025
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001026 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
1027 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001028
Robert Phillipsd470e1b2019-09-04 15:05:35 -04001029 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001030 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
1031
Robert Phillips429f0d32019-09-11 17:03:28 -04001032 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001033 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001034 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
1035 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001036 };
1037
1038 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -04001039 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -04001040 continue;
1041 }
1042
1043 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
1044
Robert Phillipsefb9f142019-05-17 14:19:44 -04001045 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
1046 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
1047 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -04001048 }
1049
Robert Phillipsefb9f142019-05-17 14:19:44 -04001050 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -04001051
Robert Phillipsefb9f142019-05-17 14:19:44 -04001052 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -04001053 // We must also check whether we allow rendering to the format using the
1054 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -04001055 if (!vkCaps->isFormatAsColorTypeRenderable(
1056 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -04001057 continue;
1058 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001059 }
1060
Robert Phillipsd34691b2019-09-24 13:38:43 -04001061 {
Greg Danielc1ad77c2020-05-06 11:40:03 -04001062 auto uninitCreateMtd = [format](GrContext* context, GrMipMapped mipMapped,
Robert Phillips459b2952019-05-23 09:38:27 -04001063 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001064 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
1065 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -04001066 renderable,
1067 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -04001068 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001069 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -04001070 };
Robert Phillipsefb9f142019-05-17 14:19:44 -04001071
Robert Phillipsb04b6942019-05-21 17:24:31 -04001072 test_wrapping(context, reporter, uninitCreateMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001073 combo.fColorType, mipMapped, renderable, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -04001074 }
Robert Phillips459b2952019-05-23 09:38:27 -04001075
Robert Phillips459b2952019-05-23 09:38:27 -04001076 {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001077 // We're creating backend textures without specifying a color type "view" of
1078 // them at the public API level. Therefore, Ganesh will not apply any swizzles
1079 // before writing the color to the texture. However, our validation code does
1080 // rely on interpreting the texture contents via a SkColorType and therefore
1081 // swizzles may be applied during the read step.
1082 // Ideally we'd update our validation code to use a "raw" read that doesn't
1083 // impose a color type but for now we just munge the data we upload to match the
1084 // expectation.
1085 GrSwizzle swizzle;
1086 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001087 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -04001088 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
1089 swizzle = GrSwizzle("aaaa");
1090 break;
Robert Phillips429f0d32019-09-11 17:03:28 -04001091 case GrColorType::kAlpha_16:
1092 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
1093 swizzle = GrSwizzle("aaaa");
1094 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -04001095 case GrColorType::kAlpha_F16:
1096 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
1097 swizzle = GrSwizzle("aaaa");
1098 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001099 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -04001100 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
1101 swizzle = GrSwizzle("bgra");
1102 }
1103 break;
1104 default:
1105 swizzle = GrSwizzle("rgba");
1106 break;
1107 }
Greg Danielc1ad77c2020-05-06 11:40:03 -04001108
1109 bool finishedBackendCreation = false;
1110 bool* finishedPtr = &finishedBackendCreation;
1111
1112 auto createWithColorMtd = [format, swizzle, finishedPtr](
1113 GrContext* context, const SkColor4f& color, GrMipMapped mipMapped,
1114 GrRenderable renderable) {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001115 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001116 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -04001117 swizzledColor,
1118 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -04001119 renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001120 GrProtected::kNo,
1121 mark_signaled,
1122 finishedPtr);
Greg Danieldddf7092020-05-06 11:52:37 -04001123 check_vk_layout(beTex, VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001124 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -04001125 };
Robert Phillips459b2952019-05-23 09:38:27 -04001126 test_color_init(context, reporter, createWithColorMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001127 combo.fColorType, combo.fColor, mipMapped, renderable,
1128 finishedPtr);
Robert Phillips459b2952019-05-23 09:38:27 -04001129 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001130 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001131 }
1132 }
1133}
1134
1135#endif