blob: 34aee51db2e2b6a5e9b3850c3ad64ae7fcb409a7 [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
Mike Kleinfe0aeb32019-05-20 10:55:11 -05008#include "include/core/SkSurface.h"
Robert Phillips02dc0302019-07-02 17:58:27 -04009#include "include/core/SkSurfaceCharacterization.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050010#include "include/gpu/GrContext.h"
Robert Phillips459b2952019-05-23 09:38:27 -040011#include "src/core/SkAutoPixmapStorage.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050012#include "src/gpu/GrContextPriv.h"
Robert Phillipsefb9f142019-05-17 14:19:44 -040013#include "src/image/SkImage_Base.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040014#include "tests/Test.h"
Robert Phillipse3b6fe42019-09-11 11:26:46 -040015#include "tests/TestUtils.h"
16#include "tools/ToolUtils.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040017
Robert Phillips27eb5252019-06-03 12:59:40 -040018#ifdef SK_GL
19#include "src/gpu/gl/GrGLGpu.h"
20#include "src/gpu/gl/GrGLUtil.h"
21#endif
22
Robert Phillips7f367982019-09-26 14:01:36 -040023#ifdef SK_METAL
24#include "include/gpu/mtl/GrMtlTypes.h"
25#include "src/gpu/mtl/GrMtlCppUtil.h"
26#endif
27
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040028// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillips0c6daf02019-05-16 12:43:11 -040029void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040030 std::function<GrBackendTexture (GrContext*,
31 GrMipMapped,
32 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040033 GrColorType grColorType, GrMipMapped mipMapped, GrRenderable renderable) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040034 GrResourceCache* cache = context->priv().getResourceCache();
35
36 const int initialCount = cache->getResourceCount();
37
Robert Phillipsefb9f142019-05-17 14:19:44 -040038 GrBackendTexture backendTex = create(context, mipMapped, renderable);
39 if (!backendTex.isValid()) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040040 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
41 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040042 GrRenderable::kYes == renderable ? "yes" : "no");
43 return;
44 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040045
Robert Phillips0c6daf02019-05-16 12:43:11 -040046 // Skia proper should know nothing about the new backend object
47 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
48
Robert Phillipsb7f95d12019-07-26 11:13:19 -040049 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
50
51 // Wrapping a backendTexture in an image requires an SkColorType
52 if (kUnknown_SkColorType == skColorType) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040053 context->deleteBackendTexture(backendTex);
54 return;
55 }
56
Robert Phillipsd470e1b2019-09-04 15:05:35 -040057 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040058 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040059 backendTex,
60 kTopLeft_GrSurfaceOrigin,
61 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040062 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040063 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040064 if (!surf) {
65 ERRORF(reporter, "Couldn't make surface from backendTexture for colorType %d\n",
Robert Phillipsb7f95d12019-07-26 11:13:19 -040066 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040067 } else {
68 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040069 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040070 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040071
Robert Phillipsb04b6942019-05-21 17:24:31 -040072 {
73 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040074 backendTex,
75 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040076 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040077 kPremul_SkAlphaType,
78 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040079 if (!img) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040080 ERRORF(reporter, "Couldn't make image from backendTexture for skColorType %d\n",
81 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040082 } else {
83 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -040084
Robert Phillipsb04b6942019-05-21 17:24:31 -040085 GrTextureProxy* proxy = ib->peekProxy();
86 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -040087
Robert Phillipsb04b6942019-05-21 17:24:31 -040088 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
89 REPORTER_ASSERT(reporter, proxy->isInstantiated());
90 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -040091
Robert Phillipsb04b6942019-05-21 17:24:31 -040092 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040093 }
94 }
95
96 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
97
Robert Phillips5c7a25b2019-05-20 08:38:07 -040098 context->deleteBackendTexture(backendTex);
Robert Phillips0c6daf02019-05-16 12:43:11 -040099}
100
Robert Phillips7f367982019-09-26 14:01:36 -0400101static bool isBGRA(const GrBackendFormat& format) {
102 switch (format.backend()) {
103 case GrBackendApi::kMetal:
104#ifdef SK_METAL
105 return GrMtlFormatIsBGRA(format.asMtlFormat());
106#else
107 return false;
108#endif
109 case GrBackendApi::kDawn:
110 return false;
111 case GrBackendApi::kOpenGL:
112#ifdef SK_GL
113 return format.asGLFormat() == GrGLFormat::kBGRA8;
114#else
115 return false;
116#endif
117 case GrBackendApi::kVulkan: {
118#ifdef SK_VULKAN
119 VkFormat vkFormat;
120 format.asVkFormat(&vkFormat);
121 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
122#else
123 return false;
124#endif
125 }
126 case GrBackendApi::kMock:
127 return format.asMockColorType() == GrColorType::kBGRA_8888;
128 }
129 SkUNREACHABLE;
130}
131
132static bool isRGB(const GrBackendFormat& format) {
133 switch (format.backend()) {
134 case GrBackendApi::kMetal:
135 return false; // Metal doesn't even pretend to support this
136 case GrBackendApi::kDawn:
137 return false;
138 case GrBackendApi::kOpenGL:
139#ifdef SK_GL
140 return format.asGLFormat() == GrGLFormat::kRGB8;
141#else
142 return false;
143#endif
144 case GrBackendApi::kVulkan: {
145#ifdef SK_VULKAN
146 VkFormat vkFormat;
147 format.asVkFormat(&vkFormat);
148 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
149#else
150 return false;
151#endif
152 }
153 case GrBackendApi::kMock:
154 return false; // No GrColorType::kRGB_888
155 }
156 SkUNREACHABLE;
157}
158
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400159static void check_solid_pixmap(skiatest::Reporter* reporter,
160 const SkColor4f& expected, const SkPixmap& actual,
Robert Phillips7f367982019-09-26 14:01:36 -0400161 SkColorType ct, const char* label1, const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400162 // we need 0.001f across the board just for noise
163 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400164 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400165
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400166 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400167 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400168 SkASSERT(x >= 0 && y >= 0);
Robert Phillips7f367982019-09-26 14:01:36 -0400169 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
170 ToolUtils::colortype_name(ct), label1, label2, x, y,
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400171 diffs[0], diffs[1], diffs[2], diffs[3]);
172 });
173
Brian Salomon28a8f282019-10-24 20:07:39 -0400174 CheckSolidPixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400175}
176
Robert Phillips7f367982019-09-26 14:01:36 -0400177// What would raster do?
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400178static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
Robert Phillips7f367982019-09-26 14:01:36 -0400179 SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
180 : kPremul_SkAlphaType;
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400181
Robert Phillips7f367982019-09-26 14:01:36 -0400182 SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
183 SkAutoPixmapStorage pm;
184 pm.alloc(ii);
185 pm.erase(orig);
186 SkColor tmp = pm.getColor(0, 0);
187 return SkColor4f::FromColor(tmp);
Robert Phillips459b2952019-05-23 09:38:27 -0400188}
189
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400190static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
191 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400192 skiatest::Reporter* reporter, const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400193
Robert Phillips0ee10342019-09-25 09:55:16 -0400194static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
195 SkColorType skColorType, GrRenderable renderable,
Robert Phillips7f367982019-09-26 14:01:36 -0400196 const SkColor4f& color, skiatest::Reporter* reporter,
197 const char* label) {
198 if (isRGB(backendTex.getBackendFormat())) {
199 // readPixels is busted for the RGB backend format (skbug.com/8862)
200 // TODO: add a GrColorType::kRGB_888 to fix the situation
201 return;
202 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400203
204 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
205 : kPremul_SkAlphaType;
206
207 SkColor4f expectedColor = get_expected_color(color, skColorType);
208
209 SkAutoPixmapStorage actual;
210
211 {
212 SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400213 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400214
215 SkAssertResult(actual.tryAlloc(readBackII));
216 }
217
Robert Phillips0ee10342019-09-25 09:55:16 -0400218 {
219 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
220 backendTex,
221 kTopLeft_GrSurfaceOrigin,
222 skColorType,
223 at,
224 nullptr);
225 if (img) {
226 actual.erase(SkColors::kTransparent);
227 bool result = img->readPixels(actual, 0, 0);
228 if (!result) {
229 // TODO: we need a better way to tell a priori if readPixels will work for an
230 // arbitrary colorType
231#if 0
232 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n", colorType);
233#endif
234 } else {
235 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400236 label, "SkImage::readPixels");
Robert Phillips0ee10342019-09-25 09:55:16 -0400237 }
238 }
239 }
Robert Phillips7f367982019-09-26 14:01:36 -0400240
241 // This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
242 // backend texture) so it must be done last!
243 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
244 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
245 backendTex,
246 kTopLeft_GrSurfaceOrigin,
247 0,
248 skColorType,
249 nullptr, nullptr);
250 if (surf) {
251 actual.erase(SkColors::kTransparent);
252 bool result = surf->readPixels(actual, 0, 0);
253 REPORTER_ASSERT(reporter, result);
254
255 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
256 label, "SkSurface::readPixels");
257 }
258 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400259}
260
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400261// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillips459b2952019-05-23 09:38:27 -0400262void test_color_init(GrContext* context, skiatest::Reporter* reporter,
263 std::function<GrBackendTexture (GrContext*,
264 const SkColor4f&,
265 GrMipMapped,
266 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400267 GrColorType grColorType, const SkColor4f& color,
Robert Phillips459b2952019-05-23 09:38:27 -0400268 GrMipMapped mipMapped, GrRenderable renderable) {
269 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
270 if (!backendTex.isValid()) {
271 // errors here should be reported by the test_wrapping test
272 return;
273 }
274
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400275 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
276
277 // Can't wrap backend textures in images and surfaces w/o an SkColorType
278 if (kUnknown_SkColorType == skColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400279 // TODO: burrow in and scrappily check that data was uploaded!
280 context->deleteBackendTexture(backendTex);
281 return;
282 }
283
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400284 if (mipMapped == GrMipMapped::kYes) {
285 SkColor4f expectedColor = get_expected_color(color, skColorType);
286 SkColor4f expectedColors[6] = { expectedColor, expectedColor, expectedColor,
287 expectedColor, expectedColor, expectedColor };
Robert Phillips7f367982019-09-26 14:01:36 -0400288 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400289 }
290
Robert Phillips7f367982019-09-26 14:01:36 -0400291 // The last step in this test will dirty the mipmaps so do it last
292 check_base_readbacks(context, backendTex, skColorType, renderable, color,
293 reporter, "colorinit");
Robert Phillips459b2952019-05-23 09:38:27 -0400294 context->deleteBackendTexture(backendTex);
295}
296
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400297// Draw the backend texture (wrapped in an SkImage) into an RGBA surface, attempting to access
298// all the mipMap levels.
299static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
300 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400301 skiatest::Reporter* reporter, const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400302
303#ifdef SK_GL
304 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
305 if (GrBackendApi::kOpenGL == context->backend()) {
306 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
307
308 if (kRGBA_F32_SkColorType == skColorType &&
309 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
310 return;
311 }
312 }
313#endif
314
Robert Phillips7f367982019-09-26 14:01:36 -0400315 if (isRGB(backendTex.getBackendFormat())) {
316 // readPixels is busted for the RGB backend format (skbug.com/8862)
317 // TODO: add a GrColorType::kRGB_888 to fix the situation
318 return;
319 }
320
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400321 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
322 : kPremul_SkAlphaType;
Robert Phillips7f367982019-09-26 14:01:36 -0400323
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400324 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
325 backendTex,
326 kTopLeft_GrSurfaceOrigin,
327 skColorType,
328 at,
329 nullptr);
330 if (!img) {
331 return;
332 }
333
Robert Phillips7f367982019-09-26 14:01:36 -0400334 SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
335 kPremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400336
337 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
338 SkBudgeted::kNo,
Robert Phillips7f367982019-09-26 14:01:36 -0400339 readbackSurfaceII, 1,
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400340 kTopLeft_GrSurfaceOrigin,
341 nullptr);
342 if (!surf) {
343 return;
344 }
345
346 SkCanvas* canvas = surf->getCanvas();
347
348 SkPaint p;
349 p.setFilterQuality(kHigh_SkFilterQuality);
350
351 int numMipLevels = 6;
352
353 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
354 SkASSERT(rectSize >= 1);
355
356 SkRect r = SkRect::MakeWH(rectSize, rectSize);
357 canvas->clear(SK_ColorTRANSPARENT);
358 canvas->drawImageRect(img, r, &p);
359
360 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
361 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400362 kUnpremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400363 SkAutoPixmapStorage actual2;
364 SkAssertResult(actual2.tryAlloc(readbackII));
365 actual2.erase(SkColors::kTransparent);
366
367 bool result = surf->readPixels(actual2, 0, 0);
368 REPORTER_ASSERT(reporter, result);
369
Robert Phillips7f367982019-09-26 14:01:36 -0400370 check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
371 label, "mip-level failure");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400372 }
373}
374
Robert Phillips7f367982019-09-26 14:01:36 -0400375static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
376 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
377 int levelSize = 32;
378 int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
379 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
380 : kPremul_SkAlphaType;
381 for (int level = 0; level < numMipLevels; ++level) {
382 SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
383 pixmaps[level].alloc(ii);
384 pixmaps[level].erase(colors[level]);
385 levelSize /= 2;
386 }
387 return numMipLevels;
388}
389
390// Test initialization of GrBackendObjects using SkPixmaps
391static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
392 std::function<GrBackendTexture (GrContext*,
393 const SkPixmap srcData[],
394 int numLevels,
395 GrRenderable)> create,
396 SkColorType skColorType, GrMipMapped mipMapped,
397 GrRenderable renderable) {
398 SkAutoPixmapStorage pixmapMem[6];
399 SkColor4f colors[6] = {
400 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
401 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
402 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
403 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
404 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
405 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
406 };
407
408 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
409 SkASSERT(numMipLevels);
410
411 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
412 SkPixmap pixmaps[6];
413 for (int i = 0; i < numMipLevels; ++i) {
414 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
415 }
416
417 GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
418 if (!backendTex.isValid()) {
419 // errors here should be reported by the test_wrapping test
420 return;
421 }
422
423 if (skColorType == kBGRA_8888_SkColorType && !isBGRA(backendTex.getBackendFormat())) {
424 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
425 return;
426 }
427
428 if (mipMapped == GrMipMapped::kYes) {
429 SkColor4f expectedColors[6] = {
430 get_expected_color(colors[0], skColorType),
431 get_expected_color(colors[1], skColorType),
432 get_expected_color(colors[2], skColorType),
433 get_expected_color(colors[3], skColorType),
434 get_expected_color(colors[4], skColorType),
435 get_expected_color(colors[5], skColorType),
436 };
437
438 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
439 }
440
441 // The last step in this test will dirty the mipmaps so do it last
442 check_base_readbacks(context, backendTex, skColorType, renderable, colors[0],
443 reporter, "pixmap");
444 context->deleteBackendTexture(backendTex);
445}
446
Robert Phillips02dc0302019-07-02 17:58:27 -0400447enum class VkLayout {
448 kUndefined,
449 kReadOnlyOptimal,
450 kColorAttachmentOptimal
451};
452
453void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
454#if defined(SK_VULKAN) && defined(SK_DEBUG)
455 VkImageLayout expected;
456
457 switch (layout) {
458 case VkLayout::kUndefined:
459 expected = VK_IMAGE_LAYOUT_UNDEFINED;
460 break;
461 case VkLayout::kReadOnlyOptimal:
462 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
463 break;
464 case VkLayout::kColorAttachmentOptimal:
465 expected = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
466 break;
467 default:
468 SkUNREACHABLE;
469 }
470
471 GrVkImageInfo vkII;
472
473 if (backendTex.getVkImageInfo(&vkII)) {
474 SkASSERT(expected == vkII.fImageLayout);
475 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
476 }
477#endif
478}
479
480///////////////////////////////////////////////////////////////////////////////
481// This test is a bit different from the others in this file. It is mainly checking that, for any
482// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
483// its characterization and then create a new surface that wraps that backend texture.
484DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
485 GrContext* context = ctxInfo.grContext();
486
487 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
488 SkColorType colorType = static_cast<SkColorType>(ct);
489
490 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
491
492 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
493 for (bool mipMaps : { true, false } ) {
494 for (int sampleCount : {1, 2}) {
495 SkSurfaceCharacterization c;
496
497 // Get a characterization, if possible
498 {
499 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
500 ii, sampleCount,
501 origin, nullptr, mipMaps);
502 if (!s) {
503 continue;
504 }
505
506 if (!s->characterize(&c)) {
507 continue;
508 }
509
510 REPORTER_ASSERT(reporter, s->isCompatible(c));
511 }
512
513 // Test out uninitialized path
514 {
515 GrBackendTexture backendTex = context->createBackendTexture(c);
516 check_vk_layout(backendTex, VkLayout::kUndefined);
517 REPORTER_ASSERT(reporter, backendTex.isValid());
518 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
519
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400520 {
521 GrBackendFormat format = context->defaultBackendFormat(
522 c.imageInfo().colorType(),
523 GrRenderable::kYes);
524 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
525 }
526
Robert Phillips02dc0302019-07-02 17:58:27 -0400527 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
528 backendTex);
529 REPORTER_ASSERT(reporter, s2);
530 REPORTER_ASSERT(reporter, s2->isCompatible(c));
531
532 s2 = nullptr;
533 context->deleteBackendTexture(backendTex);
534 }
535
536 // Test out color-initialized path
537 {
538 GrBackendTexture backendTex = context->createBackendTexture(c,
539 SkColors::kRed);
540 check_vk_layout(backendTex, VkLayout::kColorAttachmentOptimal);
541 REPORTER_ASSERT(reporter, backendTex.isValid());
542 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
543
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400544 {
545 GrBackendFormat format = context->defaultBackendFormat(
546 c.imageInfo().colorType(),
547 GrRenderable::kYes);
548 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
549 }
550
Robert Phillips02dc0302019-07-02 17:58:27 -0400551 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
552 backendTex);
553 REPORTER_ASSERT(reporter, s2);
554 REPORTER_ASSERT(reporter, s2->isCompatible(c));
555
556 s2 = nullptr;
557 context->deleteBackendTexture(backendTex);
558 }
559 }
560 }
561 }
562 }
563}
564
Robert Phillipsefb9f142019-05-17 14:19:44 -0400565///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400566DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
567 GrContext* context = ctxInfo.grContext();
568 const GrCaps* caps = context->priv().caps();
569
Robert Phillips459b2952019-05-23 09:38:27 -0400570 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400571 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400572
Robert Phillips0c6daf02019-05-16 12:43:11 -0400573 struct {
574 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400575 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400576 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400577 { kAlpha_8_SkColorType, kTransCol },
578 { kRGB_565_SkColorType, SkColors::kRed },
579 { kARGB_4444_SkColorType, SkColors::kGreen },
580 { kRGBA_8888_SkColorType, SkColors::kBlue },
581 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400582 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400583 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips459b2952019-05-23 09:38:27 -0400584 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400585 { kRGBA_1010102_SkColorType, { .25f, .5f, .75f, 1.0f }},
Robert Phillipsb04b6942019-05-21 17:24:31 -0400586 // The kRGB_101010x_SkColorType has no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400587 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
588 { kGray_8_SkColorType, kGrayCol },
589 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
590 { kRGBA_F16_SkColorType, SkColors::kYellow },
591 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400592 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400593 { kR16G16_unorm_SkColorType, SkColors::kGreen },
594 { kA16_unorm_SkColorType, kTransCol },
595 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400596 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400597 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400598 };
599
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400600 GR_STATIC_ASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400601
602 for (auto combo : combinations) {
603 SkColorType colorType = combo.fColorType;
604
Robert Phillips0c6daf02019-05-16 12:43:11 -0400605 if (GrBackendApi::kMetal == context->backend()) {
606 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
607 if (kRGBA_F32_SkColorType == combo.fColorType) {
608 continue;
609 }
610 }
611
Robert Phillipsefb9f142019-05-17 14:19:44 -0400612 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
613 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
614 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400615 }
616
Robert Phillipsefb9f142019-05-17 14:19:44 -0400617 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400618 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
619 renderable).isValid()) {
620 continue;
621 }
Robert Phillips7f367982019-09-26 14:01:36 -0400622
Robert Phillipsefb9f142019-05-17 14:19:44 -0400623 if (GrRenderable::kYes == renderable) {
624 if (kRGB_888x_SkColorType == combo.fColorType) {
625 // Ganesh can't perform the blends correctly when rendering this format
626 continue;
627 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400628 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400629
Robert Phillipsb04b6942019-05-21 17:24:31 -0400630 {
631 auto uninitCreateMtd = [colorType](GrContext* context,
632 GrMipMapped mipMapped,
633 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400634 auto result = context->createBackendTexture(32, 32, colorType,
635 mipMapped, renderable,
636 GrProtected::kNo);
637 check_vk_layout(result, VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400638
639#ifdef SK_DEBUG
640 {
641 GrBackendFormat format = context->defaultBackendFormat(colorType,
642 renderable);
643 SkASSERT(format == result.getBackendFormat());
644 }
645#endif
646
Robert Phillips02dc0302019-07-02 17:58:27 -0400647 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400648 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400649
Robert Phillipsb04b6942019-05-21 17:24:31 -0400650 test_wrapping(context, reporter, uninitCreateMtd,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400651 SkColorTypeToGrColorType(colorType), mipMapped, renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400652 }
Robert Phillips459b2952019-05-23 09:38:27 -0400653
654 {
Robert Phillips459b2952019-05-23 09:38:27 -0400655
656 auto createWithColorMtd = [colorType](GrContext* context,
657 const SkColor4f& color,
658 GrMipMapped mipMapped,
659 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400660 auto result = context->createBackendTexture(32, 32, colorType, color,
661 mipMapped, renderable,
662 GrProtected::kNo);
663 check_vk_layout(result, GrRenderable::kYes == renderable
664 ? VkLayout::kColorAttachmentOptimal
665 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400666
667#ifdef SK_DEBUG
668 {
669 GrBackendFormat format = context->defaultBackendFormat(colorType,
670 renderable);
671 SkASSERT(format == result.getBackendFormat());
672 }
673#endif
674
Robert Phillips02dc0302019-07-02 17:58:27 -0400675 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400676 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500677 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
678 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
679 // the color passed to it. However, createBackendTexture() that takes a
680 // SkColor4f is color type / alpha type unaware and will simply compute
681 // luminance from the r, g, b, channels.
682 SkColor4f color = combo.fColor;
683 if (colorType == kGray_8_SkColorType) {
684 color = {color.fR * color.fA,
685 color.fG * color.fA,
686 color.fB * color.fA,
687 1.f};
688 }
Robert Phillips459b2952019-05-23 09:38:27 -0400689 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon85c3d682019-11-04 15:04:54 -0500690 SkColorTypeToGrColorType(colorType), color, mipMapped,
691 renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400692 }
Robert Phillips7f367982019-09-26 14:01:36 -0400693
Brian Salomon85c3d682019-11-04 15:04:54 -0500694 auto createWithSrcDataMtd = [](GrContext* context,
695 const SkPixmap srcData[],
696 int numLevels,
697 GrRenderable renderable) {
698 SkASSERT(srcData && numLevels);
699 auto result = context->createBackendTexture(srcData, numLevels, renderable,
700 GrProtected::kNo);
701 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400702#ifdef SK_DEBUG
Brian Salomon85c3d682019-11-04 15:04:54 -0500703 {
704 auto format =
705 context->defaultBackendFormat(srcData[0].colorType(), renderable);
706 SkASSERT(format == result.getBackendFormat());
707 }
Robert Phillips7f367982019-09-26 14:01:36 -0400708#endif
Brian Salomon85c3d682019-11-04 15:04:54 -0500709 return result;
710 };
Robert Phillips7f367982019-09-26 14:01:36 -0400711
Brian Salomon85c3d682019-11-04 15:04:54 -0500712 test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType, mipMapped,
713 renderable);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400714 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400715 }
716 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400717}
718
Robert Phillipsefb9f142019-05-17 14:19:44 -0400719///////////////////////////////////////////////////////////////////////////////
720#ifdef SK_GL
721
722#include "src/gpu/gl/GrGLCaps.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -0400723#include "src/gpu/gl/GrGLDefines.h"
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400724#include "src/gpu/gl/GrGLUtil.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -0400725
726DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
727 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
728 GrGLStandard standard = glCtx->gl()->fStandard;
729 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400730 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400731
Robert Phillips459b2952019-05-23 09:38:27 -0400732 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400733 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400734
Robert Phillips0c6daf02019-05-16 12:43:11 -0400735 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400736 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400737 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400738 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400739 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400740 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
741 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400742
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400743 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
744 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400745
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400746 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
747 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
748 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
749 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.5f, 0, 0, 1.0f } },
750 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
751 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400752
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400753 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
754 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400755
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400756 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
757 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400758
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400759 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400760
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400761 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
762 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400763
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400764 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400765 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
766 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400767
Robert Phillips429f0d32019-09-11 17:03:28 -0400768 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400769 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400770
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400771 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
772 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400773 };
774
775 for (auto combo : combinations) {
776 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
777
Greg Daniel7bfc9132019-08-14 14:23:53 -0400778 if (!glCaps->isFormatTexturable(format)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400779 continue;
780 }
Greg Daniele877dce2019-07-11 10:52:43 -0400781
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400782 if (GrColorType::kBGRA_8888 == combo.fColorType) {
Brian Salomon85c3d682019-11-04 15:04:54 -0500783 // We allow using a GL_RGBA8 texture as BGRA on desktop GL but not ES.
Robert Phillips0c6daf02019-05-16 12:43:11 -0400784 if (GR_GL_RGBA8 == combo.fFormat && kGL_GrGLStandard != standard) {
785 continue;
786 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400787 }
788
Robert Phillipsefb9f142019-05-17 14:19:44 -0400789 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
790 if (GrMipMapped::kYes == mipMapped && !glCaps->mipMapSupport()) {
791 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400792 }
793
Robert Phillipsefb9f142019-05-17 14:19:44 -0400794 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400795
Robert Phillipsefb9f142019-05-17 14:19:44 -0400796 if (GrRenderable::kYes == renderable) {
Greg Daniel900583a2019-08-06 12:05:31 -0400797 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400798 continue;
799 }
800 }
801
Robert Phillipsd34691b2019-09-24 13:38:43 -0400802 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400803 auto uninitCreateMtd = [format](GrContext* context,
804 GrMipMapped mipMapped,
805 GrRenderable renderable) {
806 return context->createBackendTexture(32, 32, format,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400807 mipMapped, renderable,
808 GrProtected::kNo);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400809 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400810
Robert Phillipsb04b6942019-05-21 17:24:31 -0400811 test_wrapping(context, reporter, uninitCreateMtd,
812 combo.fColorType, mipMapped, renderable);
813 }
Robert Phillips459b2952019-05-23 09:38:27 -0400814
815 {
Brian Salomon85c3d682019-11-04 15:04:54 -0500816 // We're creating backend textures without specifying a color type "view" of
817 // them at the public API level. Therefore, Ganesh will not apply any swizzles
818 // before writing the color to the texture. However, our validation code does
819 // rely on interpreting the texture contents via a SkColorType and therefore
820 // swizzles may be applied during the read step.
821 // Ideally we'd update our validation code to use a "raw" read that doesn't
822 // impose a color type but for now we just munge the data we upload to match the
823 // expectation.
824 GrSwizzle swizzle;
825 switch (combo.fColorType) {
826 case GrColorType::kAlpha_8:
827 swizzle = GrSwizzle("aaaa");
828 break;
829 case GrColorType::kAlpha_16:
830 swizzle = GrSwizzle("aaaa");
831 break;
832 case GrColorType::kAlpha_F16:
833 swizzle = GrSwizzle("aaaa");
834 break;
835 default:
836 break;
Robert Phillips459b2952019-05-23 09:38:27 -0400837 }
838
Brian Salomon85c3d682019-11-04 15:04:54 -0500839 auto createWithColorMtd = [format, swizzle](GrContext* context,
840 const SkColor4f& color,
841 GrMipMapped mipMapped,
842 GrRenderable renderable) {
843 auto swizzledColor = swizzle.applyTo(color);
844 return context->createBackendTexture(32, 32, format, swizzledColor,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400845 mipMapped, renderable,
846 GrProtected::kNo);
Robert Phillips459b2952019-05-23 09:38:27 -0400847 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500848 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
849 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
850 // the color passed to it. However, createBackendTexture() that takes a
851 // SkColor4f is color type/alpha type unaware and will simply compute luminance
852 //from the r, g, b, channels.
853 SkColor4f color = combo.fColor;
854 if (combo.fColorType == GrColorType::kGray_8) {
855 color = {color.fR * color.fA,
856 color.fG * color.fA,
857 color.fB * color.fA,
858 1.f};
859 }
Robert Phillips459b2952019-05-23 09:38:27 -0400860
Brian Salomon85c3d682019-11-04 15:04:54 -0500861 test_color_init(context, reporter, createWithColorMtd, combo.fColorType, color,
862 mipMapped, renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400863 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400864 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400865 }
866 }
867}
868
Robert Phillipsefb9f142019-05-17 14:19:44 -0400869#endif
870
871///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400872
873#ifdef SK_VULKAN
874
875#include "src/gpu/vk/GrVkCaps.h"
876
877DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
878 GrContext* context = ctxInfo.grContext();
879 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
880
Robert Phillips459b2952019-05-23 09:38:27 -0400881 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400882 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400883
Robert Phillips0c6daf02019-05-16 12:43:11 -0400884 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400885 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400886 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400887 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400888 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400889 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
890 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400891
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400892 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
893 // there is nothing to tell Skia to make the provided color opaque. Clients will need
894 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400895 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
896 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400897
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400898 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400899
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400900 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32, { 0.5f, 0, 0, 1.0f }},
901 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400902
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400903 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
904 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400905
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400906 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400907 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
908 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
909 // the alpha channel of the color). Clients should, in general, fill all the channels
910 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400911 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400912
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400913 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
914 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400915
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400916 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400917 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
918
Robert Phillips429f0d32019-09-11 17:03:28 -0400919 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400920 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400921 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
922 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400923 };
924
925 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400926 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400927 continue;
928 }
929
930 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
931
Robert Phillipsefb9f142019-05-17 14:19:44 -0400932 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
933 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
934 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400935 }
936
Robert Phillipsefb9f142019-05-17 14:19:44 -0400937 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400938
Robert Phillipsefb9f142019-05-17 14:19:44 -0400939 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400940 // We must also check whether we allow rendering to the format using the
941 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -0400942 if (!vkCaps->isFormatAsColorTypeRenderable(
943 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400944 continue;
945 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400946 }
947
Robert Phillipsd34691b2019-09-24 13:38:43 -0400948 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400949 auto uninitCreateMtd = [format](GrContext* context,
Robert Phillips459b2952019-05-23 09:38:27 -0400950 GrMipMapped mipMapped,
951 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400952 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
953 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400954 renderable,
955 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400956 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400957 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400958 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400959
Robert Phillipsb04b6942019-05-21 17:24:31 -0400960 test_wrapping(context, reporter, uninitCreateMtd,
961 combo.fColorType, mipMapped, renderable);
962 }
Robert Phillips459b2952019-05-23 09:38:27 -0400963
Robert Phillips459b2952019-05-23 09:38:27 -0400964 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400965 // We're creating backend textures without specifying a color type "view" of
966 // them at the public API level. Therefore, Ganesh will not apply any swizzles
967 // before writing the color to the texture. However, our validation code does
968 // rely on interpreting the texture contents via a SkColorType and therefore
969 // swizzles may be applied during the read step.
970 // Ideally we'd update our validation code to use a "raw" read that doesn't
971 // impose a color type but for now we just munge the data we upload to match the
972 // expectation.
973 GrSwizzle swizzle;
974 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400975 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400976 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
977 swizzle = GrSwizzle("aaaa");
978 break;
Robert Phillips429f0d32019-09-11 17:03:28 -0400979 case GrColorType::kAlpha_16:
980 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
981 swizzle = GrSwizzle("aaaa");
982 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -0400983 case GrColorType::kAlpha_F16:
984 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
985 swizzle = GrSwizzle("aaaa");
986 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400987 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400988 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
989 swizzle = GrSwizzle("bgra");
990 }
991 break;
992 default:
993 swizzle = GrSwizzle("rgba");
994 break;
995 }
996 auto createWithColorMtd = [format, swizzle](GrContext* context,
997 const SkColor4f& color,
998 GrMipMapped mipMapped,
999 GrRenderable renderable) {
1000 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001001 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -04001002 swizzledColor,
1003 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -04001004 renderable,
1005 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -04001006 check_vk_layout(beTex, GrRenderable::kYes == renderable
1007 ? VkLayout::kColorAttachmentOptimal
1008 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001009 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -04001010 };
Robert Phillips459b2952019-05-23 09:38:27 -04001011 test_color_init(context, reporter, createWithColorMtd,
1012 combo.fColorType, combo.fColor, mipMapped, renderable);
1013 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001014 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001015 }
1016 }
1017}
1018
1019#endif