blob: 8dceeb91e745fc7342377e48b1b418ba226cbf06 [file] [log] [blame]
Robert Phillips0c6daf02019-05-16 12:43:11 -04001/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Robert Phillipse19babf2020-04-06 13:57:30 -04008#include "include/core/SkCanvas.h"
Mike Kleinfe0aeb32019-05-20 10:55:11 -05009#include "include/core/SkSurface.h"
Robert Phillips02dc0302019-07-02 17:58:27 -040010#include "include/core/SkSurfaceCharacterization.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050011#include "include/gpu/GrContext.h"
Robert Phillips459b2952019-05-23 09:38:27 -040012#include "src/core/SkAutoPixmapStorage.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050013#include "src/gpu/GrContextPriv.h"
Robert Phillipsefb9f142019-05-17 14:19:44 -040014#include "src/image/SkImage_Base.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040015#include "tests/Test.h"
Robert Phillipse3b6fe42019-09-11 11:26:46 -040016#include "tests/TestUtils.h"
17#include "tools/ToolUtils.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -040018
Robert Phillips27eb5252019-06-03 12:59:40 -040019#ifdef SK_GL
Robert Phillipsee946932019-12-18 11:16:17 -050020#include "src/gpu/gl/GrGLCaps.h"
21#include "src/gpu/gl/GrGLDefines.h"
Robert Phillips27eb5252019-06-03 12:59:40 -040022#include "src/gpu/gl/GrGLGpu.h"
23#include "src/gpu/gl/GrGLUtil.h"
24#endif
25
Robert Phillips7f367982019-09-26 14:01:36 -040026#ifdef SK_METAL
27#include "include/gpu/mtl/GrMtlTypes.h"
28#include "src/gpu/mtl/GrMtlCppUtil.h"
29#endif
30
Greg Danielb2365d82020-05-13 15:32:04 -040031static void wait_on_backend_work_to_finish(GrContext* context, bool* finishedCreate) {
Greg Danielc1ad77c2020-05-06 11:40:03 -040032 while (finishedCreate && !(*finishedCreate)) {
33 context->checkAsyncWorkCompletion();
34 }
35 if (finishedCreate) {
36 // The same boolean (pointed to by finishedCreate) is often used multiply and sequentially
37 // throughout our tests to create different backend textures.
38 // Reset it here so that it can be use to signal a future backend texture's creation
39 *finishedCreate = false;
40 }
Greg Danielb2365d82020-05-13 15:32:04 -040041}
42
43static void delete_backend_texture(GrContext* context, const GrBackendTexture& backendTexture,
44 bool* finishedCreate) {
45 wait_on_backend_work_to_finish(context, finishedCreate);
Greg Danielc1ad77c2020-05-06 11:40:03 -040046 context->deleteBackendTexture(backendTexture);
47}
48
Greg Danielb2365d82020-05-13 15:32:04 -040049static void mark_signaled(void* context) {
50 *(bool*)context = true;
51}
52
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -040053// Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
Robert Phillips0c6daf02019-05-16 12:43:11 -040054void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040055 std::function<GrBackendTexture (GrContext*,
56 GrMipMapped,
57 GrRenderable)> create,
Greg Danielc1ad77c2020-05-06 11:40:03 -040058 GrColorType grColorType, GrMipMapped mipMapped, GrRenderable renderable,
59 bool* finishedBECreate) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040060 GrResourceCache* cache = context->priv().getResourceCache();
61
62 const int initialCount = cache->getResourceCount();
63
Robert Phillipsefb9f142019-05-17 14:19:44 -040064 GrBackendTexture backendTex = create(context, mipMapped, renderable);
65 if (!backendTex.isValid()) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -040066 ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
67 grColorType,
Robert Phillips0c6daf02019-05-16 12:43:11 -040068 GrRenderable::kYes == renderable ? "yes" : "no");
69 return;
70 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040071
Robert Phillips0c6daf02019-05-16 12:43:11 -040072 // Skia proper should know nothing about the new backend object
73 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
74
Robert Phillipsb7f95d12019-07-26 11:13:19 -040075 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
76
77 // Wrapping a backendTexture in an image requires an SkColorType
78 if (kUnknown_SkColorType == skColorType) {
Greg Danielc1ad77c2020-05-06 11:40:03 -040079 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillipsb04b6942019-05-21 17:24:31 -040080 return;
81 }
82
Robert Phillipsd470e1b2019-09-04 15:05:35 -040083 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
Robert Phillipsb04b6942019-05-21 17:24:31 -040084 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040085 backendTex,
86 kTopLeft_GrSurfaceOrigin,
87 0,
Robert Phillipsb7f95d12019-07-26 11:13:19 -040088 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -040089 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040090 if (!surf) {
Robert Phillips9a30ee02020-04-29 08:58:39 -040091 ERRORF(reporter, "Couldn't make surface from backendTexture for %s\n",
92 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -040093 } else {
94 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040095 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040096 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040097
Robert Phillipsb04b6942019-05-21 17:24:31 -040098 {
99 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -0400100 backendTex,
101 kTopLeft_GrSurfaceOrigin,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400102 skColorType,
Robert Phillips459b2952019-05-23 09:38:27 -0400103 kPremul_SkAlphaType,
104 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400105 if (!img) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400106 ERRORF(reporter, "Couldn't make image from backendTexture for %s\n",
107 ToolUtils::colortype_name(skColorType));
Robert Phillipsb04b6942019-05-21 17:24:31 -0400108 } else {
109 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400110
Robert Phillipsb04b6942019-05-21 17:24:31 -0400111 GrTextureProxy* proxy = ib->peekProxy();
112 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -0400113
Robert Phillipsb04b6942019-05-21 17:24:31 -0400114 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
115 REPORTER_ASSERT(reporter, proxy->isInstantiated());
116 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -0400117
Robert Phillipsb04b6942019-05-21 17:24:31 -0400118 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400119 }
120 }
121
122 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
123
Greg Danielc1ad77c2020-05-06 11:40:03 -0400124 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400125}
126
Robert Phillips9a30ee02020-04-29 08:58:39 -0400127static bool isBGRA8(const GrBackendFormat& format) {
Robert Phillips7f367982019-09-26 14:01:36 -0400128 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400129 case GrBackendApi::kOpenGL:
130#ifdef SK_GL
131 return format.asGLFormat() == GrGLFormat::kBGRA8;
132#else
133 return false;
134#endif
135 case GrBackendApi::kVulkan: {
136#ifdef SK_VULKAN
137 VkFormat vkFormat;
138 format.asVkFormat(&vkFormat);
139 return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
140#else
141 return false;
142#endif
143 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500144 case GrBackendApi::kMetal:
145#ifdef SK_METAL
Robert Phillips9a30ee02020-04-29 08:58:39 -0400146 return GrMtlFormatIsBGRA8(format.asMtlFormat());
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500147#else
148 return false;
149#endif
150 case GrBackendApi::kDirect3D:
151#ifdef SK_DIRECT3D
152 return false; // TODO
153#else
154 return false;
155#endif
156 case GrBackendApi::kDawn:
Stephen White36248742020-06-10 22:24:57 -0400157#ifdef SK_DAWN
158 wgpu::TextureFormat dawnFormat;
159 format.asDawnFormat(&dawnFormat);
160 return dawnFormat == wgpu::TextureFormat::BGRA8Unorm;
161#else
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500162 return false;
Stephen White36248742020-06-10 22:24:57 -0400163#endif
Robert Phillipsa27d6252019-12-10 14:48:36 -0500164 case GrBackendApi::kMock: {
165 SkImage::CompressionType compression = format.asMockCompressionType();
166 if (compression != SkImage::CompressionType::kNone) {
167 return false; // No compressed formats are BGRA
168 }
169
Robert Phillips7f367982019-09-26 14:01:36 -0400170 return format.asMockColorType() == GrColorType::kBGRA_8888;
Robert Phillipsa27d6252019-12-10 14:48:36 -0500171 }
Robert Phillips7f367982019-09-26 14:01:36 -0400172 }
173 SkUNREACHABLE;
174}
175
176static bool isRGB(const GrBackendFormat& format) {
177 switch (format.backend()) {
Robert Phillips7f367982019-09-26 14:01:36 -0400178 case GrBackendApi::kOpenGL:
179#ifdef SK_GL
180 return format.asGLFormat() == GrGLFormat::kRGB8;
181#else
182 return false;
183#endif
184 case GrBackendApi::kVulkan: {
185#ifdef SK_VULKAN
186 VkFormat vkFormat;
187 format.asVkFormat(&vkFormat);
188 return vkFormat == VK_FORMAT_R8G8B8_UNORM;
189#else
190 return false;
191#endif
192 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500193 case GrBackendApi::kMetal:
194 return false; // Metal doesn't even pretend to support this
195 case GrBackendApi::kDirect3D:
196 return false; // Not supported in Direct3D 12
197 case GrBackendApi::kDawn:
198 return false;
Robert Phillips7f367982019-09-26 14:01:36 -0400199 case GrBackendApi::kMock:
200 return false; // No GrColorType::kRGB_888
201 }
202 SkUNREACHABLE;
203}
204
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400205static void check_solid_pixmap(skiatest::Reporter* reporter,
206 const SkColor4f& expected, const SkPixmap& actual,
Robert Phillips7f367982019-09-26 14:01:36 -0400207 SkColorType ct, const char* label1, const char* label2) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400208 // we need 0.001f across the board just for noise
209 // we need 0.01f across the board for 1010102
Robert Phillips7f367982019-09-26 14:01:36 -0400210 const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
Robert Phillips27eb5252019-06-03 12:59:40 -0400211
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400212 auto error = std::function<ComparePixmapsErrorReporter>(
Robert Phillips7f367982019-09-26 14:01:36 -0400213 [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400214 SkASSERT(x >= 0 && y >= 0);
Robert Phillips7f367982019-09-26 14:01:36 -0400215 ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)",
216 ToolUtils::colortype_name(ct), label1, label2, x, y,
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400217 diffs[0], diffs[1], diffs[2], diffs[3]);
218 });
219
Brian Salomon28a8f282019-10-24 20:07:39 -0400220 CheckSolidPixels(expected, actual, tols, error);
Robert Phillips27eb5252019-06-03 12:59:40 -0400221}
222
Robert Phillips7f367982019-09-26 14:01:36 -0400223// What would raster do?
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400224static SkColor4f get_expected_color(SkColor4f orig, SkColorType ct) {
Robert Phillips7f367982019-09-26 14:01:36 -0400225 SkAlphaType at = SkColorTypeIsAlwaysOpaque(ct) ? kOpaque_SkAlphaType
226 : kPremul_SkAlphaType;
Robert Phillipse3b6fe42019-09-11 11:26:46 -0400227
Robert Phillips7f367982019-09-26 14:01:36 -0400228 SkImageInfo ii = SkImageInfo::Make(2, 2, ct, at);
229 SkAutoPixmapStorage pm;
230 pm.alloc(ii);
231 pm.erase(orig);
232 SkColor tmp = pm.getColor(0, 0);
233 return SkColor4f::FromColor(tmp);
Robert Phillips459b2952019-05-23 09:38:27 -0400234}
235
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400236static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
237 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400238 skiatest::Reporter* reporter, const char* label);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400239
Robert Phillips0ee10342019-09-25 09:55:16 -0400240static void check_base_readbacks(GrContext* context, const GrBackendTexture& backendTex,
241 SkColorType skColorType, GrRenderable renderable,
Robert Phillips7f367982019-09-26 14:01:36 -0400242 const SkColor4f& color, skiatest::Reporter* reporter,
243 const char* label) {
244 if (isRGB(backendTex.getBackendFormat())) {
245 // readPixels is busted for the RGB backend format (skbug.com/8862)
246 // TODO: add a GrColorType::kRGB_888 to fix the situation
247 return;
248 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400249
250 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
251 : kPremul_SkAlphaType;
252
253 SkColor4f expectedColor = get_expected_color(color, skColorType);
254
255 SkAutoPixmapStorage actual;
256
257 {
258 SkImageInfo readBackII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400259 kUnpremul_SkAlphaType);
Robert Phillips0ee10342019-09-25 09:55:16 -0400260
261 SkAssertResult(actual.tryAlloc(readBackII));
262 }
263
Robert Phillips0ee10342019-09-25 09:55:16 -0400264 {
265 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
266 backendTex,
267 kTopLeft_GrSurfaceOrigin,
268 skColorType,
269 at,
270 nullptr);
271 if (img) {
272 actual.erase(SkColors::kTransparent);
273 bool result = img->readPixels(actual, 0, 0);
274 if (!result) {
275 // TODO: we need a better way to tell a priori if readPixels will work for an
276 // arbitrary colorType
277#if 0
278 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n", colorType);
279#endif
280 } else {
281 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400282 label, "SkImage::readPixels");
Robert Phillips0ee10342019-09-25 09:55:16 -0400283 }
284 }
285 }
Robert Phillips7f367982019-09-26 14:01:36 -0400286
287 // This will mark any mipmaps as dirty (bc that is what we do when we wrap a renderable
288 // backend texture) so it must be done last!
289 if (GrRenderable::kYes == renderable && context->colorTypeSupportedAsSurface(skColorType)) {
290 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
291 backendTex,
292 kTopLeft_GrSurfaceOrigin,
293 0,
294 skColorType,
295 nullptr, nullptr);
296 if (surf) {
297 actual.erase(SkColors::kTransparent);
298 bool result = surf->readPixels(actual, 0, 0);
299 REPORTER_ASSERT(reporter, result);
300
301 check_solid_pixmap(reporter, expectedColor, actual, skColorType,
302 label, "SkSurface::readPixels");
303 }
304 }
Robert Phillips0ee10342019-09-25 09:55:16 -0400305}
306
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400307// Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
Robert Phillips459b2952019-05-23 09:38:27 -0400308void test_color_init(GrContext* context, skiatest::Reporter* reporter,
309 std::function<GrBackendTexture (GrContext*,
310 const SkColor4f&,
311 GrMipMapped,
312 GrRenderable)> create,
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400313 GrColorType grColorType, const SkColor4f& color,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400314 GrMipMapped mipMapped, GrRenderable renderable, bool* finishedBECreate) {
Robert Phillips459b2952019-05-23 09:38:27 -0400315 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
316 if (!backendTex.isValid()) {
317 // errors here should be reported by the test_wrapping test
318 return;
319 }
320
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400321 SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
322
323 // Can't wrap backend textures in images and surfaces w/o an SkColorType
324 if (kUnknown_SkColorType == skColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400325 // TODO: burrow in and scrappily check that data was uploaded!
Greg Danielc1ad77c2020-05-06 11:40:03 -0400326 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips459b2952019-05-23 09:38:27 -0400327 return;
328 }
329
Greg Danielb2365d82020-05-13 15:32:04 -0400330 auto checkBackendTexture = [&](const SkColor4f& testColor) {
331 if (mipMapped == GrMipMapped::kYes) {
332 SkColor4f expectedColor = get_expected_color(testColor, skColorType);
333 SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
334 expectedColor, expectedColor, expectedColor};
335 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "colorinit");
336 }
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400337
Greg Danielb2365d82020-05-13 15:32:04 -0400338 // The last step in this test will dirty the mipmaps so do it last
339 check_base_readbacks(context, backendTex, skColorType, renderable, testColor, reporter,
340 "colorinit");
341 };
342
343 checkBackendTexture(color);
344
345 // Make sure the initial create work has finished so we can test the update independently.
346 wait_on_backend_work_to_finish(context, finishedBECreate);
347
348 SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
349
350 // Reupload the new data and make sure everything still works. We test with an SkColorType so
351 // we may actually swizzle the input during the create path. The update does not do any swizzle
352 // of the passed in color. So we manually do it here so we get the same expected results.
353 SkColor4f swizzledColor = context->priv().caps()->getWriteSwizzle(
354 backendTex.getBackendFormat(), grColorType).applyTo(newColor);
355 context->updateBackendTexture(backendTex, swizzledColor, mark_signaled, finishedBECreate);
356
357 checkBackendTexture(newColor);
358
Greg Danielc1ad77c2020-05-06 11:40:03 -0400359 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips459b2952019-05-23 09:38:27 -0400360}
361
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400362// Draw the backend texture (wrapped in an SkImage) into an RGBA surface, attempting to access
363// all the mipMap levels.
364static void check_mipmaps(GrContext* context, const GrBackendTexture& backendTex,
365 SkColorType skColorType, const SkColor4f expectedColors[6],
Robert Phillips7f367982019-09-26 14:01:36 -0400366 skiatest::Reporter* reporter, const char* label) {
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400367
368#ifdef SK_GL
369 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
370 if (GrBackendApi::kOpenGL == context->backend()) {
371 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
372
373 if (kRGBA_F32_SkColorType == skColorType &&
374 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
375 return;
376 }
377 }
378#endif
379
Robert Phillips7f367982019-09-26 14:01:36 -0400380 if (isRGB(backendTex.getBackendFormat())) {
381 // readPixels is busted for the RGB backend format (skbug.com/8862)
382 // TODO: add a GrColorType::kRGB_888 to fix the situation
383 return;
384 }
385
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400386 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
387 : kPremul_SkAlphaType;
Robert Phillips7f367982019-09-26 14:01:36 -0400388
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400389 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
390 backendTex,
391 kTopLeft_GrSurfaceOrigin,
392 skColorType,
393 at,
394 nullptr);
395 if (!img) {
396 return;
397 }
398
Robert Phillips7f367982019-09-26 14:01:36 -0400399 SkImageInfo readbackSurfaceII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
400 kPremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400401
402 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
403 SkBudgeted::kNo,
Robert Phillips7f367982019-09-26 14:01:36 -0400404 readbackSurfaceII, 1,
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400405 kTopLeft_GrSurfaceOrigin,
406 nullptr);
407 if (!surf) {
408 return;
409 }
410
411 SkCanvas* canvas = surf->getCanvas();
412
413 SkPaint p;
414 p.setFilterQuality(kHigh_SkFilterQuality);
415
416 int numMipLevels = 6;
417
418 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
419 SkASSERT(rectSize >= 1);
420
421 SkRect r = SkRect::MakeWH(rectSize, rectSize);
422 canvas->clear(SK_ColorTRANSPARENT);
423 canvas->drawImageRect(img, r, &p);
424
425 SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
426 kRGBA_8888_SkColorType,
Robert Phillips7f367982019-09-26 14:01:36 -0400427 kUnpremul_SkAlphaType);
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400428 SkAutoPixmapStorage actual2;
429 SkAssertResult(actual2.tryAlloc(readbackII));
430 actual2.erase(SkColors::kTransparent);
431
432 bool result = surf->readPixels(actual2, 0, 0);
433 REPORTER_ASSERT(reporter, result);
434
Robert Phillipsee946932019-12-18 11:16:17 -0500435 SkString str;
436 str.appendf("mip-level %d", i);
437
Robert Phillips7f367982019-09-26 14:01:36 -0400438 check_solid_pixmap(reporter, expectedColors[i], actual2, skColorType,
Robert Phillipsee946932019-12-18 11:16:17 -0500439 label, str.c_str());
Robert Phillipsc1dbb4b2019-09-24 16:32:35 -0400440 }
441}
442
Robert Phillips7f367982019-09-26 14:01:36 -0400443static int make_pixmaps(SkColorType skColorType, GrMipMapped mipMapped,
444 const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
445 int levelSize = 32;
446 int numMipLevels = mipMapped == GrMipMapped::kYes ? 6 : 1;
447 SkAlphaType at = SkColorTypeIsAlwaysOpaque(skColorType) ? kOpaque_SkAlphaType
448 : kPremul_SkAlphaType;
449 for (int level = 0; level < numMipLevels; ++level) {
450 SkImageInfo ii = SkImageInfo::Make(levelSize, levelSize, skColorType, at);
451 pixmaps[level].alloc(ii);
452 pixmaps[level].erase(colors[level]);
453 levelSize /= 2;
454 }
455 return numMipLevels;
456}
457
458// Test initialization of GrBackendObjects using SkPixmaps
459static void test_pixmap_init(GrContext* context, skiatest::Reporter* reporter,
460 std::function<GrBackendTexture (GrContext*,
461 const SkPixmap srcData[],
462 int numLevels,
463 GrRenderable)> create,
464 SkColorType skColorType, GrMipMapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400465 GrRenderable renderable, bool* finishedBECreate) {
Robert Phillips7f367982019-09-26 14:01:36 -0400466 SkAutoPixmapStorage pixmapMem[6];
467 SkColor4f colors[6] = {
468 { 1.0f, 0.0f, 0.0f, 1.0f }, // R
469 { 0.0f, 1.0f, 0.0f, 0.9f }, // G
470 { 0.0f, 0.0f, 1.0f, 0.7f }, // B
471 { 0.0f, 1.0f, 1.0f, 0.5f }, // C
472 { 1.0f, 0.0f, 1.0f, 0.3f }, // M
473 { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
474 };
475
476 int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
477 SkASSERT(numMipLevels);
478
479 // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
480 SkPixmap pixmaps[6];
481 for (int i = 0; i < numMipLevels; ++i) {
482 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
483 }
484
485 GrBackendTexture backendTex = create(context, pixmaps, numMipLevels, renderable);
486 if (!backendTex.isValid()) {
487 // errors here should be reported by the test_wrapping test
488 return;
489 }
490
Robert Phillips9a30ee02020-04-29 08:58:39 -0400491 if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(backendTex.getBackendFormat())) {
Robert Phillips7f367982019-09-26 14:01:36 -0400492 // When kBGRA is backed by an RGBA something goes wrong in the swizzling
Greg Danielc1ad77c2020-05-06 11:40:03 -0400493 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips7f367982019-09-26 14:01:36 -0400494 return;
495 }
496
Greg Danielb2365d82020-05-13 15:32:04 -0400497 auto checkBackendTexture = [&](SkColor4f colors[6]) {
498 if (mipMapped == GrMipMapped::kYes) {
499 SkColor4f expectedColors[6] = {
500 get_expected_color(colors[0], skColorType),
501 get_expected_color(colors[1], skColorType),
502 get_expected_color(colors[2], skColorType),
503 get_expected_color(colors[3], skColorType),
504 get_expected_color(colors[4], skColorType),
505 get_expected_color(colors[5], skColorType),
506 };
Robert Phillips7f367982019-09-26 14:01:36 -0400507
Greg Danielb2365d82020-05-13 15:32:04 -0400508 check_mipmaps(context, backendTex, skColorType, expectedColors, reporter, "pixmap");
509 }
510
511 // The last step in this test will dirty the mipmaps so do it last
512 check_base_readbacks(context, backendTex, skColorType, renderable, colors[0], reporter,
513 "pixmap");
514 };
515
516 checkBackendTexture(colors);
517
518 // Make sure the initial create work has finished so we can test the update independently.
519 wait_on_backend_work_to_finish(context, finishedBECreate);
520
521 SkColor4f colorsNew[6] = {
522 {1.0f, 1.0f, 0.0f, 0.2f}, // Y
523 {1.0f, 0.0f, 0.0f, 1.0f}, // R
524 {0.0f, 1.0f, 0.0f, 0.9f}, // G
525 {0.0f, 0.0f, 1.0f, 0.7f}, // B
526 {0.0f, 1.0f, 1.0f, 0.5f}, // C
527 {1.0f, 0.0f, 1.0f, 0.3f}, // M
528 };
529 make_pixmaps(skColorType, mipMapped, colorsNew, pixmapMem);
530 for (int i = 0; i < numMipLevels; ++i) {
531 pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
Robert Phillips7f367982019-09-26 14:01:36 -0400532 }
533
Greg Danielb2365d82020-05-13 15:32:04 -0400534 // Upload new data and make sure everything still works
535 context->updateBackendTexture(backendTex, pixmaps, numMipLevels, mark_signaled,
536 finishedBECreate);
537
538 checkBackendTexture(colorsNew);
539
Greg Danielc1ad77c2020-05-06 11:40:03 -0400540 delete_backend_texture(context, backendTex, finishedBECreate);
Robert Phillips7f367982019-09-26 14:01:36 -0400541}
542
Robert Phillips02dc0302019-07-02 17:58:27 -0400543enum class VkLayout {
544 kUndefined,
545 kReadOnlyOptimal,
Robert Phillips02dc0302019-07-02 17:58:27 -0400546};
547
548void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
549#if defined(SK_VULKAN) && defined(SK_DEBUG)
550 VkImageLayout expected;
551
552 switch (layout) {
553 case VkLayout::kUndefined:
554 expected = VK_IMAGE_LAYOUT_UNDEFINED;
555 break;
556 case VkLayout::kReadOnlyOptimal:
557 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
558 break;
Robert Phillips02dc0302019-07-02 17:58:27 -0400559 default:
560 SkUNREACHABLE;
561 }
562
563 GrVkImageInfo vkII;
564
565 if (backendTex.getVkImageInfo(&vkII)) {
566 SkASSERT(expected == vkII.fImageLayout);
567 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
568 }
569#endif
570}
571
572///////////////////////////////////////////////////////////////////////////////
573// This test is a bit different from the others in this file. It is mainly checking that, for any
574// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
575// its characterization and then create a new surface that wraps that backend texture.
576DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
577 GrContext* context = ctxInfo.grContext();
578
579 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
580 SkColorType colorType = static_cast<SkColorType>(ct);
581
582 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
583
584 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
585 for (bool mipMaps : { true, false } ) {
586 for (int sampleCount : {1, 2}) {
587 SkSurfaceCharacterization c;
588
589 // Get a characterization, if possible
590 {
591 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
592 ii, sampleCount,
593 origin, nullptr, mipMaps);
594 if (!s) {
595 continue;
596 }
597
598 if (!s->characterize(&c)) {
599 continue;
600 }
601
602 REPORTER_ASSERT(reporter, s->isCompatible(c));
603 }
604
605 // Test out uninitialized path
606 {
607 GrBackendTexture backendTex = context->createBackendTexture(c);
608 check_vk_layout(backendTex, VkLayout::kUndefined);
609 REPORTER_ASSERT(reporter, backendTex.isValid());
610 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
611
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400612 {
613 GrBackendFormat format = context->defaultBackendFormat(
614 c.imageInfo().colorType(),
615 GrRenderable::kYes);
616 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
617 }
618
Robert Phillips02dc0302019-07-02 17:58:27 -0400619 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
620 backendTex);
621 REPORTER_ASSERT(reporter, s2);
622 REPORTER_ASSERT(reporter, s2->isCompatible(c));
623
624 s2 = nullptr;
625 context->deleteBackendTexture(backendTex);
626 }
627
628 // Test out color-initialized path
Greg Danielc1ad77c2020-05-06 11:40:03 -0400629
Robert Phillips02dc0302019-07-02 17:58:27 -0400630 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400631
632 bool finished = false;
Robert Phillips02dc0302019-07-02 17:58:27 -0400633 GrBackendTexture backendTex = context->createBackendTexture(c,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400634 SkColors::kRed,
635 mark_signaled,
636 &finished);
Greg Danieldddf7092020-05-06 11:52:37 -0400637 check_vk_layout(backendTex, VkLayout::kReadOnlyOptimal);
Robert Phillips02dc0302019-07-02 17:58:27 -0400638 REPORTER_ASSERT(reporter, backendTex.isValid());
639 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
640
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400641 {
642 GrBackendFormat format = context->defaultBackendFormat(
643 c.imageInfo().colorType(),
644 GrRenderable::kYes);
645 REPORTER_ASSERT(reporter, format == backendTex.getBackendFormat());
646 }
647
Robert Phillips02dc0302019-07-02 17:58:27 -0400648 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
649 backendTex);
650 REPORTER_ASSERT(reporter, s2);
651 REPORTER_ASSERT(reporter, s2->isCompatible(c));
652
653 s2 = nullptr;
Greg Danielc1ad77c2020-05-06 11:40:03 -0400654 delete_backend_texture(context, backendTex, &finished);
Robert Phillips02dc0302019-07-02 17:58:27 -0400655 }
656 }
657 }
658 }
659 }
660}
661
Robert Phillipsefb9f142019-05-17 14:19:44 -0400662///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400663DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
664 GrContext* context = ctxInfo.grContext();
665 const GrCaps* caps = context->priv().caps();
666
Robert Phillips459b2952019-05-23 09:38:27 -0400667 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400668 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400669
Robert Phillips0c6daf02019-05-16 12:43:11 -0400670 struct {
671 SkColorType fColorType;
Robert Phillips459b2952019-05-23 09:38:27 -0400672 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400673 } combinations[] = {
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400674 { kAlpha_8_SkColorType, kTransCol },
675 { kRGB_565_SkColorType, SkColors::kRed },
676 { kARGB_4444_SkColorType, SkColors::kGreen },
677 { kRGBA_8888_SkColorType, SkColors::kBlue },
678 { kRGB_888x_SkColorType, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400679 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400680 { kBGRA_8888_SkColorType, { 1, 0, 0, 1.0f } },
Robert Phillips9a30ee02020-04-29 08:58:39 -0400681 // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
682 { kRGBA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
683 { kBGRA_1010102_SkColorType, { 0.25f, 0.5f, 0.75f, 1.0f }},
684 // RGB/BGR 101010x have no Ganesh correlate
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400685 { kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Mike Kleinf7eb0542020-02-11 12:19:08 -0600686 { kBGR_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400687 { kGray_8_SkColorType, kGrayCol },
688 { kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
689 { kRGBA_F16_SkColorType, SkColors::kYellow },
690 { kRGBA_F32_SkColorType, SkColors::kGray },
Robert Phillips7f367982019-09-26 14:01:36 -0400691 { kR8G8_unorm_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400692 { kR16G16_unorm_SkColorType, SkColors::kGreen },
693 { kA16_unorm_SkColorType, kTransCol },
694 { kA16_float_SkColorType, kTransCol },
Robert Phillips7f367982019-09-26 14:01:36 -0400695 { kR16G16_float_SkColorType, { .25f, .75f, 0, 1 } },
Robert Phillipsea1b30b2019-09-19 16:05:48 -0400696 { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 } },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400697 };
698
Brian Salomon4dea72a2019-12-18 10:43:10 -0500699 static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
Robert Phillips0c6daf02019-05-16 12:43:11 -0400700
701 for (auto combo : combinations) {
702 SkColorType colorType = combo.fColorType;
703
Robert Phillips0c6daf02019-05-16 12:43:11 -0400704 if (GrBackendApi::kMetal == context->backend()) {
705 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
706 if (kRGBA_F32_SkColorType == combo.fColorType) {
707 continue;
708 }
709 }
710
Robert Phillipsefb9f142019-05-17 14:19:44 -0400711 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
712 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
713 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400714 }
715
Robert Phillipsefb9f142019-05-17 14:19:44 -0400716 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400717 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
718 renderable).isValid()) {
719 continue;
720 }
Robert Phillips7f367982019-09-26 14:01:36 -0400721
Robert Phillipsefb9f142019-05-17 14:19:44 -0400722 if (GrRenderable::kYes == renderable) {
723 if (kRGB_888x_SkColorType == combo.fColorType) {
724 // Ganesh can't perform the blends correctly when rendering this format
725 continue;
726 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400727 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400728
Robert Phillipsb04b6942019-05-21 17:24:31 -0400729 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400730 auto uninitCreateMtd = [colorType](GrContext* context, GrMipMapped mipMapped,
Robert Phillipsb04b6942019-05-21 17:24:31 -0400731 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400732 auto result = context->createBackendTexture(32, 32, colorType,
733 mipMapped, renderable,
734 GrProtected::kNo);
735 check_vk_layout(result, VkLayout::kUndefined);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400736
737#ifdef SK_DEBUG
738 {
739 GrBackendFormat format = context->defaultBackendFormat(colorType,
740 renderable);
741 SkASSERT(format == result.getBackendFormat());
742 }
743#endif
744
Robert Phillips02dc0302019-07-02 17:58:27 -0400745 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400746 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400747
Robert Phillipsb04b6942019-05-21 17:24:31 -0400748 test_wrapping(context, reporter, uninitCreateMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400749 SkColorTypeToGrColorType(colorType), mipMapped, renderable,
750 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400751 }
Robert Phillips459b2952019-05-23 09:38:27 -0400752
Greg Danielc1ad77c2020-05-06 11:40:03 -0400753 bool finishedBackendCreation = false;
754 bool* finishedPtr = &finishedBackendCreation;
755
Robert Phillips459b2952019-05-23 09:38:27 -0400756 {
Robert Phillips459b2952019-05-23 09:38:27 -0400757
Greg Danielc1ad77c2020-05-06 11:40:03 -0400758 auto createWithColorMtd = [colorType, finishedPtr](GrContext* context,
759 const SkColor4f& color,
760 GrMipMapped mipMapped,
761 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400762 auto result = context->createBackendTexture(32, 32, colorType, color,
763 mipMapped, renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400764 GrProtected::kNo,
765 mark_signaled,
766 finishedPtr);
Greg Danieldddf7092020-05-06 11:52:37 -0400767 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400768
769#ifdef SK_DEBUG
770 {
771 GrBackendFormat format = context->defaultBackendFormat(colorType,
772 renderable);
773 SkASSERT(format == result.getBackendFormat());
774 }
775#endif
776
Robert Phillips02dc0302019-07-02 17:58:27 -0400777 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400778 };
Brian Salomon85c3d682019-11-04 15:04:54 -0500779 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
780 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
781 // the color passed to it. However, createBackendTexture() that takes a
782 // SkColor4f is color type / alpha type unaware and will simply compute
783 // luminance from the r, g, b, channels.
784 SkColor4f color = combo.fColor;
785 if (colorType == kGray_8_SkColorType) {
786 color = {color.fR * color.fA,
787 color.fG * color.fA,
788 color.fB * color.fA,
789 1.f};
790 }
Robert Phillips459b2952019-05-23 09:38:27 -0400791 test_color_init(context, reporter, createWithColorMtd,
Brian Salomon85c3d682019-11-04 15:04:54 -0500792 SkColorTypeToGrColorType(colorType), color, mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400793 renderable, finishedPtr);
Robert Phillips459b2952019-05-23 09:38:27 -0400794 }
Robert Phillips7f367982019-09-26 14:01:36 -0400795
Robert Phillips9a30ee02020-04-29 08:58:39 -0400796 {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400797 auto createWithSrcDataMtd = [finishedPtr](GrContext* context,
798 const SkPixmap srcData[],
799 int numLevels,
800 GrRenderable renderable) {
Robert Phillips9a30ee02020-04-29 08:58:39 -0400801 SkASSERT(srcData && numLevels);
802 auto result = context->createBackendTexture(srcData, numLevels, renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400803 GrProtected::kNo, mark_signaled,
804 finishedPtr);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400805 check_vk_layout(result, VkLayout::kReadOnlyOptimal);
Robert Phillips7f367982019-09-26 14:01:36 -0400806#ifdef SK_DEBUG
Robert Phillips9a30ee02020-04-29 08:58:39 -0400807 {
808 auto format = context->defaultBackendFormat(srcData[0].colorType(),
809 renderable);
810 SkASSERT(format == result.getBackendFormat());
811 }
Robert Phillips7f367982019-09-26 14:01:36 -0400812#endif
Robert Phillips9a30ee02020-04-29 08:58:39 -0400813 return result;
814 };
Robert Phillips7f367982019-09-26 14:01:36 -0400815
Robert Phillips9a30ee02020-04-29 08:58:39 -0400816 test_pixmap_init(context, reporter, createWithSrcDataMtd, colorType, mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400817 renderable, finishedPtr);
Robert Phillips9a30ee02020-04-29 08:58:39 -0400818 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400819 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400820 }
821 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400822}
823
Robert Phillipsefb9f142019-05-17 14:19:44 -0400824///////////////////////////////////////////////////////////////////////////////
825#ifdef SK_GL
826
Robert Phillips0c6daf02019-05-16 12:43:11 -0400827DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
828 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
829 GrGLStandard standard = glCtx->gl()->fStandard;
830 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400831 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400832
Robert Phillips459b2952019-05-23 09:38:27 -0400833 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400834 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400835
Robert Phillips0c6daf02019-05-16 12:43:11 -0400836 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400837 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400838 GrGLenum fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400839 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400840 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400841 { GrColorType::kRGBA_8888, GR_GL_RGBA8, SkColors::kRed },
842 { GrColorType::kRGBA_8888_SRGB, GR_GL_SRGB8_ALPHA8, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400843
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400844 { GrColorType::kRGB_888x, GR_GL_RGBA8, SkColors::kYellow },
845 { GrColorType::kRGB_888x, GR_GL_RGB8, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400846
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400847 { GrColorType::kBGRA_8888, GR_GL_RGBA8, SkColors::kBlue },
848 { GrColorType::kBGRA_8888, GR_GL_BGRA8, SkColors::kBlue },
849 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
Robert Phillips9a30ee02020-04-29 08:58:39 -0400850 { GrColorType::kRGBA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
851 { GrColorType::kBGRA_1010102, GR_GL_RGB10_A2, { 0.25f, 0.5f, 0.75f, 1.f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400852 { GrColorType::kBGR_565, GR_GL_RGB565, SkColors::kRed },
853 { GrColorType::kABGR_4444, GR_GL_RGBA4, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400854
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400855 { GrColorType::kAlpha_8, GR_GL_ALPHA8, kTransCol },
856 { GrColorType::kAlpha_8, GR_GL_R8, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400857
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400858 { GrColorType::kGray_8, GR_GL_LUMINANCE8, kGrayCol },
859 { GrColorType::kGray_8, GR_GL_R8, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400860
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400861 { GrColorType::kRGBA_F32, GR_GL_RGBA32F, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400862
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400863 { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F, SkColors::kLtGray },
864 { GrColorType::kRGBA_F16, GR_GL_RGBA16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400865
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400866 { GrColorType::kRG_88, GR_GL_RG8, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400867 { GrColorType::kAlpha_F16, GR_GL_R16F, { 1.0f, 0, 0, 0.5f } },
868 { GrColorType::kAlpha_F16, GR_GL_LUMINANCE16F, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400869
Robert Phillips429f0d32019-09-11 17:03:28 -0400870 { GrColorType::kAlpha_16, GR_GL_R16, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400871 { GrColorType::kRG_1616, GR_GL_RG16, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400872
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400873 { GrColorType::kRGBA_16161616, GR_GL_RGBA16, SkColors::kLtGray },
874 { GrColorType::kRG_F16, GR_GL_RG16F, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400875 };
876
877 for (auto combo : combinations) {
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000878 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
Robert Phillips0c6daf02019-05-16 12:43:11 -0400879
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000880 if (!glCaps->isFormatTexturable(format)) {
881 continue;
882 }
883
884 if (GrColorType::kBGRA_8888 == combo.fColorType ||
885 GrColorType::kBGRA_1010102 == combo.fColorType) {
886 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not ES
887 if (kGL_GrGLStandard != standard &&
888 (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
889 continue;
890 }
891 }
892
893 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
894 if (GrMipMapped::kYes == mipMapped && !glCaps->mipMapSupport()) {
Robert Phillipsefb9f142019-05-17 14:19:44 -0400895 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400896 }
897
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000898 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400899
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000900 if (GrRenderable::kYes == renderable) {
901 if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
902 continue;
903 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400904 }
905
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000906 {
907 auto uninitCreateMtd = [format](GrContext* context, GrMipMapped mipMapped,
908 GrRenderable renderable) {
909 return context->createBackendTexture(32, 32, format,
910 mipMapped, renderable,
911 GrProtected::kNo);
912 };
913
914 test_wrapping(context, reporter, uninitCreateMtd,
915 combo.fColorType, mipMapped, renderable, nullptr);
916 }
917
918 {
919 // We're creating backend textures without specifying a color type "view" of
920 // them at the public API level. Therefore, Ganesh will not apply any swizzles
921 // before writing the color to the texture. However, our validation code does
922 // rely on interpreting the texture contents via a SkColorType and therefore
923 // swizzles may be applied during the read step.
924 // Ideally we'd update our validation code to use a "raw" read that doesn't
925 // impose a color type but for now we just munge the data we upload to match the
926 // expectation.
927 GrSwizzle swizzle;
928 switch (combo.fColorType) {
929 case GrColorType::kAlpha_8:
930 swizzle = GrSwizzle("aaaa");
931 break;
932 case GrColorType::kAlpha_16:
933 swizzle = GrSwizzle("aaaa");
934 break;
935 case GrColorType::kAlpha_F16:
936 swizzle = GrSwizzle("aaaa");
937 break;
938 default:
939 break;
Robert Phillips459b2952019-05-23 09:38:27 -0400940 }
941
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000942 bool finishedBackendCreation = false;
943 bool* finishedPtr = &finishedBackendCreation;
Greg Danielc1ad77c2020-05-06 11:40:03 -0400944
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000945 auto createWithColorMtd = [format, swizzle, finishedPtr](
946 GrContext* context, const SkColor4f& color, GrMipMapped mipMapped,
947 GrRenderable renderable) {
948 auto swizzledColor = swizzle.applyTo(color);
949 return context->createBackendTexture(32, 32, format, swizzledColor,
950 mipMapped, renderable,
951 GrProtected::kNo, mark_signaled,
952 finishedPtr);
953 };
954 // We make our comparison color using SkPixmap::erase(color) on a pixmap of
955 // combo.fColorType and then calling SkPixmap::readPixels(). erase() will premul
956 // the color passed to it. However, createBackendTexture() that takes a
957 // SkColor4f is color type/alpha type unaware and will simply compute luminance
958 //from the r, g, b, channels.
959 SkColor4f color = combo.fColor;
960 if (combo.fColorType == GrColorType::kGray_8) {
961 color = {color.fR * color.fA,
962 color.fG * color.fA,
963 color.fB * color.fA,
964 1.f};
Brian Salomon85c3d682019-11-04 15:04:54 -0500965 }
Robert Phillips459b2952019-05-23 09:38:27 -0400966
Derek Sollenberger96f8db02020-06-19 19:11:27 +0000967 test_color_init(context, reporter, createWithColorMtd, combo.fColorType, color,
968 mipMapped, renderable, finishedPtr);
Robert Phillips459b2952019-05-23 09:38:27 -0400969 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400970 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400971 }
972 }
973}
974
Robert Phillipsefb9f142019-05-17 14:19:44 -0400975#endif
976
977///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400978
979#ifdef SK_VULKAN
980
981#include "src/gpu/vk/GrVkCaps.h"
982
983DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
984 GrContext* context = ctxInfo.grContext();
985 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
986
Robert Phillips459b2952019-05-23 09:38:27 -0400987 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillips7f367982019-09-26 14:01:36 -0400988 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
Robert Phillips459b2952019-05-23 09:38:27 -0400989
Robert Phillips0c6daf02019-05-16 12:43:11 -0400990 struct {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400991 GrColorType fColorType;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400992 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400993 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400994 } combinations[] = {
Robert Phillipsb7f95d12019-07-26 11:13:19 -0400995 { GrColorType::kRGBA_8888, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
996 { GrColorType::kRGBA_8888_SRGB, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400997
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400998 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
999 // there is nothing to tell Skia to make the provided color opaque. Clients will need
1000 // to provide an opaque initialization color in this case.
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001001 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
1002 { GrColorType::kRGB_888x, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001003
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001004 { GrColorType::kBGRA_8888, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001005
Robert Phillips9a30ee02020-04-29 08:58:39 -04001006 { GrColorType::kRGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1007 { 0.25f, 0.5f, 0.75f, 1.0f }},
1008 { GrColorType::kBGRA_1010102, VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1009 { 0.25f, 0.5f, 0.75f, 1.0f }},
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001010 { GrColorType::kBGR_565, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -04001011
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001012 { GrColorType::kABGR_4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
1013 { GrColorType::kABGR_4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -04001014
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001015 { GrColorType::kAlpha_8, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -04001016 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
1017 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
1018 // the alpha channel of the color). Clients should, in general, fill all the channels
1019 // of the provided color with the same value in such cases.
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001020 { GrColorType::kGray_8, VK_FORMAT_R8_UNORM, kGrayCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -04001021
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001022 { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
1023 { GrColorType::kRGBA_F16, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001024
Robert Phillipsd470e1b2019-09-04 15:05:35 -04001025 { GrColorType::kRG_88, VK_FORMAT_R8G8_UNORM, { 1, 0.5f, 0, 1 } },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001026 { GrColorType::kAlpha_F16, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f }},
1027
Robert Phillips429f0d32019-09-11 17:03:28 -04001028 { GrColorType::kAlpha_16, VK_FORMAT_R16_UNORM, kTransCol },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001029 { GrColorType::kRG_1616, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001030 { GrColorType::kRGBA_16161616, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
1031 { GrColorType::kRG_F16, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -04001032 };
1033
1034 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -04001035 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -04001036 continue;
1037 }
1038
1039 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
1040
Robert Phillipsefb9f142019-05-17 14:19:44 -04001041 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
1042 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
1043 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -04001044 }
1045
Robert Phillipsefb9f142019-05-17 14:19:44 -04001046 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -04001047
Robert Phillipsefb9f142019-05-17 14:19:44 -04001048 if (GrRenderable::kYes == renderable) {
Brian Salomon4eb38b72019-08-05 12:58:39 -04001049 // We must also check whether we allow rendering to the format using the
1050 // color type.
Greg Daniel900583a2019-08-06 12:05:31 -04001051 if (!vkCaps->isFormatAsColorTypeRenderable(
1052 combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -04001053 continue;
1054 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001055 }
1056
Robert Phillipsd34691b2019-09-24 13:38:43 -04001057 {
Greg Danielc1ad77c2020-05-06 11:40:03 -04001058 auto uninitCreateMtd = [format](GrContext* context, GrMipMapped mipMapped,
Robert Phillips459b2952019-05-23 09:38:27 -04001059 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001060 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
1061 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -04001062 renderable,
1063 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -04001064 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001065 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -04001066 };
Robert Phillipsefb9f142019-05-17 14:19:44 -04001067
Robert Phillipsb04b6942019-05-21 17:24:31 -04001068 test_wrapping(context, reporter, uninitCreateMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001069 combo.fColorType, mipMapped, renderable, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -04001070 }
Robert Phillips459b2952019-05-23 09:38:27 -04001071
Robert Phillips459b2952019-05-23 09:38:27 -04001072 {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001073 // We're creating backend textures without specifying a color type "view" of
1074 // them at the public API level. Therefore, Ganesh will not apply any swizzles
1075 // before writing the color to the texture. However, our validation code does
1076 // rely on interpreting the texture contents via a SkColorType and therefore
1077 // swizzles may be applied during the read step.
1078 // Ideally we'd update our validation code to use a "raw" read that doesn't
1079 // impose a color type but for now we just munge the data we upload to match the
1080 // expectation.
1081 GrSwizzle swizzle;
1082 switch (combo.fColorType) {
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001083 case GrColorType::kAlpha_8:
Brian Salomonb450f3b2019-07-09 09:36:51 -04001084 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
1085 swizzle = GrSwizzle("aaaa");
1086 break;
Robert Phillips429f0d32019-09-11 17:03:28 -04001087 case GrColorType::kAlpha_16:
1088 SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
1089 swizzle = GrSwizzle("aaaa");
1090 break;
Robert Phillips17a3a0b2019-09-18 13:56:54 -04001091 case GrColorType::kAlpha_F16:
1092 SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
1093 swizzle = GrSwizzle("aaaa");
1094 break;
Robert Phillipsb7f95d12019-07-26 11:13:19 -04001095 case GrColorType::kABGR_4444:
Brian Salomonb450f3b2019-07-09 09:36:51 -04001096 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
1097 swizzle = GrSwizzle("bgra");
1098 }
1099 break;
1100 default:
1101 swizzle = GrSwizzle("rgba");
1102 break;
1103 }
Greg Danielc1ad77c2020-05-06 11:40:03 -04001104
1105 bool finishedBackendCreation = false;
1106 bool* finishedPtr = &finishedBackendCreation;
1107
1108 auto createWithColorMtd = [format, swizzle, finishedPtr](
1109 GrContext* context, const SkColor4f& color, GrMipMapped mipMapped,
1110 GrRenderable renderable) {
Brian Salomonb450f3b2019-07-09 09:36:51 -04001111 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001112 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -04001113 swizzledColor,
1114 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -04001115 renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001116 GrProtected::kNo,
1117 mark_signaled,
1118 finishedPtr);
Greg Danieldddf7092020-05-06 11:52:37 -04001119 check_vk_layout(beTex, VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -04001120 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -04001121 };
Robert Phillips459b2952019-05-23 09:38:27 -04001122 test_color_init(context, reporter, createWithColorMtd,
Greg Danielc1ad77c2020-05-06 11:40:03 -04001123 combo.fColorType, combo.fColor, mipMapped, renderable,
1124 finishedPtr);
Robert Phillips459b2952019-05-23 09:38:27 -04001125 }
Robert Phillipsefb9f142019-05-17 14:19:44 -04001126 }
Robert Phillips0c6daf02019-05-16 12:43:11 -04001127 }
1128 }
1129}
1130
1131#endif