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