blob: b4a2baae175d25c1336132587bce936832c2721d [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"
15
Robert Phillips27eb5252019-06-03 12:59:40 -040016#ifdef SK_GL
17#include "src/gpu/gl/GrGLGpu.h"
18#include "src/gpu/gl/GrGLUtil.h"
19#endif
20
Robert Phillips0c6daf02019-05-16 12:43:11 -040021// Test wrapping of GrBackendObjects in SkSurfaces and SkImages
22void test_wrapping(GrContext* context, skiatest::Reporter* reporter,
Robert Phillipsb04b6942019-05-21 17:24:31 -040023 std::function<GrBackendTexture (GrContext*,
24 GrMipMapped,
25 GrRenderable)> create,
Robert Phillipsefb9f142019-05-17 14:19:44 -040026 SkColorType colorType, GrMipMapped mipMapped, GrRenderable renderable) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040027 GrResourceCache* cache = context->priv().getResourceCache();
28
29 const int initialCount = cache->getResourceCount();
30
Robert Phillipsefb9f142019-05-17 14:19:44 -040031 GrBackendTexture backendTex = create(context, mipMapped, renderable);
32 if (!backendTex.isValid()) {
Robert Phillips0c6daf02019-05-16 12:43:11 -040033 ERRORF(reporter, "Couldn't create backendTexture for colorType %d renderable %s\n",
34 colorType,
35 GrRenderable::kYes == renderable ? "yes" : "no");
36 return;
37 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040038
Robert Phillips0c6daf02019-05-16 12:43:11 -040039 // Skia proper should know nothing about the new backend object
40 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
41
Robert Phillipsb04b6942019-05-21 17:24:31 -040042 if (kUnknown_SkColorType == colorType) {
43 context->deleteBackendTexture(backendTex);
44 return;
45 }
46
47 if (GrRenderable::kYes == renderable) {
48 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040049 backendTex,
50 kTopLeft_GrSurfaceOrigin,
51 0,
52 colorType,
53 nullptr, nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040054 if (!surf) {
55 ERRORF(reporter, "Couldn't make surface from backendTexture for colorType %d\n",
56 colorType);
57 } else {
58 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040059 }
Robert Phillipsb04b6942019-05-21 17:24:31 -040060 }
Robert Phillips0c6daf02019-05-16 12:43:11 -040061
Robert Phillipsb04b6942019-05-21 17:24:31 -040062 {
63 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
Robert Phillips459b2952019-05-23 09:38:27 -040064 backendTex,
65 kTopLeft_GrSurfaceOrigin,
66 colorType,
67 kPremul_SkAlphaType,
68 nullptr);
Robert Phillipsb04b6942019-05-21 17:24:31 -040069 if (!img) {
70 ERRORF(reporter, "Couldn't make image from backendTexture for colorType %d\n",
71 colorType);
72 } else {
73 SkImage_Base* ib = as_IB(img);
Robert Phillipsefb9f142019-05-17 14:19:44 -040074
Robert Phillipsb04b6942019-05-21 17:24:31 -040075 GrTextureProxy* proxy = ib->peekProxy();
76 REPORTER_ASSERT(reporter, proxy);
Robert Phillipsefb9f142019-05-17 14:19:44 -040077
Robert Phillipsb04b6942019-05-21 17:24:31 -040078 REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipMapped());
79 REPORTER_ASSERT(reporter, proxy->isInstantiated());
80 REPORTER_ASSERT(reporter, mipMapped == proxy->mipMapped());
Robert Phillipsefb9f142019-05-17 14:19:44 -040081
Robert Phillipsb04b6942019-05-21 17:24:31 -040082 REPORTER_ASSERT(reporter, initialCount+1 == cache->getResourceCount());
Robert Phillips0c6daf02019-05-16 12:43:11 -040083 }
84 }
85
86 REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
87
Robert Phillips5c7a25b2019-05-20 08:38:07 -040088 context->deleteBackendTexture(backendTex);
Robert Phillips0c6daf02019-05-16 12:43:11 -040089}
90
Robert Phillips27eb5252019-06-03 12:59:40 -040091static bool colors_eq(SkColor colA, SkColor colB, int tol) {
92 int maxDiff = 0;
93 for (int i = 0; i < 4; ++i) {
94 int diff = SkTAbs<int>((0xFF & (colA >> i*8)) - (0xFF & (colB >> i*8)));
95 if (maxDiff < diff) {
96 maxDiff = diff;
97 }
98 }
99
100 return maxDiff <= tol;
101}
102
Robert Phillips459b2952019-05-23 09:38:27 -0400103static void compare_pixmaps(const SkPixmap& expected, const SkPixmap& actual,
104 SkColorType colorType, skiatest::Reporter* reporter) {
105 SkASSERT(expected.info() == actual.info());
106 for (int y = 0; y < expected.height(); ++y) {
107 for (int x = 0; x < expected.width(); ++x) {
108
109 SkColor expectedCol = expected.getColor(x, y);
110 SkColor actualCol = actual.getColor(x, y);
111
Robert Phillips459b2952019-05-23 09:38:27 -0400112 // GPU and raster differ a bit on kGray_8_SkColorType and kRGBA_1010102_SkColorType
Robert Phillips27eb5252019-06-03 12:59:40 -0400113 if (colors_eq(actualCol, expectedCol, 12)) {
Robert Phillips459b2952019-05-23 09:38:27 -0400114 continue;
115 }
116
117 ERRORF(reporter,
Robert Phillips27eb5252019-06-03 12:59:40 -0400118 "Mismatched pixels at %d %d ct: %d expected: 0x%x actual: 0x%x\n",
119 x, y, colorType, expectedCol, actualCol);
Robert Phillips459b2952019-05-23 09:38:27 -0400120 return;
121 }
122 }
123}
124
125// Test initialization of GrBackendObjects to a specific color
126void test_color_init(GrContext* context, skiatest::Reporter* reporter,
127 std::function<GrBackendTexture (GrContext*,
128 const SkColor4f&,
129 GrMipMapped,
130 GrRenderable)> create,
131 SkColorType colorType, const SkColor4f& color,
132 GrMipMapped mipMapped, GrRenderable renderable) {
133 GrBackendTexture backendTex = create(context, color, mipMapped, renderable);
134 if (!backendTex.isValid()) {
135 // errors here should be reported by the test_wrapping test
136 return;
137 }
138
139 if (kUnknown_SkColorType == colorType) {
140 // TODO: burrow in and scrappily check that data was uploaded!
141 context->deleteBackendTexture(backendTex);
142 return;
143 }
144
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400145 SkAlphaType at = SkColorTypeIsAlwaysOpaque(colorType) ? kOpaque_SkAlphaType
146 : kPremul_SkAlphaType;
147
148 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, at);
Robert Phillips459b2952019-05-23 09:38:27 -0400149
Robert Phillips27eb5252019-06-03 12:59:40 -0400150 SkColor4f rasterColor = color;
151 if (kGray_8_SkColorType == colorType) {
152 // For the GPU backends, gray implies a single channel which is opaque.
153 rasterColor.fR = color.fA;
154 rasterColor.fG = color.fA;
155 rasterColor.fB = color.fA;
156 rasterColor.fA = 1.0f;
157 } else if (kAlpha_8_SkColorType == colorType) {
158 // For the GPU backends, alpha implies a single alpha channel.
159 rasterColor.fR = 0;
160 rasterColor.fG = 0;
161 rasterColor.fB = 0;
162 rasterColor.fA = color.fA;
163 }
164
Robert Phillips459b2952019-05-23 09:38:27 -0400165 SkAutoPixmapStorage expected;
166 SkAssertResult(expected.tryAlloc(ii));
Robert Phillips27eb5252019-06-03 12:59:40 -0400167 expected.erase(rasterColor);
Robert Phillips459b2952019-05-23 09:38:27 -0400168
169 SkAutoPixmapStorage actual;
170 SkAssertResult(actual.tryAlloc(ii));
171 actual.erase(SkColors::kTransparent);
172
173 if (GrRenderable::kYes == renderable) {
174 sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(context,
175 backendTex,
176 kTopLeft_GrSurfaceOrigin,
177 0,
178 colorType,
179 nullptr, nullptr);
180 if (surf) {
181 bool result = surf->readPixels(actual, 0, 0);
182 REPORTER_ASSERT(reporter, result);
183
184 compare_pixmaps(expected, actual, colorType, reporter);
185
186 actual.erase(SkColors::kTransparent);
187 }
188 }
189
190 {
191 sk_sp<SkImage> img = SkImage::MakeFromTexture(context,
192 backendTex,
193 kTopLeft_GrSurfaceOrigin,
194 colorType,
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400195 at,
Robert Phillips459b2952019-05-23 09:38:27 -0400196 nullptr);
197 if (img) {
Robert Phillips27eb5252019-06-03 12:59:40 -0400198 // If possible, read back the pixels and check that they're correct
199 {
200 bool result = img->readPixels(actual, 0, 0);
201 if (!result) {
202 // TODO: we need a better way to tell a priori if readPixels will work for an
203 // arbitrary colorType
Robert Phillips459b2952019-05-23 09:38:27 -0400204#if 0
Robert Phillips27eb5252019-06-03 12:59:40 -0400205 ERRORF(reporter, "Couldn't readback from SkImage for colorType: %d\n",
206 colorType);
Robert Phillips459b2952019-05-23 09:38:27 -0400207#endif
Robert Phillips27eb5252019-06-03 12:59:40 -0400208 } else {
209 compare_pixmaps(expected, actual, colorType, reporter);
210 }
211 }
212
213 // Draw the wrapped image into an RGBA surface attempting to access all the
214 // mipMap levels.
215 {
216#ifdef SK_GL
217 // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
218 if (GrBackendApi::kOpenGL == context->backend()) {
219 GrGLGpu* glGPU = static_cast<GrGLGpu*>(context->priv().getGpu());
220
Robert Phillipsef032cd2019-06-03 15:12:50 -0400221 if (kRGBA_F32_SkColorType == colorType && GrMipMapped::kYes == mipMapped &&
222 kGLES_GrGLStandard == glGPU->ctxInfo().standard()) {
Robert Phillips27eb5252019-06-03 12:59:40 -0400223 context->deleteBackendTexture(backendTex);
224 return;
225 }
226 }
227#endif
228
229 SkImageInfo newII = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType,
230 kPremul_SkAlphaType);
231
232 SkAutoPixmapStorage actual2;
233 SkAssertResult(actual2.tryAlloc(newII));
234 actual2.erase(SkColors::kTransparent);
235
236 sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context,
237 SkBudgeted::kNo,
238 newII, 1,
239 kTopLeft_GrSurfaceOrigin,
240 nullptr);
241 if (!surf) {
242 context->deleteBackendTexture(backendTex);
243 return;
244 }
245
246 SkCanvas* canvas = surf->getCanvas();
247
248 SkPaint p;
249 p.setFilterQuality(kHigh_SkFilterQuality);
250
251 int numMipLevels = (GrMipMapped::kYes == mipMapped) ? 6 : 1;
252
253 for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
254 SkASSERT(rectSize >= 1);
255
256 SkRect r = SkRect::MakeWH(rectSize, rectSize);
257 canvas->clear(SK_ColorTRANSPARENT);
258 canvas->drawImageRect(img, r, &p);
259
260 bool result = surf->readPixels(actual2, 0, 0);
261 REPORTER_ASSERT(reporter, result);
262
263 SkColor actualColor = actual2.getColor(0, 0);
264
265 if (!colors_eq(actualColor, rasterColor.toSkColor(), 1)) {
266 ERRORF(reporter, "Pixel mismatch colorType %d: level: %d e: 0x%x a: 0x%x\n",
267 colorType, i, rasterColor.toSkColor(), actualColor);
268 }
269 }
Robert Phillips459b2952019-05-23 09:38:27 -0400270 }
271 }
272 }
273
274 context->deleteBackendTexture(backendTex);
275}
276
Robert Phillips02dc0302019-07-02 17:58:27 -0400277enum class VkLayout {
278 kUndefined,
279 kReadOnlyOptimal,
280 kColorAttachmentOptimal
281};
282
283void check_vk_layout(const GrBackendTexture& backendTex, VkLayout layout) {
284#if defined(SK_VULKAN) && defined(SK_DEBUG)
285 VkImageLayout expected;
286
287 switch (layout) {
288 case VkLayout::kUndefined:
289 expected = VK_IMAGE_LAYOUT_UNDEFINED;
290 break;
291 case VkLayout::kReadOnlyOptimal:
292 expected = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
293 break;
294 case VkLayout::kColorAttachmentOptimal:
295 expected = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
296 break;
297 default:
298 SkUNREACHABLE;
299 }
300
301 GrVkImageInfo vkII;
302
303 if (backendTex.getVkImageInfo(&vkII)) {
304 SkASSERT(expected == vkII.fImageLayout);
305 SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
306 }
307#endif
308}
309
310///////////////////////////////////////////////////////////////////////////////
311// This test is a bit different from the others in this file. It is mainly checking that, for any
312// SkSurface we can create in Ganesh, we can also create a backend texture that is compatible with
313// its characterization and then create a new surface that wraps that backend texture.
314DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CharacterizationBackendAllocationTest, reporter, ctxInfo) {
315 GrContext* context = ctxInfo.grContext();
316
317 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
318 SkColorType colorType = static_cast<SkColorType>(ct);
319
320 SkImageInfo ii = SkImageInfo::Make(32, 32, colorType, kPremul_SkAlphaType);
321
322 for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
323 for (bool mipMaps : { true, false } ) {
324 for (int sampleCount : {1, 2}) {
325 SkSurfaceCharacterization c;
326
327 // Get a characterization, if possible
328 {
329 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
330 ii, sampleCount,
331 origin, nullptr, mipMaps);
332 if (!s) {
333 continue;
334 }
335
336 if (!s->characterize(&c)) {
337 continue;
338 }
339
340 REPORTER_ASSERT(reporter, s->isCompatible(c));
341 }
342
343 // Test out uninitialized path
344 {
345 GrBackendTexture backendTex = context->createBackendTexture(c);
346 check_vk_layout(backendTex, VkLayout::kUndefined);
347 REPORTER_ASSERT(reporter, backendTex.isValid());
348 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
349
350 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
351 backendTex);
352 REPORTER_ASSERT(reporter, s2);
353 REPORTER_ASSERT(reporter, s2->isCompatible(c));
354
355 s2 = nullptr;
356 context->deleteBackendTexture(backendTex);
357 }
358
359 // Test out color-initialized path
360 {
361 GrBackendTexture backendTex = context->createBackendTexture(c,
362 SkColors::kRed);
363 check_vk_layout(backendTex, VkLayout::kColorAttachmentOptimal);
364 REPORTER_ASSERT(reporter, backendTex.isValid());
365 REPORTER_ASSERT(reporter, c.isCompatible(backendTex));
366
367 sk_sp<SkSurface> s2 = SkSurface::MakeFromBackendTexture(context, c,
368 backendTex);
369 REPORTER_ASSERT(reporter, s2);
370 REPORTER_ASSERT(reporter, s2->isCompatible(c));
371
372 s2 = nullptr;
373 context->deleteBackendTexture(backendTex);
374 }
375 }
376 }
377 }
378 }
379}
380
Robert Phillipsefb9f142019-05-17 14:19:44 -0400381///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400382DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
383 GrContext* context = ctxInfo.grContext();
384 const GrCaps* caps = context->priv().caps();
385
Robert Phillips459b2952019-05-23 09:38:27 -0400386 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400387 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400388
Robert Phillips0c6daf02019-05-16 12:43:11 -0400389 struct {
390 SkColorType fColorType;
391 GrPixelConfig fConfig;
Robert Phillips459b2952019-05-23 09:38:27 -0400392 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400393 } combinations[] = {
Robert Phillips459b2952019-05-23 09:38:27 -0400394 { kAlpha_8_SkColorType, kAlpha_8_GrPixelConfig, kTransCol },
395 { kRGB_565_SkColorType, kRGB_565_GrPixelConfig, SkColors::kRed },
396 { kARGB_4444_SkColorType, kRGBA_4444_GrPixelConfig, SkColors::kGreen },
397 { kRGBA_8888_SkColorType, kRGBA_8888_GrPixelConfig, SkColors::kBlue },
398 { kRGB_888x_SkColorType, kRGB_888_GrPixelConfig, SkColors::kCyan },
399 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
400 { kBGRA_8888_SkColorType, kBGRA_8888_GrPixelConfig, { 1, 0, 0, 1.0f } },
401 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
402 { kRGBA_1010102_SkColorType, kRGBA_1010102_GrPixelConfig, { 0.5f, 0, 0, 1.0f }},
Robert Phillipsb04b6942019-05-21 17:24:31 -0400403 // The kRGB_101010x_SkColorType has no Ganesh correlate
Robert Phillips459b2952019-05-23 09:38:27 -0400404 { kRGB_101010x_SkColorType, kUnknown_GrPixelConfig, { 0, 0.5f, 0, 0.5f }},
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400405 { kGray_8_SkColorType, kGray_8_GrPixelConfig, kGrayCol },
Robert Phillips459b2952019-05-23 09:38:27 -0400406 { kRGBA_F16Norm_SkColorType, kRGBA_half_Clamped_GrPixelConfig, SkColors::kLtGray },
407 { kRGBA_F16_SkColorType, kRGBA_half_GrPixelConfig, SkColors::kYellow },
408 { kRGBA_F32_SkColorType, kRGBA_float_GrPixelConfig, SkColors::kGray },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400409 };
410
411 SkASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
412
413 for (auto combo : combinations) {
414 SkColorType colorType = combo.fColorType;
415
416 if (!caps->isConfigTexturable(combo.fConfig)) {
417 continue;
418 }
419
420 if (GrBackendApi::kMetal == context->backend()) {
421 // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
422 if (kRGBA_F32_SkColorType == combo.fColorType) {
423 continue;
424 }
425 }
426
Robert Phillipsefb9f142019-05-17 14:19:44 -0400427 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
428 if (GrMipMapped::kYes == mipMapped && !caps->mipMapSupport()) {
429 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400430 }
431
Robert Phillipsefb9f142019-05-17 14:19:44 -0400432 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
433 if (GrRenderable::kYes == renderable) {
434 if (kRGB_888x_SkColorType == combo.fColorType) {
435 // Ganesh can't perform the blends correctly when rendering this format
436 continue;
437 }
438 if (!caps->isConfigRenderable(combo.fConfig)) {
439 continue;
440 }
441 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400442
Robert Phillipsb04b6942019-05-21 17:24:31 -0400443 {
444 auto uninitCreateMtd = [colorType](GrContext* context,
445 GrMipMapped mipMapped,
446 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400447 auto result = context->createBackendTexture(32, 32, colorType,
448 mipMapped, renderable,
449 GrProtected::kNo);
450 check_vk_layout(result, VkLayout::kUndefined);
451 return result;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400452 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400453
Robert Phillipsb04b6942019-05-21 17:24:31 -0400454 test_wrapping(context, reporter, uninitCreateMtd,
455 colorType, mipMapped, renderable);
456 }
Robert Phillips459b2952019-05-23 09:38:27 -0400457
458 {
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400459 // GL has difficulties reading back from these combinations. In particular,
460 // reading back kGray_8 is a mess.
Robert Phillips459b2952019-05-23 09:38:27 -0400461 if (GrBackendApi::kOpenGL == context->backend()) {
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400462 if (kAlpha_8_SkColorType == combo.fColorType ||
463 kGray_8_SkColorType == combo.fColorType) {
Robert Phillips459b2952019-05-23 09:38:27 -0400464 continue;
465 }
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400466 } else if (GrBackendApi::kMetal == context->backend()) {
467 // Not yet implemented for Metal
Robert Phillips459b2952019-05-23 09:38:27 -0400468 continue;
469 }
470
471 auto createWithColorMtd = [colorType](GrContext* context,
472 const SkColor4f& color,
473 GrMipMapped mipMapped,
474 GrRenderable renderable) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400475 auto result = context->createBackendTexture(32, 32, colorType, color,
476 mipMapped, renderable,
477 GrProtected::kNo);
478 check_vk_layout(result, GrRenderable::kYes == renderable
479 ? VkLayout::kColorAttachmentOptimal
480 : VkLayout::kReadOnlyOptimal);
481 return result;
Robert Phillips459b2952019-05-23 09:38:27 -0400482 };
483
484 test_color_init(context, reporter, createWithColorMtd,
485 colorType, combo.fColor, mipMapped, renderable);
486 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400487 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400488 }
489 }
490
491}
492
Robert Phillipsefb9f142019-05-17 14:19:44 -0400493///////////////////////////////////////////////////////////////////////////////
494#ifdef SK_GL
495
496#include "src/gpu/gl/GrGLCaps.h"
Robert Phillips0c6daf02019-05-16 12:43:11 -0400497#include "src/gpu/gl/GrGLDefines.h"
498
499DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
500 sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
501 GrGLStandard standard = glCtx->gl()->fStandard;
502 GrContext* context = ctxInfo.grContext();
Robert Phillipsefb9f142019-05-17 14:19:44 -0400503 const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
Robert Phillips0c6daf02019-05-16 12:43:11 -0400504
Robert Phillips459b2952019-05-23 09:38:27 -0400505 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400506 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400507
Robert Phillips0c6daf02019-05-16 12:43:11 -0400508 struct {
509 SkColorType fColorType;
510 GrGLenum fFormat;
511 // TODO: remove 'fConfig' and directly use 'fFormat' in GrGLCaps::isFormatTexturable
512 GrPixelConfig fConfig;
Robert Phillips459b2952019-05-23 09:38:27 -0400513 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400514 } combinations[] = {
Robert Phillips459b2952019-05-23 09:38:27 -0400515 { kRGBA_8888_SkColorType, GR_GL_RGBA8,
516 kRGBA_8888_GrPixelConfig, SkColors::kRed },
517 { kRGBA_8888_SkColorType, GR_GL_SRGB8_ALPHA8,
518 kSRGBA_8888_GrPixelConfig, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400519
Robert Phillips459b2952019-05-23 09:38:27 -0400520 { kRGB_888x_SkColorType, GR_GL_RGBA8,
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400521 kRGBA_8888_GrPixelConfig, SkColors::kYellow },
Robert Phillips459b2952019-05-23 09:38:27 -0400522 { kRGB_888x_SkColorType, GR_GL_RGB8,
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400523 kRGB_888_GrPixelConfig, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400524
Robert Phillips459b2952019-05-23 09:38:27 -0400525 { kBGRA_8888_SkColorType, GR_GL_RGBA8,
526 kRGBA_8888_GrPixelConfig, SkColors::kBlue },
527 { kBGRA_8888_SkColorType, GR_GL_BGRA8,
528 kBGRA_8888_GrPixelConfig, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400529
Robert Phillips459b2952019-05-23 09:38:27 -0400530 { kRGBA_1010102_SkColorType, GR_GL_RGB10_A2,
531 // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
532 kRGBA_1010102_GrPixelConfig, { 0.5f, 0, 0, 1.0f }},
533 { kRGB_565_SkColorType, GR_GL_RGB565,
534 kRGB_565_GrPixelConfig, SkColors::kRed },
535 { kARGB_4444_SkColorType, GR_GL_RGBA4,
536 kRGBA_4444_GrPixelConfig, SkColors::kGreen },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400537
Robert Phillips459b2952019-05-23 09:38:27 -0400538 { kAlpha_8_SkColorType, GR_GL_ALPHA8,
539 kAlpha_8_as_Alpha_GrPixelConfig, kTransCol },
540 { kAlpha_8_SkColorType, GR_GL_R8,
541 kAlpha_8_as_Red_GrPixelConfig, kTransCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400542
Robert Phillips459b2952019-05-23 09:38:27 -0400543 { kGray_8_SkColorType, GR_GL_LUMINANCE8,
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400544 kGray_8_as_Lum_GrPixelConfig, kGrayCol },
Robert Phillips459b2952019-05-23 09:38:27 -0400545 { kGray_8_SkColorType, GR_GL_R8,
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400546 kGray_8_as_Red_GrPixelConfig, kGrayCol },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400547
Robert Phillips459b2952019-05-23 09:38:27 -0400548 { kRGBA_F32_SkColorType, GR_GL_RGBA32F,
549 kRGBA_float_GrPixelConfig, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400550
Robert Phillips459b2952019-05-23 09:38:27 -0400551 { kRGBA_F16Norm_SkColorType, GR_GL_RGBA16F,
552 kRGBA_half_Clamped_GrPixelConfig, SkColors::kLtGray },
553 { kRGBA_F16_SkColorType, GR_GL_RGBA16F,
554 kRGBA_half_GrPixelConfig, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400555
556 // These backend formats don't have SkColorType equivalents
Robert Phillips459b2952019-05-23 09:38:27 -0400557 { kUnknown_SkColorType, GR_GL_RG8,
558 kRG_88_GrPixelConfig, { 0.5f, 0.5f, 0, 0 }},
559 { kUnknown_SkColorType, GR_GL_R16F,
560 kAlpha_half_as_Red_GrPixelConfig, { 1.0f, 0, 0, 0.5f }},
561 { kUnknown_SkColorType, GR_GL_COMPRESSED_RGB8_ETC2,
562 kRGB_ETC1_GrPixelConfig, SkColors::kRed },
Robert Phillips8043f322019-05-31 08:11:36 -0400563 { kUnknown_SkColorType, GR_GL_COMPRESSED_ETC1_RGB8,
564 kRGB_ETC1_GrPixelConfig, SkColors::kRed },
Robert Phillipsfe18de52019-06-06 17:21:50 -0400565 { kUnknown_SkColorType, GR_GL_R16,
566 kR_16_GrPixelConfig, SkColors::kRed },
567 { kUnknown_SkColorType, GR_GL_RG16,
Robert Phillips66a46032019-06-18 08:00:42 -0400568 kRG_1616_GrPixelConfig, SkColors::kYellow },
569
570 // Experimental (for Y416 and mutant P016/P010)
571 { kUnknown_SkColorType, GR_GL_RGBA16,
572 kRGBA_16161616_GrPixelConfig, SkColors::kLtGray },
573 { kUnknown_SkColorType, GR_GL_RG16F,
574 kRG_half_GrPixelConfig, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400575 };
576
577 for (auto combo : combinations) {
Robert Phillips8043f322019-05-31 08:11:36 -0400578 if (kRGB_ETC1_GrPixelConfig == combo.fConfig) {
579 // RGB8_ETC2/ETC1_RGB8 is an either/or situation
580 GrGLenum supportedETC1Format = glCaps->configSizedInternalFormat(combo.fConfig);
581 if (supportedETC1Format != combo.fFormat) {
582 continue;
583 }
584 }
585
Robert Phillips0c6daf02019-05-16 12:43:11 -0400586 GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
587
Robert Phillips8043f322019-05-31 08:11:36 -0400588 if (GR_GL_COMPRESSED_RGB8_ETC2 == combo.fFormat ||
589 GR_GL_COMPRESSED_ETC1_RGB8 == combo.fFormat) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400590 // We current disallow uninitialized ETC1 textures in the GL backend
591 continue;
592 }
Greg Daniele877dce2019-07-11 10:52:43 -0400593
Robert Phillips97256382019-07-17 15:26:36 -0400594 GrColorType grCT = SkColorTypeAndFormatToGrColorType(glCaps, combo.fColorType, format);
595 if (GrColorType::kUnknown == grCT) {
596 continue;
Greg Daniele877dce2019-07-11 10:52:43 -0400597 }
598
599 if (!glCaps->isFormatTexturable(grCT, format)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400600 continue;
601 }
602
603 if (kBGRA_8888_SkColorType == combo.fColorType) {
604 if (GR_GL_RGBA8 == combo.fFormat && kGL_GrGLStandard != standard) {
605 continue;
606 }
607 if (GR_GL_BGRA8 == combo.fFormat && kGL_GrGLStandard == standard) {
608 continue;
609 }
610 }
611
Robert Phillipsefb9f142019-05-17 14:19:44 -0400612 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
613 if (GrMipMapped::kYes == mipMapped && !glCaps->mipMapSupport()) {
614 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400615 }
616
Robert Phillipsefb9f142019-05-17 14:19:44 -0400617 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400618
Robert Phillipsefb9f142019-05-17 14:19:44 -0400619 if (GrRenderable::kYes == renderable) {
620 if (kRGB_888x_SkColorType == combo.fColorType) {
621 // Ganesh can't perform the blends correctly when rendering this format
622 continue;
623 }
624 if (!glCaps->isConfigRenderable(combo.fConfig)) {
625 continue;
626 }
627 }
628
Robert Phillipsb04b6942019-05-21 17:24:31 -0400629 {
630 auto uninitCreateMtd = [format](GrContext* context,
631 GrMipMapped mipMapped,
632 GrRenderable renderable) {
633 return context->createBackendTexture(32, 32, format,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400634 mipMapped, renderable,
635 GrProtected::kNo);
Robert Phillipsb04b6942019-05-21 17:24:31 -0400636 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400637
Robert Phillipsb04b6942019-05-21 17:24:31 -0400638 test_wrapping(context, reporter, uninitCreateMtd,
639 combo.fColorType, mipMapped, renderable);
640 }
Robert Phillips459b2952019-05-23 09:38:27 -0400641
642 {
643 // GL has difficulties reading back from these combinations
644 if (kAlpha_8_SkColorType == combo.fColorType) {
645 continue;
646 }
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400647 if (GrRenderable::kYes != renderable) {
Robert Phillips459b2952019-05-23 09:38:27 -0400648 continue;
649 }
650
651 auto createWithColorMtd = [format](GrContext* context,
652 const SkColor4f& color,
653 GrMipMapped mipMapped,
654 GrRenderable renderable) {
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400655 return context->createBackendTexture(32, 32, format, color,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400656 mipMapped, renderable,
657 GrProtected::kNo);
Robert Phillips459b2952019-05-23 09:38:27 -0400658 };
659
660 test_color_init(context, reporter, createWithColorMtd,
661 combo.fColorType, combo.fColor, mipMapped, renderable);
662 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400663 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400664 }
665 }
666}
667
Robert Phillipsefb9f142019-05-17 14:19:44 -0400668#endif
669
670///////////////////////////////////////////////////////////////////////////////
Robert Phillips0c6daf02019-05-16 12:43:11 -0400671
672#ifdef SK_VULKAN
673
674#include "src/gpu/vk/GrVkCaps.h"
675
676DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
677 GrContext* context = ctxInfo.grContext();
678 const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
679
Robert Phillips459b2952019-05-23 09:38:27 -0400680 constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400681 constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
Robert Phillips459b2952019-05-23 09:38:27 -0400682
Robert Phillips0c6daf02019-05-16 12:43:11 -0400683 struct {
684 SkColorType fColorType;
685 VkFormat fFormat;
Robert Phillips459b2952019-05-23 09:38:27 -0400686 SkColor4f fColor;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400687 } combinations[] = {
Robert Phillips459b2952019-05-23 09:38:27 -0400688 { kRGBA_8888_SkColorType, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kRed },
689 { kRGBA_8888_SkColorType, VK_FORMAT_R8G8B8A8_SRGB, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400690
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400691 // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
692 // there is nothing to tell Skia to make the provided color opaque. Clients will need
693 // to provide an opaque initialization color in this case.
694 { kRGB_888x_SkColorType, VK_FORMAT_R8G8B8A8_UNORM, SkColors::kYellow },
695 { kRGB_888x_SkColorType, VK_FORMAT_R8G8B8_UNORM, SkColors::kCyan },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400696
Robert Phillips459b2952019-05-23 09:38:27 -0400697 { kBGRA_8888_SkColorType, VK_FORMAT_B8G8R8A8_UNORM, SkColors::kBlue },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400698
Robert Phillips459b2952019-05-23 09:38:27 -0400699 { kRGBA_1010102_SkColorType, VK_FORMAT_A2B10G10R10_UNORM_PACK32, { 0.5f, 0, 0, 1.0f } },
700 { kRGB_565_SkColorType, VK_FORMAT_R5G6B5_UNORM_PACK16, SkColors::kRed },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400701
Brian Salomonb450f3b2019-07-09 09:36:51 -0400702 { kARGB_4444_SkColorType, VK_FORMAT_R4G4B4A4_UNORM_PACK16, SkColors::kCyan },
Robert Phillips459b2952019-05-23 09:38:27 -0400703 { kARGB_4444_SkColorType, VK_FORMAT_B4G4R4A4_UNORM_PACK16, SkColors::kYellow },
Robert Phillipsefb9f142019-05-17 14:19:44 -0400704
Robert Phillips459b2952019-05-23 09:38:27 -0400705 { kAlpha_8_SkColorType, VK_FORMAT_R8_UNORM, kTransCol },
Robert Phillipsbd1ef682019-05-31 12:48:49 -0400706 // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
707 // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
708 // the alpha channel of the color). Clients should, in general, fill all the channels
709 // of the provided color with the same value in such cases.
710 { kGray_8_SkColorType, VK_FORMAT_R8_UNORM, kGrayCol },
711
Robert Phillips459b2952019-05-23 09:38:27 -0400712 { kRGBA_F32_SkColorType, VK_FORMAT_R32G32B32A32_SFLOAT, SkColors::kRed },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400713
Robert Phillips459b2952019-05-23 09:38:27 -0400714 { kRGBA_F16Norm_SkColorType, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kLtGray },
715 { kRGBA_F16_SkColorType, VK_FORMAT_R16G16B16A16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400716
717 // These backend formats don't have SkColorType equivalents
Robert Phillips459b2952019-05-23 09:38:27 -0400718 { kUnknown_SkColorType, VK_FORMAT_R8G8_UNORM, { 0.5f, 0.5f, 0, 0 } },
719 { kUnknown_SkColorType, VK_FORMAT_R16_SFLOAT, { 1.0f, 0, 0, 0.5f } },
Robert Phillipsfe18de52019-06-06 17:21:50 -0400720 { kUnknown_SkColorType, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, SkColors::kRed },
Robert Phillipsfe18de52019-06-06 17:21:50 -0400721 { kUnknown_SkColorType, VK_FORMAT_R16_UNORM, SkColors::kRed },
722 { kUnknown_SkColorType, VK_FORMAT_R16G16_UNORM, SkColors::kYellow },
Robert Phillips66a46032019-06-18 08:00:42 -0400723
724 // Experimental (for Y416 and mutant P016/P010)
725 { kUnknown_SkColorType, VK_FORMAT_R16G16B16A16_UNORM, SkColors::kLtGray },
726 { kUnknown_SkColorType, VK_FORMAT_R16G16_SFLOAT, SkColors::kYellow },
Robert Phillips0c6daf02019-05-16 12:43:11 -0400727 };
728
729 for (auto combo : combinations) {
Greg Daniel2f2caea2019-07-08 14:24:47 -0400730 if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400731 continue;
732 }
733
734 GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
735
Robert Phillipsefb9f142019-05-17 14:19:44 -0400736 for (auto mipMapped : { GrMipMapped::kNo, GrMipMapped::kYes }) {
737 if (GrMipMapped::kYes == mipMapped && !vkCaps->mipMapSupport()) {
738 continue;
Robert Phillips0c6daf02019-05-16 12:43:11 -0400739 }
740
Robert Phillipsefb9f142019-05-17 14:19:44 -0400741 for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
Robert Phillips0c6daf02019-05-16 12:43:11 -0400742
Robert Phillipsefb9f142019-05-17 14:19:44 -0400743 if (GrRenderable::kYes == renderable) {
744 if (kRGB_888x_SkColorType == combo.fColorType) {
745 // Ganesh can't perform the blends correctly when rendering this format
746 continue;
747 }
748 if (!vkCaps->isFormatRenderable(combo.fFormat)) {
749 continue;
750 }
751 }
752
Robert Phillipsb04b6942019-05-21 17:24:31 -0400753 {
754 auto uninitCreateMtd = [format](GrContext* context,
Robert Phillips459b2952019-05-23 09:38:27 -0400755 GrMipMapped mipMapped,
756 GrRenderable renderable) {
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400757 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
758 mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400759 renderable,
760 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400761 check_vk_layout(beTex, VkLayout::kUndefined);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400762 return beTex;
Robert Phillipsb04b6942019-05-21 17:24:31 -0400763 };
Robert Phillipsefb9f142019-05-17 14:19:44 -0400764
Robert Phillipsb04b6942019-05-21 17:24:31 -0400765 test_wrapping(context, reporter, uninitCreateMtd,
766 combo.fColorType, mipMapped, renderable);
767 }
Robert Phillips459b2952019-05-23 09:38:27 -0400768
Robert Phillips459b2952019-05-23 09:38:27 -0400769 {
Brian Salomonb450f3b2019-07-09 09:36:51 -0400770 // We're creating backend textures without specifying a color type "view" of
771 // them at the public API level. Therefore, Ganesh will not apply any swizzles
772 // before writing the color to the texture. However, our validation code does
773 // rely on interpreting the texture contents via a SkColorType and therefore
774 // swizzles may be applied during the read step.
775 // Ideally we'd update our validation code to use a "raw" read that doesn't
776 // impose a color type but for now we just munge the data we upload to match the
777 // expectation.
778 GrSwizzle swizzle;
779 switch (combo.fColorType) {
780 case kAlpha_8_SkColorType:
781 SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
782 swizzle = GrSwizzle("aaaa");
783 break;
784 case kARGB_4444_SkColorType:
785 if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
786 swizzle = GrSwizzle("bgra");
787 }
788 break;
789 default:
790 swizzle = GrSwizzle("rgba");
791 break;
792 }
793 auto createWithColorMtd = [format, swizzle](GrContext* context,
794 const SkColor4f& color,
795 GrMipMapped mipMapped,
796 GrRenderable renderable) {
797 auto swizzledColor = swizzle.applyTo(color);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400798 GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
Brian Salomonb450f3b2019-07-09 09:36:51 -0400799 swizzledColor,
800 mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400801 renderable,
802 GrProtected::kNo);
Robert Phillips02dc0302019-07-02 17:58:27 -0400803 check_vk_layout(beTex, GrRenderable::kYes == renderable
804 ? VkLayout::kColorAttachmentOptimal
805 : VkLayout::kReadOnlyOptimal);
Robert Phillipsd1d869d2019-06-07 14:21:31 -0400806 return beTex;
Robert Phillips459b2952019-05-23 09:38:27 -0400807 };
Robert Phillips459b2952019-05-23 09:38:27 -0400808 test_color_init(context, reporter, createWithColorMtd,
809 combo.fColorType, combo.fColor, mipMapped, renderable);
810 }
Robert Phillipsefb9f142019-05-17 14:19:44 -0400811 }
Robert Phillips0c6daf02019-05-16 12:43:11 -0400812 }
813 }
814}
815
816#endif