1 /*
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 
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkSurface.h"
10 #include "include/core/SkSurfaceCharacterization.h"
11 #include "include/gpu/GrDirectContext.h"
12 #include "src/core/SkAutoPixmapStorage.h"
13 #include "src/gpu/GrDirectContextPriv.h"
14 #include "src/gpu/GrProxyProvider.h"
15 #include "src/gpu/GrSurfaceFillContext.h"
16 #include "src/gpu/effects/GrBlendFragmentProcessor.h"
17 #include "src/image/SkImage_Base.h"
18 #include "tests/Test.h"
19 #include "tests/TestUtils.h"
20 #include "tools/ToolUtils.h"
21 #include "tools/gpu/ManagedBackendTexture.h"
22 #include "tools/gpu/ProxyUtils.h"
23 
24 #ifdef SK_GL
25 #include "src/gpu/gl/GrGLCaps.h"
26 #include "src/gpu/gl/GrGLDefines.h"
27 #include "src/gpu/gl/GrGLGpu.h"
28 #include "src/gpu/gl/GrGLUtil.h"
29 #endif
30 
31 #ifdef SK_METAL
32 #include "include/gpu/mtl/GrMtlTypes.h"
33 #include "src/gpu/mtl/GrMtlCppUtil.h"
34 #endif
35 
36 using sk_gpu_test::ManagedBackendTexture;
37 
38 // Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
test_wrapping(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,GrMipmapped,GrRenderable)> create,GrColorType grColorType,GrMipmapped mipMapped,GrRenderable renderable)39 void test_wrapping(GrDirectContext* dContext,
40                    skiatest::Reporter* reporter,
41                    std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
42                                                               GrMipmapped,
43                                                               GrRenderable)> create,
44                    GrColorType grColorType,
45                    GrMipmapped mipMapped,
46                    GrRenderable renderable) {
47     GrResourceCache* cache = dContext->priv().getResourceCache();
48 
49     const int initialCount = cache->getResourceCount();
50 
51     sk_sp<ManagedBackendTexture> mbet = create(dContext, mipMapped, renderable);
52     if (!mbet) {
53         ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
54                grColorType,
55                GrRenderable::kYes == renderable ? "yes" : "no");
56         return;
57     }
58 
59     // Skia proper should know nothing about the new backend object
60     REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
61 
62     SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
63 
64     // Wrapping a backendTexture in an SkImage/SkSurface requires an SkColorType
65     if (skColorType == kUnknown_SkColorType) {
66         return;
67     }
68 
69     // As we transition to using attachments instead of GrTextures and GrRenderTargets individual
70     // proxy instansiations may add multiple things to the cache. There would be an entry for the
71     // GrTexture/GrRenderTarget and entries for one or more attachments.
72     int cacheEntriesPerProxy = 1;
73     // We currently only have attachments on the vulkan backend
74     if (dContext->backend() == GrBackend::kVulkan) {
75         // If we ever make a rt with multisamples this would have an additional
76         // attachment as well.
77         cacheEntriesPerProxy++;
78     }
79 
80     if (GrRenderable::kYes == renderable && dContext->colorTypeSupportedAsSurface(skColorType)) {
81         sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(dContext,
82                                                                   mbet->texture(),
83                                                                   kTopLeft_GrSurfaceOrigin,
84                                                                   0,
85                                                                   skColorType,
86                                                                   nullptr, nullptr);
87         if (!surf) {
88             ERRORF(reporter, "Couldn't make SkSurface from backendTexture for %s\n",
89                    ToolUtils::colortype_name(skColorType));
90         } else {
91             REPORTER_ASSERT(reporter,
92                             initialCount + cacheEntriesPerProxy == cache->getResourceCount());
93         }
94     }
95 
96     {
97         sk_sp<SkImage> img = SkImage::MakeFromTexture(dContext,
98                                                       mbet->texture(),
99                                                       kTopLeft_GrSurfaceOrigin,
100                                                       skColorType,
101                                                       kUnpremul_SkAlphaType,
102                                                       nullptr);
103         if (!img) {
104             ERRORF(reporter, "Couldn't make SkImage from backendTexture for %s\n",
105                    ToolUtils::colortype_name(skColorType));
106         } else {
107             GrTextureProxy* proxy = sk_gpu_test::GetTextureImageProxy(img.get(), dContext);
108             REPORTER_ASSERT(reporter, proxy);
109 
110             REPORTER_ASSERT(reporter, mipMapped == proxy->proxyMipmapped());
111             REPORTER_ASSERT(reporter, proxy->isInstantiated());
112             REPORTER_ASSERT(reporter, mipMapped == proxy->mipmapped());
113 
114             REPORTER_ASSERT(reporter,
115                             initialCount + cacheEntriesPerProxy == cache->getResourceCount());
116         }
117     }
118 
119     REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
120 }
121 
isBGRA8(const GrBackendFormat & format)122 static bool isBGRA8(const GrBackendFormat& format) {
123     switch (format.backend()) {
124         case GrBackendApi::kOpenGL:
125 #ifdef SK_GL
126             return format.asGLFormat() == GrGLFormat::kBGRA8;
127 #else
128             return false;
129 #endif
130         case GrBackendApi::kVulkan: {
131 #ifdef SK_VULKAN
132             VkFormat vkFormat;
133             format.asVkFormat(&vkFormat);
134             return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
135 #else
136             return false;
137 #endif
138         }
139         case GrBackendApi::kMetal:
140 #ifdef SK_METAL
141             return GrMtlFormatIsBGRA8(format.asMtlFormat());
142 #else
143             return false;
144 #endif
145         case GrBackendApi::kDirect3D:
146 #ifdef SK_DIRECT3D
147             return false; // TODO
148 #else
149             return false;
150 #endif
151         case GrBackendApi::kDawn:
152 #ifdef SK_DAWN
153             wgpu::TextureFormat dawnFormat;
154             format.asDawnFormat(&dawnFormat);
155             return dawnFormat == wgpu::TextureFormat::BGRA8Unorm;
156 #else
157             return false;
158 #endif
159         case GrBackendApi::kMock: {
160             SkImage::CompressionType compression = format.asMockCompressionType();
161             if (compression != SkImage::CompressionType::kNone) {
162                 return false; // No compressed formats are BGRA
163             }
164 
165             return format.asMockColorType() == GrColorType::kBGRA_8888;
166         }
167     }
168     SkUNREACHABLE;
169 }
170 
isRGB(const GrBackendFormat & format)171 static bool isRGB(const GrBackendFormat& format) {
172     switch (format.backend()) {
173         case GrBackendApi::kOpenGL:
174 #ifdef SK_GL
175             return format.asGLFormat() == GrGLFormat::kRGB8;
176 #else
177             return false;
178 #endif
179         case GrBackendApi::kVulkan: {
180 #ifdef SK_VULKAN
181             VkFormat vkFormat;
182             format.asVkFormat(&vkFormat);
183             return vkFormat == VK_FORMAT_R8G8B8_UNORM;
184 #else
185             return false;
186 #endif
187         }
188         case GrBackendApi::kMetal:
189             return false;  // Metal doesn't even pretend to support this
190         case GrBackendApi::kDirect3D:
191             return false;  // Not supported in Direct3D 12
192         case GrBackendApi::kDawn:
193             return false;
194         case GrBackendApi::kMock:
195             return false;  // No GrColorType::kRGB_888
196     }
197     SkUNREACHABLE;
198 }
199 
check_solid_pixmap(skiatest::Reporter * reporter,const SkColor4f & expected,const SkPixmap & actual,GrColorType ct,const char * label1,const char * label2)200 static void check_solid_pixmap(skiatest::Reporter* reporter,
201                                const SkColor4f& expected,
202                                const SkPixmap& actual,
203                                GrColorType ct,
204                                const char* label1,
205                                const char* label2) {
206     // we need 0.001f across the board just for noise
207     // we need 0.01f across the board for 1010102
208     const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
209 
210     auto error = std::function<ComparePixmapsErrorReporter>(
211         [reporter, ct, label1, label2](int x, int y, const float diffs[4]) {
212             SkASSERT(x >= 0 && y >= 0);
213             ERRORF(reporter, "%s %s %s - mismatch at %d, %d (%f, %f, %f %f)", GrColorTypeToStr(ct),
214                    label1, label2, x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
215         });
216 
217     CheckSolidPixels(expected, actual, tols, error);
218 }
219 
220 // Determine what color we expect if we store 'orig' in 'ct' converted back to SkColor4f.
get_expected_color(SkColor4f orig,GrColorType ct)221 static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct) {
222     GrImageInfo ii(ct, kUnpremul_SkAlphaType, nullptr, {1, 1});
223     std::unique_ptr<char[]> data(new char[ii.minRowBytes()]);
224     GrClearImage(ii, data.get(), ii.minRowBytes(), orig.array());
225 
226     // Read back to SkColor4f.
227     SkColor4f result;
228     GrImageInfo resultII(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, nullptr, {1, 1});
229     GrConvertPixels(GrPixmap(resultII,  &result.fR,   sizeof(result)),
230                     GrPixmap(      ii,  data.get(), ii.minRowBytes()));
231     return result;
232 }
233 
234 static void check_mipmaps(GrDirectContext*,
235                           const GrBackendTexture&,
236                           GrColorType,
237                           const SkColor4f expectedColors[6],
238                           skiatest::Reporter*,
239                           const char* label);
240 
check_base_readbacks(GrDirectContext * dContext,const GrBackendTexture & backendTex,GrColorType colorType,GrRenderable renderableTexture,const SkColor4f & color,skiatest::Reporter * reporter,const char * label)241 static void check_base_readbacks(GrDirectContext* dContext,
242                                  const GrBackendTexture& backendTex,
243                                  GrColorType colorType,
244                                  GrRenderable renderableTexture,
245                                  const SkColor4f& color,
246                                  skiatest::Reporter* reporter,
247                                  const char* label) {
248     if (isRGB(backendTex.getBackendFormat())) {
249         // readPixels is busted for the RGB backend format (skbug.com/8862)
250         // TODO: add a GrColorType::kRGB_888 to fix the situation
251         return;
252     }
253 
254     SkColor4f expectedColor = get_expected_color(color, colorType);
255 
256     SkAutoPixmapStorage actual;
257 
258     {
259         SkImageInfo readBackII = SkImageInfo::Make(32, 32,
260                                                    kRGBA_8888_SkColorType,
261                                                    kUnpremul_SkAlphaType);
262 
263         SkAssertResult(actual.tryAlloc(readBackII));
264     }
265     for (GrRenderable renderableCtx : {GrRenderable::kNo, GrRenderable::kYes}) {
266         if (renderableCtx == GrRenderable::kYes && renderableTexture == GrRenderable::kNo) {
267             continue;
268         }
269         sk_sp<GrSurfaceProxy> proxy;
270         if (renderableCtx == GrRenderable::kYes) {
271             proxy = dContext->priv().proxyProvider()->wrapRenderableBackendTexture(
272                     backendTex, 1, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, nullptr);
273         } else {
274             proxy = dContext->priv().proxyProvider()->wrapBackendTexture(
275                     backendTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
276         }
277         if (!proxy) {
278             ERRORF(reporter, "Could not make proxy from backend texture");
279             return;
280         }
281         auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
282                                                                colorType);
283         GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
284         GrColorInfo info(colorType, kUnpremul_SkAlphaType, nullptr);
285         auto surfaceContext = GrSurfaceContext::Make(dContext, readView, info);
286         if (!surfaceContext) {
287             ERRORF(reporter, "Could not create surface context for colorType: %d\n", colorType);
288         }
289 
290         if (!surfaceContext->readPixels(dContext, actual, {0, 0})) {
291             // TODO: we need a better way to tell a priori if readPixels will work for an
292             // arbitrary colorType
293 #if 0
294             ERRORF(reporter, "Couldn't readback from GrSurfaceContext for colorType: %d\n",
295                    colorType);
296 #endif
297         } else {
298             auto name = SkStringPrintf("%s::readPixels",
299                                        (renderableCtx == GrRenderable::kYes ? "GrSurfaceFillContext"
300                                                                             : "GrSurfaceContext"));
301             check_solid_pixmap(reporter, expectedColor, actual, colorType, label, name.c_str());
302         }
303     }
304 }
305 
306 // Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
test_color_init(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,const SkColor4f &,GrMipmapped,GrRenderable)> create,GrColorType colorType,const SkColor4f & color,GrMipmapped mipmapped,GrRenderable renderable)307 void test_color_init(GrDirectContext* dContext,
308                      skiatest::Reporter* reporter,
309                      std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
310                                                                 const SkColor4f&,
311                                                                 GrMipmapped,
312                                                                 GrRenderable)> create,
313                      GrColorType colorType,
314                      const SkColor4f& color,
315                      GrMipmapped mipmapped,
316                      GrRenderable renderable) {
317     sk_sp<ManagedBackendTexture> mbet = create(dContext, color, mipmapped, renderable);
318     if (!mbet) {
319         // errors here should be reported by the test_wrapping test
320         return;
321     }
322 
323     auto checkBackendTexture = [&](const SkColor4f& testColor) {
324         if (mipmapped == GrMipmapped::kYes) {
325             SkColor4f expectedColor = get_expected_color(testColor, colorType);
326             SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
327                                            expectedColor, expectedColor, expectedColor};
328             check_mipmaps(dContext, mbet->texture(), colorType, expectedColors, reporter,
329                           "colorinit");
330         }
331 
332         // The last step in this test will dirty the mipmaps so do it last
333         check_base_readbacks(dContext, mbet->texture(), colorType, renderable, testColor, reporter,
334                              "colorinit");
335     };
336 
337     checkBackendTexture(color);
338 
339     SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
340 
341     SkColorType skColorType = GrColorTypeToSkColorType(colorType);
342     // Our update method only works with SkColorTypes.
343     if (skColorType != kUnknown_SkColorType) {
344         dContext->updateBackendTexture(mbet->texture(),
345                                        skColorType,
346                                        newColor,
347                                        ManagedBackendTexture::ReleaseProc,
348                                        mbet->releaseContext());
349         checkBackendTexture(newColor);
350     }
351 }
352 
353 // Draw the backend texture into an RGBA surface fill context, attempting to access all the mipMap
354 // levels.
check_mipmaps(GrDirectContext * dContext,const GrBackendTexture & backendTex,GrColorType colorType,const SkColor4f expectedColors[6],skiatest::Reporter * reporter,const char * label)355 static void check_mipmaps(GrDirectContext* dContext,
356                           const GrBackendTexture& backendTex,
357                           GrColorType colorType,
358                           const SkColor4f expectedColors[6],
359                           skiatest::Reporter* reporter,
360                           const char* label) {
361 #ifdef SK_GL
362     // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
363     if (GrBackendApi::kOpenGL == dContext->backend()) {
364         GrGLGpu* glGPU = static_cast<GrGLGpu*>(dContext->priv().getGpu());
365 
366         if (colorType == GrColorType::kRGBA_F32 &&
367             glGPU->ctxInfo().standard() == kGLES_GrGLStandard) {
368             return;
369         }
370     }
371 #endif
372 
373     if (isRGB(backendTex.getBackendFormat())) {
374         // readPixels is busted for the RGB backend format (skbug.com/8862)
375         // TODO: add a GrColorType::kRGB_888 to fix the situation
376         return;
377     }
378 
379     GrImageInfo info(GrColorType::kRGBA_8888, kUnpremul_SkAlphaType, nullptr, {32, 32});
380     auto dstFillContext = GrSurfaceFillContext::Make(dContext, info);
381     if (!dstFillContext) {
382         ERRORF(reporter, "Could not make dst fill context.");
383         return;
384     }
385 
386     int numMipLevels = 6;
387 
388     auto proxy = dContext->priv().proxyProvider()->wrapBackendTexture(backendTex,
389                                                                       kBorrow_GrWrapOwnership,
390                                                                       GrWrapCacheable::kNo,
391                                                                       kRW_GrIOType);
392     if (!proxy) {
393         ERRORF(reporter, "Could not make proxy from backend texture");
394         return;
395     }
396     auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
397                                                            colorType);
398     GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
399 
400     for (int i = 0, rectSize = 32; i < numMipLevels; ++i, rectSize /= 2) {
401         SkASSERT(rectSize >= 1);
402         dstFillContext->clear(SK_PMColor4fTRANSPARENT);
403 
404         SkMatrix texMatrix;
405         texMatrix.setScale(1 << i, 1 << i);
406         static constexpr GrSamplerState kNearestNearest(GrSamplerState::Filter::kNearest,
407                                                         GrSamplerState::MipmapMode::kNearest);
408         auto fp = GrTextureEffect::Make(readView,
409                                         kUnpremul_SkAlphaType,
410                                         texMatrix,
411                                         kNearestNearest,
412                                         *dstFillContext->caps());
413         // Our swizzles for alpha color types currently produce (a, a, a, a) in the shader. Remove
414         // this once they are correctly (0, 0, 0, a).
415         if (GrColorTypeIsAlphaOnly(colorType)) {
416             auto black = GrFragmentProcessor::MakeColor(SK_PMColor4fBLACK);
417             fp = GrBlendFragmentProcessor::Make(std::move(fp),
418                                                 std::move(black),
419                                                 SkBlendMode::kModulate);
420         }
421         dstFillContext->fillRectWithFP(SkIRect::MakeWH(rectSize, rectSize), std::move(fp));
422 
423         SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
424                                                    kRGBA_8888_SkColorType,
425                                                    kUnpremul_SkAlphaType);
426         SkAutoPixmapStorage actual;
427         SkAssertResult(actual.tryAlloc(readbackII));
428         actual.erase(SkColors::kTransparent);
429 
430         bool result = dstFillContext->readPixels(dContext, actual, {0, 0});
431         REPORTER_ASSERT(reporter, result);
432 
433         SkString str;
434         str.appendf("mip-level %d", i);
435 
436         check_solid_pixmap(reporter, expectedColors[i], actual, colorType, label, str.c_str());
437     }
438 }
439 
make_pixmaps(SkColorType skColorType,GrMipmapped mipmapped,const SkColor4f colors[6],SkPixmap pixmaps[6],std::unique_ptr<char[]> * mem)440 static int make_pixmaps(SkColorType skColorType,
441                         GrMipmapped mipmapped,
442                         const SkColor4f colors[6],
443                         SkPixmap pixmaps[6],
444                         std::unique_ptr<char[]>* mem) {
445     int levelSize = 32;
446     int numMipLevels = mipmapped == GrMipmapped::kYes ? 6 : 1;
447     size_t size = 0;
448     SkImageInfo ii[6];
449     size_t rowBytes[6];
450     for (int level = 0; level < numMipLevels; ++level) {
451         ii[level] = SkImageInfo::Make(levelSize, levelSize, skColorType, kUnpremul_SkAlphaType);
452         rowBytes[level] = ii[level].minRowBytes();
453         // Make sure we test row bytes that aren't tight.
454         if (!(level % 2)) {
455             rowBytes[level] += (level + 1)*SkColorTypeBytesPerPixel(ii[level].colorType());
456         }
457         size += rowBytes[level]*ii[level].height();
458         levelSize /= 2;
459     }
460     mem->reset(new char[size]);
461     char* addr = mem->get();
462     for (int level = 0; level < numMipLevels; ++level) {
463         pixmaps[level].reset(ii[level], addr, rowBytes[level]);
464         addr += rowBytes[level]*ii[level].height();
465         pixmaps[level].erase(colors[level]);
466         levelSize /= 2;
467     }
468     return numMipLevels;
469 }
470 
471 // Test initialization of GrBackendObjects using SkPixmaps
test_pixmap_init(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,const SkPixmap srcData[],int numLevels,GrSurfaceOrigin,GrRenderable)> create,SkColorType skColorType,GrSurfaceOrigin origin,GrMipmapped mipmapped,GrRenderable renderable)472 static void test_pixmap_init(GrDirectContext* dContext,
473                              skiatest::Reporter* reporter,
474                              std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
475                                                                         const SkPixmap srcData[],
476                                                                         int numLevels,
477                                                                         GrSurfaceOrigin,
478                                                                         GrRenderable)> create,
479                              SkColorType skColorType,
480                              GrSurfaceOrigin origin,
481                              GrMipmapped mipmapped,
482                              GrRenderable renderable) {
483     SkPixmap pixmaps[6];
484     std::unique_ptr<char[]> memForPixmaps;
485     SkColor4f colors[6] = {
486         { 1.0f, 0.0f, 0.0f, 1.0f }, // R
487         { 0.0f, 1.0f, 0.0f, 0.9f }, // G
488         { 0.0f, 0.0f, 1.0f, 0.7f }, // B
489         { 0.0f, 1.0f, 1.0f, 0.5f }, // C
490         { 1.0f, 0.0f, 1.0f, 0.3f }, // M
491         { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
492     };
493 
494     int numMipLevels = make_pixmaps(skColorType, mipmapped, colors, pixmaps, &memForPixmaps);
495     SkASSERT(numMipLevels);
496 
497     sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
498     if (!mbet) {
499         // errors here should be reported by the test_wrapping test
500         return;
501     }
502 
503     if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(mbet->texture().getBackendFormat())) {
504         // When kBGRA is backed by an RGBA something goes wrong in the swizzling
505         return;
506     }
507 
508     auto checkBackendTexture = [&](SkColor4f colors[6]) {
509         GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
510         if (mipmapped == GrMipmapped::kYes) {
511             SkColor4f expectedColors[6] = {
512                     get_expected_color(colors[0], grColorType),
513                     get_expected_color(colors[1], grColorType),
514                     get_expected_color(colors[2], grColorType),
515                     get_expected_color(colors[3], grColorType),
516                     get_expected_color(colors[4], grColorType),
517                     get_expected_color(colors[5], grColorType),
518             };
519 
520             check_mipmaps(dContext, mbet->texture(), grColorType, expectedColors, reporter,
521                           "pixmap");
522         }
523 
524         // The last step in this test will dirty the mipmaps so do it last
525         check_base_readbacks(dContext, mbet->texture(), grColorType, renderable, colors[0],
526                              reporter, "pixmap");
527     };
528 
529     checkBackendTexture(colors);
530 
531     SkColor4f colorsNew[6] = {
532         {1.0f, 1.0f, 0.0f, 0.2f},  // Y
533         {1.0f, 0.0f, 0.0f, 1.0f},  // R
534         {0.0f, 1.0f, 0.0f, 0.9f},  // G
535         {0.0f, 0.0f, 1.0f, 0.7f},  // B
536         {0.0f, 1.0f, 1.0f, 0.5f},  // C
537         {1.0f, 0.0f, 1.0f, 0.3f},  // M
538     };
539     make_pixmaps(skColorType, mipmapped, colorsNew, pixmaps, &memForPixmaps);
540 
541     // Upload new data and make sure everything still works
542     dContext->updateBackendTexture(mbet->texture(),
543                                    pixmaps,
544                                    numMipLevels,
545                                    origin,
546                                    ManagedBackendTexture::ReleaseProc,
547                                    mbet->releaseContext());
548 
549     checkBackendTexture(colorsNew);
550 }
551 
552 enum class VkLayout {
553     kUndefined,
554     kReadOnlyOptimal,
555 };
556 
check_vk_tiling(const GrBackendTexture & backendTex)557 void check_vk_tiling(const GrBackendTexture& backendTex) {
558 #if defined(SK_VULKAN) && defined(SK_DEBUG)
559     GrVkImageInfo vkII;
560     if (backendTex.getVkImageInfo(&vkII)) {
561         SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
562     }
563 #endif
564 }
565 
566 ///////////////////////////////////////////////////////////////////////////////
color_type_backend_allocation_test(const sk_gpu_test::ContextInfo & ctxInfo,skiatest::Reporter * reporter)567 void color_type_backend_allocation_test(const sk_gpu_test::ContextInfo& ctxInfo,
568                                         skiatest::Reporter* reporter) {
569     auto context = ctxInfo.directContext();
570     const GrCaps* caps = context->priv().caps();
571 
572     constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
573     constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
574 
575     struct {
576         SkColorType   fColorType;
577         SkColor4f     fColor;
578     } combinations[] = {
579         { kAlpha_8_SkColorType,           kTransCol                },
580         { kRGB_565_SkColorType,           SkColors::kRed           },
581         { kARGB_4444_SkColorType,         SkColors::kGreen         },
582         { kRGBA_8888_SkColorType,         SkColors::kBlue          },
583         { kRGB_888x_SkColorType,          SkColors::kCyan          },
584         // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
585         { kBGRA_8888_SkColorType,         { 1, 0, 0, 1.0f }        },
586         // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
587         { kRGBA_1010102_SkColorType,      { 0.25f, 0.5f, 0.75f, 1.0f }},
588         { kBGRA_1010102_SkColorType,      { 0.25f, 0.5f, 0.75f, 1.0f }},
589         // RGB/BGR 101010x have no Ganesh correlate
590         { kRGB_101010x_SkColorType,       { 0, 0.5f, 0, 0.5f }     },
591         { kBGR_101010x_SkColorType,       { 0, 0.5f, 0, 0.5f }     },
592         { kGray_8_SkColorType,            kGrayCol                 },
593         { kRGBA_F16Norm_SkColorType,      SkColors::kLtGray        },
594         { kRGBA_F16_SkColorType,          SkColors::kYellow        },
595         { kRGBA_F32_SkColorType,          SkColors::kGray          },
596         { kR8G8_unorm_SkColorType,        { .25f, .75f, 0, 1 }     },
597         { kR16G16_unorm_SkColorType,      SkColors::kGreen         },
598         { kA16_unorm_SkColorType,         kTransCol                },
599         { kA16_float_SkColorType,         kTransCol                },
600         { kR16G16_float_SkColorType,      { .25f, .75f, 0, 1 }     },
601         { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 }   },
602     };
603 
604     static_assert(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
605 
606     for (auto combo : combinations) {
607         SkColorType colorType = combo.fColorType;
608 
609         if (GrBackendApi::kMetal == context->backend()) {
610             // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
611             if (kRGBA_F32_SkColorType == combo.fColorType) {
612                 continue;
613             }
614         }
615 
616         for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
617             if (GrMipmapped::kYes == mipmapped && !caps->mipmapSupport()) {
618                 continue;
619             }
620 
621             for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
622                 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
623                                                    renderable).isValid()) {
624                     continue;
625                 }
626 
627                 if (GrRenderable::kYes == renderable) {
628                     if (kRGB_888x_SkColorType == combo.fColorType) {
629                         // Ganesh can't perform the blends correctly when rendering this format
630                         continue;
631                     }
632                 }
633 
634                 {
635                     auto uninitCreateMtd = [colorType](GrDirectContext* dContext,
636                                                        GrMipmapped mipmapped,
637                                                        GrRenderable renderable) {
638                         auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
639                                                                            32, 32,
640                                                                            colorType,
641                                                                            mipmapped,
642                                                                            renderable,
643                                                                            GrProtected::kNo);
644                         check_vk_tiling(mbet->texture());
645 #ifdef SK_DEBUG
646                         {
647                             GrBackendFormat format = dContext->defaultBackendFormat(colorType,
648                                                                                     renderable);
649                             SkASSERT(format == mbet->texture().getBackendFormat());
650                         }
651 #endif
652 
653                         return mbet;
654                     };
655 
656                     test_wrapping(context, reporter, uninitCreateMtd,
657                                   SkColorTypeToGrColorType(colorType), mipmapped, renderable);
658                 }
659 
660                 {
661                     auto createWithColorMtd = [colorType](GrDirectContext* dContext,
662                                                           const SkColor4f& color,
663                                                           GrMipmapped mipmapped,
664                                                           GrRenderable renderable) {
665                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
666                                                                         32, 32,
667                                                                         colorType,
668                                                                         color,
669                                                                         mipmapped,
670                                                                         renderable,
671                                                                         GrProtected::kNo);
672                         check_vk_tiling(mbet->texture());
673 
674 #ifdef SK_DEBUG
675                         {
676                             GrBackendFormat format = dContext->defaultBackendFormat(colorType,
677                                                                                    renderable);
678                             SkASSERT(format == mbet->texture().getBackendFormat());
679                         }
680 #endif
681 
682                         return mbet;
683                     };
684                     test_color_init(context, reporter, createWithColorMtd,
685                                     SkColorTypeToGrColorType(colorType), combo.fColor, mipmapped,
686                                     renderable);
687                 }
688 
689                 for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
690                     auto createWithSrcDataMtd = [](GrDirectContext* dContext,
691                                                    const SkPixmap srcData[],
692                                                    int numLevels,
693                                                    GrSurfaceOrigin origin,
694                                                    GrRenderable renderable) {
695                         SkASSERT(srcData && numLevels);
696                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
697                                                                         srcData,
698                                                                         numLevels,
699                                                                         origin,
700                                                                         renderable,
701                                                                         GrProtected::kNo);
702                         check_vk_tiling(mbet->texture());
703 #ifdef SK_DEBUG
704                         {
705                             auto format = dContext->defaultBackendFormat(srcData[0].colorType(),
706                                                                          renderable);
707                             SkASSERT(format == mbet->texture().getBackendFormat());
708                         }
709 #endif
710                         return mbet;
711                     };
712 
713                     test_pixmap_init(context,
714                                      reporter,
715                                      createWithSrcDataMtd,
716                                      colorType,
717                                      origin,
718                                      mipmapped,
719                                      renderable);
720                 }
721             }
722         }
723     }
724 }
725 
DEF_GPUTEST(ColorTypeBackendAllocationTest,reporter,options)726 DEF_GPUTEST(ColorTypeBackendAllocationTest, reporter, options) {
727     for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
728         auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
729         if (!sk_gpu_test::GrContextFactory::IsRenderingContext(type)) {
730             continue;
731         }
732         sk_gpu_test::GrContextFactory factory(options);
733         sk_gpu_test::ContextInfo info = factory.getContextInfo(type);
734         if (!info.directContext()) {
735             continue;
736         }
737         color_type_backend_allocation_test(info, reporter);
738         // The GL backend must support contexts that don't allow GL_UNPACK_ROW_LENGTH. Other
739         // backends are not required to work with this cap disabled.
740         if (info.directContext()->priv().caps()->writePixelsRowBytesSupport() &&
741             info.directContext()->backend() == GrBackendApi::kOpenGL) {
742             GrContextOptions overrideOptions = options;
743             overrideOptions.fDisallowWritePixelRowBytes = true;
744             sk_gpu_test::GrContextFactory overrideFactory(overrideOptions);
745             info = overrideFactory.getContextInfo(type);
746             color_type_backend_allocation_test(info, reporter);
747         }
748     }
749 }
750 
751 ///////////////////////////////////////////////////////////////////////////////
752 #ifdef SK_GL
753 
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest,reporter,ctxInfo)754 DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest, reporter, ctxInfo) {
755     sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
756     GrGLStandard standard = glCtx->gl()->fStandard;
757     auto context = ctxInfo.directContext();
758     const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
759 
760     constexpr SkColor4f kTransCol     { 0,     0.25f, 0.75f, 0.5f };
761     constexpr SkColor4f kGrayCol      { 0.75f, 0.75f, 0.75f, 1.f  };
762     constexpr SkColor4f kTransGrayCol { 0.5f,  0.5f,  0.5f,  .8f  };
763 
764     struct {
765         GrColorType   fColorType;
766         GrGLenum      fFormat;
767         SkColor4f     fColor;
768     } combinations[] = {
769         { GrColorType::kRGBA_8888,        GR_GL_RGBA8,                SkColors::kRed       },
770         { GrColorType::kRGBA_8888_SRGB,   GR_GL_SRGB8_ALPHA8,         SkColors::kRed       },
771 
772         { GrColorType::kRGB_888x,         GR_GL_RGBA8,                SkColors::kYellow    },
773         { GrColorType::kRGB_888x,         GR_GL_RGB8,                 SkColors::kCyan      },
774 
775         { GrColorType::kBGRA_8888,        GR_GL_RGBA8,                SkColors::kBlue      },
776         { GrColorType::kBGRA_8888,        GR_GL_BGRA8,                SkColors::kBlue      },
777         // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
778         { GrColorType::kRGBA_1010102,     GR_GL_RGB10_A2,             { 0.25f, 0.5f, 0.75f, 1.f }},
779         { GrColorType::kBGRA_1010102,     GR_GL_RGB10_A2,             { 0.25f, 0.5f, 0.75f, 1.f }},
780         { GrColorType::kBGR_565,          GR_GL_RGB565,               SkColors::kRed       },
781         { GrColorType::kABGR_4444,        GR_GL_RGBA4,                SkColors::kGreen     },
782 
783         { GrColorType::kAlpha_8,          GR_GL_ALPHA8,               kTransCol            },
784         { GrColorType::kAlpha_8,          GR_GL_R8,                   kTransCol            },
785 
786         { GrColorType::kGray_8,           GR_GL_LUMINANCE8,           kGrayCol             },
787         { GrColorType::kGray_8,           GR_GL_R8,                   kGrayCol             },
788 
789         { GrColorType::kGrayAlpha_88,     GR_GL_LUMINANCE8_ALPHA8,    kTransGrayCol        },
790 
791         { GrColorType::kRGBA_F32,         GR_GL_RGBA32F,              SkColors::kRed       },
792 
793         { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F,              SkColors::kLtGray    },
794         { GrColorType::kRGBA_F16,         GR_GL_RGBA16F,              SkColors::kYellow    },
795 
796         { GrColorType::kRG_88,            GR_GL_RG8,                  { 1, 0.5f, 0, 1 }    },
797         { GrColorType::kAlpha_F16,        GR_GL_R16F,                 { 1.0f, 0, 0, 0.5f } },
798         { GrColorType::kAlpha_F16,        GR_GL_LUMINANCE16F,         kGrayCol             },
799 
800         { GrColorType::kAlpha_16,         GR_GL_R16,                  kTransCol            },
801         { GrColorType::kRG_1616,          GR_GL_RG16,                 SkColors::kYellow    },
802 
803         { GrColorType::kRGBA_16161616,    GR_GL_RGBA16,               SkColors::kLtGray    },
804         { GrColorType::kRG_F16,           GR_GL_RG16F,                SkColors::kYellow    },
805     };
806 
807     for (auto combo : combinations) {
808         for (GrGLenum target : {GR_GL_TEXTURE_2D, GR_GL_TEXTURE_RECTANGLE}) {
809             GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, target);
810 
811             if (!glCaps->isFormatTexturable(format)) {
812                 continue;
813             }
814 
815             if (GrColorType::kBGRA_8888 == combo.fColorType ||
816                 GrColorType::kBGRA_1010102 == combo.fColorType) {
817                 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not
818                 // ES
819                 if (kGL_GrGLStandard != standard &&
820                     (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
821                     continue;
822                 }
823             }
824 
825             for (auto mipMapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
826                 if (GrMipmapped::kYes == mipMapped &&
827                     (!glCaps->mipmapSupport() || target == GR_GL_TEXTURE_RECTANGLE)) {
828                     continue;
829                 }
830 
831                 for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
832                     if (GrRenderable::kYes == renderable) {
833                         if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
834                             continue;
835                         }
836                     }
837 
838                     {
839                         auto uninitCreateMtd = [format](GrDirectContext* dContext,
840                                                         GrMipmapped mipMapped,
841                                                         GrRenderable renderable) {
842                             return ManagedBackendTexture::MakeWithoutData(dContext,
843                                                                           32, 32,
844                                                                           format,
845                                                                           mipMapped,
846                                                                           renderable,
847                                                                           GrProtected::kNo);
848                         };
849 
850                         test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType,
851                                       mipMapped, renderable);
852                     }
853 
854                     {
855                         // We're creating backend textures without specifying a color type "view" of
856                         // them at the public API level. Therefore, Ganesh will not apply any
857                         // swizzles before writing the color to the texture. However, our validation
858                         // code does rely on interpreting the texture contents via a SkColorType and
859                         // therefore swizzles may be applied during the read step. Ideally we'd
860                         // update our validation code to use a "raw" read that doesn't impose a
861                         // color type but for now we just munge the data we upload to match the
862                         // expectation.
863                         GrSwizzle swizzle;
864                         switch (combo.fColorType) {
865                             case GrColorType::kAlpha_8:
866                                 swizzle = GrSwizzle("aaaa");
867                                 break;
868                             case GrColorType::kAlpha_16:
869                                 swizzle = GrSwizzle("aaaa");
870                                 break;
871                             case GrColorType::kAlpha_F16:
872                                 swizzle = GrSwizzle("aaaa");
873                                 break;
874                             default:
875                                 break;
876                         }
877                         auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
878                                                                     const SkColor4f& color,
879                                                                     GrMipmapped mipmapped,
880                                                                     GrRenderable renderable) {
881                             auto swizzledColor = swizzle.applyTo(color);
882                             return ManagedBackendTexture::MakeWithData(dContext,
883                                                                        32, 32,
884                                                                        format,
885                                                                        swizzledColor,
886                                                                        mipmapped,
887                                                                        renderable,
888                                                                        GrProtected::kNo);
889                         };
890                         test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
891                                         combo.fColor, mipMapped, renderable);
892                     }
893                 }
894             }
895         }
896     }
897 }
898 
899 #endif
900 
901 ///////////////////////////////////////////////////////////////////////////////
902 
903 #ifdef SK_VULKAN
904 
905 #include "src/gpu/vk/GrVkCaps.h"
906 
DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest,reporter,ctxInfo)907 DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest, reporter, ctxInfo) {
908     auto context = ctxInfo.directContext();
909     const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
910 
911     constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
912     constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
913 
914     struct {
915         GrColorType fColorType;
916         VkFormat    fFormat;
917         SkColor4f   fColor;
918     } combinations[] = {
919         { GrColorType::kRGBA_8888,        VK_FORMAT_R8G8B8A8_UNORM,           SkColors::kRed      },
920         { GrColorType::kRGBA_8888_SRGB,   VK_FORMAT_R8G8B8A8_SRGB,            SkColors::kRed      },
921 
922         // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
923         // there is nothing to tell Skia to make the provided color opaque. Clients will need
924         // to provide an opaque initialization color in this case.
925         { GrColorType::kRGB_888x,         VK_FORMAT_R8G8B8A8_UNORM,           SkColors::kYellow   },
926         { GrColorType::kRGB_888x,         VK_FORMAT_R8G8B8_UNORM,             SkColors::kCyan     },
927 
928         { GrColorType::kBGRA_8888,        VK_FORMAT_B8G8R8A8_UNORM,           SkColors::kBlue     },
929 
930         { GrColorType::kRGBA_1010102,     VK_FORMAT_A2B10G10R10_UNORM_PACK32,
931                                                                       { 0.25f, 0.5f, 0.75f, 1.0f }},
932         { GrColorType::kBGRA_1010102,     VK_FORMAT_A2R10G10B10_UNORM_PACK32,
933                                                                       { 0.25f, 0.5f, 0.75f, 1.0f }},
934         { GrColorType::kBGR_565,          VK_FORMAT_R5G6B5_UNORM_PACK16,      SkColors::kRed      },
935 
936         { GrColorType::kABGR_4444,        VK_FORMAT_R4G4B4A4_UNORM_PACK16,    SkColors::kCyan     },
937         { GrColorType::kABGR_4444,        VK_FORMAT_B4G4R4A4_UNORM_PACK16,    SkColors::kYellow   },
938 
939         { GrColorType::kAlpha_8,          VK_FORMAT_R8_UNORM,                 kTransCol           },
940         // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
941         // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
942         // the alpha channel of the color). Clients should, in general, fill all the channels
943         // of the provided color with the same value in such cases.
944         { GrColorType::kGray_8,           VK_FORMAT_R8_UNORM,                 kGrayCol            },
945 
946         { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT,      SkColors::kLtGray   },
947         { GrColorType::kRGBA_F16,         VK_FORMAT_R16G16B16A16_SFLOAT,      SkColors::kYellow   },
948 
949         { GrColorType::kRG_88,            VK_FORMAT_R8G8_UNORM,               { 1, 0.5f, 0, 1 }   },
950         { GrColorType::kAlpha_F16,        VK_FORMAT_R16_SFLOAT,               { 1.0f, 0, 0, 0.5f }},
951 
952         { GrColorType::kAlpha_16,         VK_FORMAT_R16_UNORM,                kTransCol           },
953         { GrColorType::kRG_1616,          VK_FORMAT_R16G16_UNORM,             SkColors::kYellow   },
954         { GrColorType::kRGBA_16161616,    VK_FORMAT_R16G16B16A16_UNORM,       SkColors::kLtGray   },
955         { GrColorType::kRG_F16,           VK_FORMAT_R16G16_SFLOAT,            SkColors::kYellow   },
956     };
957 
958     for (auto combo : combinations) {
959         if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
960             continue;
961         }
962 
963         GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
964 
965         for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
966             if (GrMipmapped::kYes == mipMapped && !vkCaps->mipmapSupport()) {
967                 continue;
968             }
969 
970             for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
971 
972                 if (GrRenderable::kYes == renderable) {
973                     // We must also check whether we allow rendering to the format using the
974                     // color type.
975                     if (!vkCaps->isFormatAsColorTypeRenderable(
976                             combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
977                         continue;
978                     }
979                 }
980 
981                 {
982                     auto uninitCreateMtd = [format](GrDirectContext* dContext,
983                                                     GrMipmapped mipMapped,
984                                                     GrRenderable renderable) {
985                         auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
986                                                                            32, 32,
987                                                                            format,
988                                                                            mipMapped,
989                                                                            renderable,
990                                                                            GrProtected::kNo);
991                         check_vk_tiling(mbet->texture());
992                         return mbet;
993                     };
994 
995                     test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType, mipMapped,
996                                   renderable);
997                 }
998 
999                 {
1000                     // We're creating backend textures without specifying a color type "view" of
1001                     // them at the public API level. Therefore, Ganesh will not apply any swizzles
1002                     // before writing the color to the texture. However, our validation code does
1003                     // rely on interpreting the texture contents via a SkColorType and therefore
1004                     // swizzles may be applied during the read step.
1005                     // Ideally we'd update our validation code to use a "raw" read that doesn't
1006                     // impose a color type but for now we just munge the data we upload to match the
1007                     // expectation.
1008                     GrSwizzle swizzle;
1009                     switch (combo.fColorType) {
1010                         case GrColorType::kAlpha_8:
1011                             SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
1012                             swizzle = GrSwizzle("aaaa");
1013                             break;
1014                         case GrColorType::kAlpha_16:
1015                             SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
1016                             swizzle = GrSwizzle("aaaa");
1017                             break;
1018                         case GrColorType::kAlpha_F16:
1019                             SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
1020                             swizzle = GrSwizzle("aaaa");
1021                             break;
1022                         case GrColorType::kABGR_4444:
1023                             if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
1024                                 swizzle = GrSwizzle("bgra");
1025                             }
1026                             break;
1027                         default:
1028                             swizzle = GrSwizzle("rgba");
1029                             break;
1030                     }
1031 
1032                     auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
1033                                                                 const SkColor4f& color,
1034                                                                 GrMipmapped mipMapped,
1035                                                                 GrRenderable renderable) {
1036                         auto swizzledColor = swizzle.applyTo(color);
1037                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
1038                                                                         32, 32,
1039                                                                         format,
1040                                                                         swizzledColor,
1041                                                                         mipMapped,
1042                                                                         renderable,
1043                                                                         GrProtected::kNo);
1044                         check_vk_tiling(mbet->texture());
1045                         return mbet;
1046                     };
1047                     test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
1048                                     combo.fColor, mipMapped, renderable);
1049                 }
1050             }
1051         }
1052     }
1053 }
1054 
1055 #endif
1056