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