blob: 527ddebcd5931fd61b7e8a677d7c63996aee9e30 [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
Robert Phillipsee946932019-12-18 11:16:17 -050019#include "src/gpu/gl/GrGLCaps.h"
20#include "src/gpu/gl/GrGLDefines.h"
Robert Phillips27eb5252019-06-03 12:59:40 -040021#include "src/gpu/gl/GrGLGpu.h"
22#include "src/gpu/gl/GrGLUtil.h"
23#endif
24
Robert Phillips7f367982019-09-26 14:01:36 -040025#ifdef SK_METAL
26#include "include/gpu/mtl/GrMtlTypes.h"
27#include "src/gpu/mtl/GrMtlCppUtil.h"
28#endif
29
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040030// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillips0c6daf02019-05-16 12:43:11 -040031void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040032 std::function<GrBackendTexture (GrContext*,
33 GrMipMapped,
34 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040035 GrColorType grColorType, GrMipMapped mipMapped, GrRenderable renderable) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040036 GrResourceCache* cache = context->priv().getResourceCache();
37
38 const int initialCount = cache->getResourceCount();
39
Robert Phillipsefb9f142019-05-17 14:19:44 -040040 GrBackendTexture backendTex = create(context, mipMapped, renderable);
41 if (!backendTex.isValid()) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040042 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
43 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040044 GrRenderable::kYes == renderable ? "yes" : "no");
45 return;
46 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040047
Robert Phillips0c6daf02019-05-16 12:43:11 -040048 // Skia proper should know nothing about the new backend object
49 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
50
Robert Phillipsb7f95d12019-07-26 11:13:19 -040051 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
52
53 // Wrapping a backendTexture in an image requires an SkColorType
54 if (kUnknown_SkColorType == skColorType) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040055 context->deleteBackendTexture(backendTex);
56 return;
57 }
58
Robert Phillipsd470e1b2019-09-04 15:05:35 -040059 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040060 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040061 backendTex,
62 kTopLeft_GrSurfaceOrigin,
63 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040064 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040065 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040066 if (!surf) {
67 ERRORF(reporter, "Couldn't make surface from backendTexture for colorType %d\n",
Robert Phillipsb7f95d12019-07-26 11:13:19 -040068 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040069 } else {
70 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040071 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040072 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040073
Robert Phillipsb04b6942019-05-21 17:24:31 -040074 {
75 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040076 backendTex,
77 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040078 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040079 kPremul_SkAlphaType,
80 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040081 if (!img) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040082 ERRORF(reporter, "Couldn't make image from backendTexture for skColorType %d\n",
83 skColorType);
Robert Phillipsb04b6942019-05-21 17:24:31 -040084 } else {
85 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -040086
Robert Phillipsb04b6942019-05-21 17:24:31 -040087 GrTextureProxy* proxy = ib->peekProxy();
88 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -040089
Robert Phillipsb04b6942019-05-21 17:24:31 -040090 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
91 REPORTER_ASSERT(reporter, proxy->isInstantiated());
92 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -040093
Robert Phillipsb04b6942019-05-21 17:24:31 -040094 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040095 }
96 }
97
98 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
99
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400100 context->deleteBackendTexture(backendTex);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400101}
102
Robert Phillips7f367982019-09-26 14:01:36 -0400103static bool isBGRA(const GrBackendFormat& format) {
104 switch (format.backend()) {
105 case GrBackendApi::kMetal:
106#ifdef SK_METAL
107 return GrMtlFormatIsBGRA(format.asMtlFormat());
108#else
109 return false;
110#endif
111 case GrBackendApi::kDawn:
112 return false;
113 case GrBackendApi::kOpenGL:
114#ifdef SK_GL
115 return format.asGLFormat() == GrGLFormat::kBGRA8;
116#else
117 return false;
118#endif
119 case GrBackendApi::kVulkan: {
120#ifdef SK_VULKAN
121 VkFormat vkFormat;
122 format.asVkFormat(&vkFormat);
123 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
124#else
125 return false;
126#endif
127 }
Robert Phillipsa27d6252019-12-10 14:48:36 -0500128 case GrBackendApi::kMock: {
129 SkImage::CompressionType compression = format.asMockCompressionType();
130 if (compression != SkImage::CompressionType::kNone) {
131 return false; // No compressed formats are BGRA
132 }
133
Robert Phillips7f367982019-09-26 14:01:36 -0400134 return format.asMockColorType() == GrColorType::kBGRA_8888;
Robert Phillipsa27d6252019-12-10 14:48:36 -0500135 }
Robert Phillips7f367982019-09-26 14:01:36 -0400136 }
137 SkUNREACHABLE;
138}
139
140static bool isRGB(const GrBackendFormat& format) {
141 switch (format.backend()) {
142 case GrBackendApi::kMetal:
143 return false; // Metal doesn't even pretend to support this
144 case GrBackendApi::kDawn:
145 return false;
146 case GrBackendApi::kOpenGL:
147#ifdef SK_GL
148 return format.asGLFormat() == GrGLFormat::kRGB8;
149#else
150 return false;
151#endif
152 case GrBackendApi::kVulkan: {
153#ifdef SK_VULKAN
154 VkFormat vkFormat;
155 format.asVkFormat(&vkFormat);
156 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
157#else
158 return false;
159#endif
160 }
161 case GrBackendApi::kMock:
162 return false; // No GrColorType::kRGB_888
163 }
164 SkUNREACHABLE;
165}
166
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400167static void check_solid_pixmap(skiatest::Reporter* reporter,
168 const SkColor4f& expected, const SkPixmap& actual,
Robert Phillips7f367982019-09-26 14:01:36 -0400169 SkColorType ct, const char* label1, const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400170 // we need 0.001f across the board just for noise
171 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400172 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400173
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400174 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400175 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400176 SkASSERT(x >= 0 && y >= 0);
Robert Phillips7f367982019-09-26 14:01:36 -0400177 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
178 ToolUtils::colortype_name(ct), label1, label2, x, y,
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400179 diffs[0], diffs[1], diffs[2], diffs[3]);
180 });
181
Brian Salomon28a8f282019-10-24 20:07:39 -0400182 CheckSolidPixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400183}
184
Robert Phillips7f367982019-09-26 14:01:36 -0400185// What would raster do?
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400186static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
Robert Phillips7f367982019-09-26 14:01:36 -0400187 SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
188 : kPremul_SkAlphaType;
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400189
Robert Phillips7f367982019-09-26 14:01:36 -0400190 SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
191 SkAutoPixmapStorage pm;
192 pm.alloc(ii);
193 pm.erase(orig);
194 SkColor tmp = pm.getColor(0, 0);
195 return SkColor4f::FromColor(tmp);
Robert Phillips459b2952019-05-23 09:38:27 -0400196}
197
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400198static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
199 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400200 skiatest::Reporter* reporter, const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400201
Robert Phillips0ee10342019-09-25 09:55:16 -0400202static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
203 SkColorType skColorType, GrRenderable renderable,
Robert Phillips7f367982019-09-26 14:01:36 -0400204 const SkColor4f& color, skiatest::Reporter* reporter,
205 const char* label) {
206 if (isRGB(backendTex.getBackendFormat())) {
207 // readPixels is busted for the RGB backend format (skbug.com/8862)
208 // TODO: add a GrColorType::kRGB_888 to fix the situation
209 return;
210 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400211
212 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
213 : kPremul_SkAlphaType;
214
215 SkColor4f expectedColor = get_expected_color(color, skColorType);
216
217 SkAutoPixmapStorage actual;
218
219 {
220 SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400221 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400222
223 SkAssertResult(actual.tryAlloc(readBackII));
224 }
225
Robert Phillips0ee10342019-09-25 09:55:16 -0400226 {
227 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
228 backendTex,
229 kTopLeft_GrSurfaceOrigin,
230 skColorType,
231 at,
232 nullptr);
233 if (img) {
234 actual.erase(SkColors::kTransparent);
235 bool result = img->readPixels(actual, 0, 0);
236 if (!result) {
237 // TODO: we need a better way to tell a priori if readPixels will work for an
238 // arbitrary colorType
239#if 0
240 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n", colorType);
241#endif
242 } else {
243 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400244 label, "SkImage::readPixels");
Robert Phillips0ee10342019-09-25 09:55:16 -0400245 }
246 }
247 }
Robert Phillips7f367982019-09-26 14:01:36 -0400248
249 // This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
250 // backend texture) so it must be done last!
251 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
252 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
253 backendTex,
254 kTopLeft_GrSurfaceOrigin,
255 0,
256 skColorType,
257 nullptr, nullptr);
258 if (surf) {
259 actual.erase(SkColors::kTransparent);
260 bool result = surf->readPixels(actual, 0, 0);
261 REPORTER_ASSERT(reporter, result);
262
263 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
264 label, "SkSurface::readPixels");
265 }
266 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400267}
268
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400269// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillips459b2952019-05-23 09:38:27 -0400270void test_color_init(GrContext* context, skiatest::Reporter* reporter,
271 std::function<GrBackendTexture (GrContext*,
272 const SkColor4f&,
273 GrMipMapped,
274 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400275 GrColorType grColorType, const SkColor4f& color,
Robert Phillips459b2952019-05-23 09:38:27 -0400276 GrMipMapped mipMapped, GrRenderable renderable) {
277 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
278 if (!backendTex.isValid()) {
279 // errors here should be reported by the test_wrapping test
280 return;
281 }
282
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400283 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
284
285 // Can't wrap backend textures in images and surfaces w/o an SkColorType
286 if (kUnknown_SkColorType == skColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400287 // TODO: burrow in and scrappily check that data was uploaded!
288 context->deleteBackendTexture(backendTex);
289 return;
290 }
291
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400292 if (mipMapped == GrMipMapped::kYes) {
293 SkColor4f expectedColor = get_expected_color(color, skColorType);
294 SkColor4f expectedColors[6] = { expectedColor, expectedColor, expectedColor,
295 expectedColor, expectedColor, expectedColor };
Robert Phillips7f367982019-09-26 14:01:36 -0400296 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400297 }
298
Robert Phillips7f367982019-09-26 14:01:36 -0400299 // The last step in this test will dirty the mipmaps so do it last
300 check_base_readbacks(context, backendTex, skColorType, renderable, color,
301 reporter, "colorinit");
Robert Phillips459b2952019-05-23 09:38:27 -0400302 context->deleteBackendTexture(backendTex);
303}
304
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400305// Draw the backend texture (wrapped in an SkImage) into an RGBA surface, attempting to access
306// all the mipMap levels.
307static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
308 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400309 skiatest::Reporter* reporter, const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400310
311#ifdef SK_GL
312 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
313 if (GrBackendApi::kOpenGL == context->backend()) {
314 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
315
316 if (kRGBA_F32_SkColorType == skColorType &&
317 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
318 return;
319 }
320 }
321#endif
322
Robert Phillips7f367982019-09-26 14:01:36 -0400323 if (isRGB(backendTex.getBackendFormat())) {
324 // readPixels is busted for the RGB backend format (skbug.com/8862)
325 // TODO: add a GrColorType::kRGB_888 to fix the situation
326 return;
327 }
328
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400329 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
330 : kPremul_SkAlphaType;
Robert Phillips7f367982019-09-26 14:01:36 -0400331
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400332 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
333 backendTex,
334 kTopLeft_GrSurfaceOrigin,
335 skColorType,
336 at,
337 nullptr);
338 if (!img) {
339 return;
340 }
341
Robert Phillips7f367982019-09-26 14:01:36 -0400342 SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
343 kPremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400344
345 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
346 SkBudgeted::kNo,
Robert Phillips7f367982019-09-26 14:01:36 -0400347 readbackSurfaceII, 1,
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400348 kTopLeft_GrSurfaceOrigin,
349 nullptr);
350 if (!surf) {
351 return;
352 }
353
354 SkCanvas* canvas = surf->getCanvas();
355
356 SkPaint p;
357 p.setFilterQuality(kHigh_SkFilterQuality);
358
359 int numMipLevels = 6;
360
361 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
362 SkASSERT(rectSize >= 1);
363
364 SkRect r = SkRect::MakeWH(rectSize, rectSize);
365 canvas->clear(SK_ColorTRANSPARENT);
366 canvas->drawImageRect(img, r, &p);
367
368 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
369 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400370 kUnpremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400371 SkAutoPixmapStorage actual2;
372 SkAssertResult(actual2.tryAlloc(readbackII));
373 actual2.erase(SkColors::kTransparent);
374
375 bool result = surf->readPixels(actual2, 0, 0);
376 REPORTER_ASSERT(reporter, result);
377
Robert Phillipsee946932019-12-18 11:16:17 -0500378 SkString str;
379 str.appendf("mip-level %d", i);
380
Robert Phillips7f367982019-09-26 14:01:36 -0400381 check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
Robert Phillipsee946932019-12-18 11:16:17 -0500382 label, str.c_str());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400383 }
384}
385
Robert Phillips7f367982019-09-26 14:01:36 -0400386static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
387 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
388 int levelSize = 32;
389 int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
390 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
391 : kPremul_SkAlphaType;
392 for (int level = 0; level < numMipLevels; ++level) {
393 SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
394 pixmaps[level].alloc(ii);
395 pixmaps[level].erase(colors[level]);
396 levelSize /= 2;
397 }
398 return numMipLevels;
399}
400
401// Test initialization of GrBackendObjects using SkPixmaps
402static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
403 std::function<GrBackendTexture (GrContext*,
404 const SkPixmap srcData[],
405 int numLevels,
406 GrRenderable)> create,
407 SkColorType skColorType, GrMipMapped mipMapped,
408 GrRenderable renderable) {
409 SkAutoPixmapStorage pixmapMem[6];
410 SkColor4f colors[6] = {
411 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
412 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
413 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
414 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
415 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
416 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
417 };
418
419 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
420 SkASSERT(numMipLevels);
421
422 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
423 SkPixmap pixmaps[6];
424 for (int i = 0; i < numMipLevels; ++i) {
425 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
426 }
427
428 GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
429 if (!backendTex.isValid()) {
430 // errors here should be reported by the test_wrapping test
431 return;
432 }
433
434 if (skColorType == kBGRA_8888_SkColorType && !isBGRA(backendTex.getBackendFormat())) {
435 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
436 return;
437 }
438
439 if (mipMapped == GrMipMapped::kYes) {
440 SkColor4f expectedColors[6] = {
441 get_expected_color(colors[0], skColorType),
442 get_expected_color(colors[1], skColorType),
443 get_expected_color(colors[2], skColorType),
444 get_expected_color(colors[3], skColorType),
445 get_expected_color(colors[4], skColorType),
446 get_expected_color(colors[5], skColorType),
447 };
448
449 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
450 }
451
452 // The last step in this test will dirty the mipmaps so do it last
453 check_base_readbacks(context, backendTex, skColorType, renderable, colors[0],
454 reporter, "pixmap");
455 context->deleteBackendTexture(backendTex);
456}
457
Robert Phillips02dc0302019-07-02 17:58:27 -0400458enum class VkLayout {
459 kUndefined,
460 kReadOnlyOptimal,
461 kColorAttachmentOptimal
462};
463
464void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
465#if defined(SK_VULKAN) && defined(SK_DEBUG)
466 VkImageLayout expected;
467
468 switch (layout) {
469 case VkLayout::kUndefined:
470 expected = VK_IMAGE_LAYOUT_UNDEFINED;
471 break;
472 case VkLayout::kReadOnlyOptimal:
473 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
474 break;
475 case VkLayout::kColorAttachmentOptimal:
476 expected = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
477 break;
478 default:
479 SkUNREACHABLE;
480 }
481
482 GrVkImageInfo vkII;
483
484 if (backendTex.getVkImageInfo(&vkII)) {
485 SkASSERT(expected == vkII.fImageLayout);
486 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
487 }
488#endif
489}
490
491///////////////////////////////////////////////////////////////////////////////
492// This test is a bit different from the others in this file. It is mainly checking that, for any
493// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
494// its characterization and then create a new surface that wraps that backend texture.
495DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
496 GrContext* context = ctxInfo.grContext();
497
498 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
499 SkColorType colorType = static_cast<SkColorType>(ct);
500
501 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
502
503 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
504 for (bool mipMaps : { true, false } ) {
505 for (int sampleCount : {1, 2}) {
506 SkSurfaceCharacterization c;
507
508 // Get a characterization, if possible
509 {
510 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
511 ii, sampleCount,
512 origin, nullptr, mipMaps);
513 if (!s) {
514 continue;
515 }
516
517 if (!s->characterize(&c)) {
518 continue;
519 }
520
521 REPORTER_ASSERT(reporter, s->isCompatible(c));
522 }
523
524 // Test out uninitialized path
525 {
526 GrBackendTexture backendTex = context->createBackendTexture(c);
527 check_vk_layout(backendTex, VkLayout::kUndefined);
528 REPORTER_ASSERT(reporter, backendTex.isValid());
529 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
530
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400531 {
532 GrBackendFormat format = context->defaultBackendFormat(
533 c.imageInfo().colorType(),
534 GrRenderable::kYes);
535 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
536 }
537
Robert Phillips02dc0302019-07-02 17:58:27 -0400538 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
539 backendTex);
540 REPORTER_ASSERT(reporter, s2);
541 REPORTER_ASSERT(reporter, s2->isCompatible(c));
542
543 s2 = nullptr;
544 context->deleteBackendTexture(backendTex);
545 }
546
547 // Test out color-initialized path
548 {
549 GrBackendTexture backendTex = context->createBackendTexture(c,
550 SkColors::kRed);
551 check_vk_layout(backendTex, VkLayout::kColorAttachmentOptimal);
552 REPORTER_ASSERT(reporter, backendTex.isValid());
553 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
554
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400555 {
556 GrBackendFormat format = context->defaultBackendFormat(
557 c.imageInfo().colorType(),
558 GrRenderable::kYes);
559 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
560 }
561
Robert Phillips02dc0302019-07-02 17:58:27 -0400562 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
563 backendTex);
564 REPORTER_ASSERT(reporter, s2);
565 REPORTER_ASSERT(reporter, s2->isCompatible(c));
566
567 s2 = nullptr;
568 context->deleteBackendTexture(backendTex);
569 }
570 }
571 }
572 }
573 }
574}
575
Robert Phillipsefb9f142019-05-17 14:19:44 -0400576///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400577DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
578 GrContext* context = ctxInfo.grContext();
579 const GrCaps* caps = context->priv().caps();
580
Robert Phillips459b2952019-05-23 09:38:27 -0400581 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400582 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400583
Robert Phillips0c6daf02019-05-16 12:43:11 -0400584 struct {
585 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400586 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400587 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400588 { kAlpha_8_SkColorType, kTransCol },
589 { kRGB_565_SkColorType, SkColors::kRed },
590 { kARGB_4444_SkColorType, SkColors::kGreen },
591 { kRGBA_8888_SkColorType, SkColors::kBlue },
592 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400593 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400594 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips459b2952019-05-23 09:38:27 -0400595 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400596 { kRGBA_1010102_SkColorType, { .25f, .5f, .75f, 1.0f }},
Robert Phillipsb04b6942019-05-21 17:24:31 -0400597 // The kRGB_101010x_SkColorType has no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400598 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
599 { kGray_8_SkColorType, kGrayCol },
600 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
601 { kRGBA_F16_SkColorType, SkColors::kYellow },
602 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400603 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400604 { kR16G16_unorm_SkColorType, SkColors::kGreen },
605 { kA16_unorm_SkColorType, kTransCol },
606 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400607 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400608 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400609 };
610
Brian Salomon4dea72a2019-12-18 10:43:10 -0500611 static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400612
613 for (auto combo : combinations) {
614 SkColorType colorType = combo.fColorType;
615
Robert Phillips0c6daf02019-05-16 12:43:11 -0400616 if (GrBackendApi::kMetal == context->backend()) {
617 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
618 if (kRGBA_F32_SkColorType == combo.fColorType) {
619 continue;
620 }
621 }
622
Robert Phillipsefb9f142019-05-17 14:19:44 -0400623 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
624 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
625 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400626 }
627
Robert Phillipsefb9f142019-05-17 14:19:44 -0400628 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400629 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
630 renderable).isValid()) {
631 continue;
632 }
Robert Phillips7f367982019-09-26 14:01:36 -0400633
Robert Phillipsefb9f142019-05-17 14:19:44 -0400634 if (GrRenderable::kYes == renderable) {
635 if (kRGB_888x_SkColorType == combo.fColorType) {
636 // Ganesh can't perform the blends correctly when rendering this format
637 continue;
638 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400639 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400640
Robert Phillipsb04b6942019-05-21 17:24:31 -0400641 {
642 auto uninitCreateMtd = [colorType](GrContext* context,
643 GrMipMapped mipMapped,
644 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400645 auto result = context->createBackendTexture(32, 32, colorType,
646 mipMapped, renderable,
647 GrProtected::kNo);
648 check_vk_layout(result, VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400649
650#ifdef SK_DEBUG
651 {
652 GrBackendFormat format = context->defaultBackendFormat(colorType,
653 renderable);
654 SkASSERT(format == result.getBackendFormat());
655 }
656#endif
657
Robert Phillips02dc0302019-07-02 17:58:27 -0400658 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400659 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400660
Robert Phillipsb04b6942019-05-21 17:24:31 -0400661 test_wrapping(context, reporter, uninitCreateMtd,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400662 SkColorTypeToGrColorType(colorType), mipMapped, renderable);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400663 }
Robert Phillips459b2952019-05-23 09:38:27 -0400664
665 {
Robert Phillips459b2952019-05-23 09:38:27 -0400666
667 auto createWithColorMtd = [colorType](GrContext* context,
668 const SkColor4f& color,
669 GrMipMapped mipMapped,
670 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400671 auto result = context->createBackendTexture(32, 32, colorType, color,
672 mipMapped, renderable,
673 GrProtected::kNo);
674 check_vk_layout(result, GrRenderable::kYes == renderable
675 ? VkLayout::kColorAttachmentOptimal
676 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400677
678#ifdef SK_DEBUG
679 {
680 GrBackendFormat format = context->defaultBackendFormat(colorType,
681 renderable);
682 SkASSERT(format == result.getBackendFormat());
683 }
684#endif
685
Robert Phillips02dc0302019-07-02 17:58:27 -0400686 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400687 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500688 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
689 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
690 // the color passed to it. However, createBackendTexture() that takes a
691 // SkColor4f is color type / alpha type unaware and will simply compute
692 // luminance from the r, g, b, channels.
693 SkColor4f color = combo.fColor;
694 if (colorType == kGray_8_SkColorType) {
695 color = {color.fR * color.fA,
696 color.fG * color.fA,
697 color.fB * color.fA,
698 1.f};
699 }
Robert Phillips459b2952019-05-23 09:38:27 -0400700 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon85c3d682019-11-04 15:04:54 -0500701 SkColorTypeToGrColorType(colorType), color, mipMapped,
702 renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400703 }
Robert Phillips7f367982019-09-26 14:01:36 -0400704
Brian Salomon85c3d682019-11-04 15:04:54 -0500705 auto createWithSrcDataMtd = [](GrContext* context,
706 const SkPixmap srcData[],
707 int numLevels,
708 GrRenderable renderable) {
709 SkASSERT(srcData && numLevels);
710 auto result = context->createBackendTexture(srcData, numLevels, renderable,
711 GrProtected::kNo);
712 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400713#ifdef SK_DEBUG
Brian Salomon85c3d682019-11-04 15:04:54 -0500714 {
715 auto format =
716 context->defaultBackendFormat(srcData[0].colorType(), renderable);
717 SkASSERT(format == result.getBackendFormat());
718 }
Robert Phillips7f367982019-09-26 14:01:36 -0400719#endif
Brian Salomon85c3d682019-11-04 15:04:54 -0500720 return result;
721 };
Robert Phillips7f367982019-09-26 14:01:36 -0400722
Brian Salomon85c3d682019-11-04 15:04:54 -0500723 test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType, mipMapped,
724 renderable);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400725 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400726 }
727 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400728}
729
Robert Phillipsefb9f142019-05-17 14:19:44 -0400730///////////////////////////////////////////////////////////////////////////////
731#ifdef SK_GL
732
Robert Phillips0c6daf02019-05-16 12:43:11 -0400733DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
734 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
735 GrGLStandard standard = glCtx->gl()->fStandard;
736 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400737 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400738
Robert Phillips459b2952019-05-23 09:38:27 -0400739 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400740 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400741
Robert Phillips0c6daf02019-05-16 12:43:11 -0400742 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400743 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400744 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400745 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400746 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400747 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
748 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400749
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400750 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
751 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400752
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400753 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
754 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
755 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
756 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.5f, 0, 0, 1.0f } },
757 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
758 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400759
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400760 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
761 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400762
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400763 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
764 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400765
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400766 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400767
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400768 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
769 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400770
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400771 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400772 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
773 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400774
Robert Phillips429f0d32019-09-11 17:03:28 -0400775 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400776 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400777
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400778 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
779 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400780 };
781
782 for (auto combo : combinations) {
783 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
784
Greg Daniel7bfc9132019-08-14 14:23:53 -0400785 if (!glCaps->isFormatTexturable(format)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400786 continue;
787 }
Greg Daniele877dce2019-07-11 10:52:43 -0400788
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400789 if (GrColorType::kBGRA_8888 == combo.fColorType) {
Brian Salomon85c3d682019-11-04 15:04:54 -0500790 // We allow using a GL_RGBA8 texture as BGRA on desktop GL but not ES.
Robert Phillips0c6daf02019-05-16 12:43:11 -0400791 if (GR_GL_RGBA8 == combo.fFormat && kGL_GrGLStandard != standard) {
792 continue;
793 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400794 }
795
Robert Phillipsefb9f142019-05-17 14:19:44 -0400796 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
797 if (GrMipMapped::kYes == mipMapped && !glCaps->mipMapSupport()) {
798 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400799 }
800
Robert Phillipsefb9f142019-05-17 14:19:44 -0400801 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400802
Robert Phillipsefb9f142019-05-17 14:19:44 -0400803 if (GrRenderable::kYes == renderable) {
Greg Daniel900583a2019-08-06 12:05:31 -0400804 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400805 continue;
806 }
807 }
808
Robert Phillipsd34691b2019-09-24 13:38:43 -0400809 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400810 auto uninitCreateMtd = [format](GrContext* context,
811 GrMipMapped mipMapped,
812 GrRenderable renderable) {
813 return context->createBackendTexture(32, 32, format,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400814 mipMapped, renderable,
815 GrProtected::kNo);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400816 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400817
Robert Phillipsb04b6942019-05-21 17:24:31 -0400818 test_wrapping(context, reporter, uninitCreateMtd,
819 combo.fColorType, mipMapped, renderable);
820 }
Robert Phillips459b2952019-05-23 09:38:27 -0400821
822 {
Brian Salomon85c3d682019-11-04 15:04:54 -0500823 // We're creating backend textures without specifying a color type "view" of
824 // them at the public API level. Therefore, Ganesh will not apply any swizzles
825 // before writing the color to the texture. However, our validation code does
826 // rely on interpreting the texture contents via a SkColorType and therefore
827 // swizzles may be applied during the read step.
828 // Ideally we'd update our validation code to use a "raw" read that doesn't
829 // impose a color type but for now we just munge the data we upload to match the
830 // expectation.
831 GrSwizzle swizzle;
832 switch (combo.fColorType) {
833 case GrColorType::kAlpha_8:
834 swizzle = GrSwizzle("aaaa");
835 break;
836 case GrColorType::kAlpha_16:
837 swizzle = GrSwizzle("aaaa");
838 break;
839 case GrColorType::kAlpha_F16:
840 swizzle = GrSwizzle("aaaa");
841 break;
842 default:
843 break;
Robert Phillips459b2952019-05-23 09:38:27 -0400844 }
845
Brian Salomon85c3d682019-11-04 15:04:54 -0500846 auto createWithColorMtd = [format, swizzle](GrContext* context,
847 const SkColor4f& color,
848 GrMipMapped mipMapped,
849 GrRenderable renderable) {
850 auto swizzledColor = swizzle.applyTo(color);
851 return context->createBackendTexture(32, 32, format, swizzledColor,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400852 mipMapped, renderable,
853 GrProtected::kNo);
Robert Phillips459b2952019-05-23 09:38:27 -0400854 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500855 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
856 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
857 // the color passed to it. However, createBackendTexture() that takes a
858 // SkColor4f is color type/alpha type unaware and will simply compute luminance
859 //from the r, g, b, channels.
860 SkColor4f color = combo.fColor;
861 if (combo.fColorType == GrColorType::kGray_8) {
862 color = {color.fR * color.fA,
863 color.fG * color.fA,
864 color.fB * color.fA,
865 1.f};
866 }
Robert Phillips459b2952019-05-23 09:38:27 -0400867
Brian Salomon85c3d682019-11-04 15:04:54 -0500868 test_color_init(context, reporter, createWithColorMtd, combo.fColorType, color,
869 mipMapped, renderable);
Robert Phillips459b2952019-05-23 09:38:27 -0400870 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400871 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400872 }
873 }
874}
875
Robert Phillipsefb9f142019-05-17 14:19:44 -0400876#endif
877
878///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400879
880#ifdef SK_VULKAN
881
882#include "src/gpu/vk/GrVkCaps.h"
883
884DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
885 GrContext* context = ctxInfo.grContext();
886 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
887
Robert Phillips459b2952019-05-23 09:38:27 -0400888 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400889 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400890
Robert Phillips0c6daf02019-05-16 12:43:11 -0400891 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400892 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400893 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400894 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400895 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400896 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
897 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400898
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400899 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
900 // there is nothing to tell Skia to make the provided color opaque. Clients will need
901 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400902 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
903 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400904
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400905 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400906
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400907 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32, { 0.5f, 0, 0, 1.0f }},
908 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400909
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400910 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
911 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400912
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400913 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400914 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
915 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
916 // the alpha channel of the color). Clients should, in general, fill all the channels
917 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400918 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400919
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400920 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
921 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400922
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400923 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400924 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
925
Robert Phillips429f0d32019-09-11 17:03:28 -0400926 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400927 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400928 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
929 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400930 };
931
932 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400933 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400934 continue;
935 }
936
937 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
938
Robert Phillipsefb9f142019-05-17 14:19:44 -0400939 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
940 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
941 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400942 }
943
Robert Phillipsefb9f142019-05-17 14:19:44 -0400944 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400945
Robert Phillipsefb9f142019-05-17 14:19:44 -0400946 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400947 // We must also check whether we allow rendering to the format using the
948 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -0400949 if (!vkCaps->isFormatAsColorTypeRenderable(
950 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -0400951 continue;
952 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400953 }
954
Robert Phillipsd34691b2019-09-24 13:38:43 -0400955 {
Robert Phillipsb04b6942019-05-21 17:24:31 -0400956 auto uninitCreateMtd = [format](GrContext* context,
Robert Phillips459b2952019-05-23 09:38:27 -0400957 GrMipMapped mipMapped,
958 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400959 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
960 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400961 renderable,
962 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400963 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400964 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400965 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400966
Robert Phillipsb04b6942019-05-21 17:24:31 -0400967 test_wrapping(context, reporter, uninitCreateMtd,
968 combo.fColorType, mipMapped, renderable);
969 }
Robert Phillips459b2952019-05-23 09:38:27 -0400970
Robert Phillips459b2952019-05-23 09:38:27 -0400971 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400972 // We're creating backend textures without specifying a color type "view" of
973 // them at the public API level. Therefore, Ganesh will not apply any swizzles
974 // before writing the color to the texture. However, our validation code does
975 // rely on interpreting the texture contents via a SkColorType and therefore
976 // swizzles may be applied during the read step.
977 // Ideally we'd update our validation code to use a "raw" read that doesn't
978 // impose a color type but for now we just munge the data we upload to match the
979 // expectation.
980 GrSwizzle swizzle;
981 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400982 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400983 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
984 swizzle = GrSwizzle("aaaa");
985 break;
Robert Phillips429f0d32019-09-11 17:03:28 -0400986 case GrColorType::kAlpha_16:
987 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
988 swizzle = GrSwizzle("aaaa");
989 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -0400990 case GrColorType::kAlpha_F16:
991 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
992 swizzle = GrSwizzle("aaaa");
993 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400994 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -0400995 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
996 swizzle = GrSwizzle("bgra");
997 }
998 break;
999 default:
1000 swizzle = GrSwizzle("rgba");
1001 break;
1002 }
1003 auto createWithColorMtd = [format, swizzle](GrContext* context,
1004 const SkColor4f& color,
1005 GrMipMapped mipMapped,
1006 GrRenderable renderable) {
1007 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001008 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -04001009 swizzledColor,
1010 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -04001011 renderable,
1012 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -04001013 check_vk_layout(beTex, GrRenderable::kYes == renderable
1014 ? VkLayout::kColorAttachmentOptimal
1015 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001016 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -04001017 };
Robert Phillips459b2952019-05-23 09:38:27 -04001018 test_color_init(context, reporter, createWithColorMtd,
1019 combo.fColorType, combo.fColor, mipMapped, renderable);
1020 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001021 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001022 }
1023 }
1024}
1025
1026#endif