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/gpu/GrDirectContext.h"
9cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
10cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlCaps.h"
11cb93a386Sopenharmony_ci#include "tests/Test.h"
12cb93a386Sopenharmony_ci#include "tools/gpu/ManagedBackendTexture.h"
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ci#import <Metal/Metal.h>
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ciusing sk_gpu_test::ManagedBackendTexture;
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ci// In BackendAllocationTest.cpp
19cb93a386Sopenharmony_civoid test_wrapping(GrDirectContext*,
20cb93a386Sopenharmony_ci                   skiatest::Reporter*,
21cb93a386Sopenharmony_ci                   std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
22cb93a386Sopenharmony_ci                                                              GrMipmapped,
23cb93a386Sopenharmony_ci                                                              GrRenderable)> create,
24cb93a386Sopenharmony_ci                   GrColorType,
25cb93a386Sopenharmony_ci                   GrMipmapped,
26cb93a386Sopenharmony_ci                   GrRenderable);
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_civoid test_color_init(GrDirectContext*,
29cb93a386Sopenharmony_ci                     skiatest::Reporter*,
30cb93a386Sopenharmony_ci                     std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
31cb93a386Sopenharmony_ci                                                                const SkColor4f&,
32cb93a386Sopenharmony_ci                                                                GrMipmapped,
33cb93a386Sopenharmony_ci                                                                GrRenderable)> create,
34cb93a386Sopenharmony_ci                     GrColorType,
35cb93a386Sopenharmony_ci                     const SkColor4f&,
36cb93a386Sopenharmony_ci                     GrMipmapped,
37cb93a386Sopenharmony_ci                     GrRenderable);
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_METAL_CONTEXT(MtlBackendAllocationTest, reporter, ctxInfo) {
40cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
41cb93a386Sopenharmony_ci    const GrMtlCaps* mtlCaps = static_cast<const GrMtlCaps*>(dContext->priv().caps());
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci    constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
44cb93a386Sopenharmony_ci    constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci    struct {
47cb93a386Sopenharmony_ci        GrColorType      fColorType;
48cb93a386Sopenharmony_ci        MTLPixelFormat   fFormat;
49cb93a386Sopenharmony_ci        SkColor4f        fColor;
50cb93a386Sopenharmony_ci    } combinations[] = {
51cb93a386Sopenharmony_ci        { GrColorType::kRGBA_8888,        MTLPixelFormatRGBA8Unorm,      SkColors::kRed       },
52cb93a386Sopenharmony_ci        { GrColorType::kRGBA_8888_SRGB,   MTLPixelFormatRGBA8Unorm_sRGB, SkColors::kRed       },
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci        // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
55cb93a386Sopenharmony_ci        // there is nothing to tell Skia to make the provided color opaque. Clients will need
56cb93a386Sopenharmony_ci        // to provide an opaque initialization color in this case.
57cb93a386Sopenharmony_ci        { GrColorType::kRGB_888x,         MTLPixelFormatRGBA8Unorm,      SkColors::kYellow    },
58cb93a386Sopenharmony_ci
59cb93a386Sopenharmony_ci        { GrColorType::kBGRA_8888,        MTLPixelFormatBGRA8Unorm,      SkColors::kBlue      },
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci        { GrColorType::kRGBA_1010102,     MTLPixelFormatRGB10A2Unorm,
62cb93a386Sopenharmony_ci                                                                    { 0.25f, 0.5f, 0.75f, 1.0f } },
63cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
64cb93a386Sopenharmony_ci        { GrColorType::kBGRA_1010102,     MTLPixelFormatBGR10A2Unorm,
65cb93a386Sopenharmony_ci                                                                    { 0.25f, 0.5f, 0.75f, 1.0f } },
66cb93a386Sopenharmony_ci#endif
67cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
68cb93a386Sopenharmony_ci        { GrColorType::kBGR_565,          MTLPixelFormatB5G6R5Unorm,     SkColors::kRed       },
69cb93a386Sopenharmony_ci        { GrColorType::kABGR_4444,        MTLPixelFormatABGR4Unorm,      SkColors::kGreen     },
70cb93a386Sopenharmony_ci#endif
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci        { GrColorType::kAlpha_8,          MTLPixelFormatA8Unorm,         kTransCol            },
73cb93a386Sopenharmony_ci        { GrColorType::kAlpha_8,          MTLPixelFormatR8Unorm,         kTransCol            },
74cb93a386Sopenharmony_ci        { GrColorType::kGray_8,           MTLPixelFormatR8Unorm,         kGrayCol             },
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci        { GrColorType::kRGBA_F16_Clamped, MTLPixelFormatRGBA16Float,     SkColors::kLtGray    },
77cb93a386Sopenharmony_ci        { GrColorType::kRGBA_F16,         MTLPixelFormatRGBA16Float,     SkColors::kYellow    },
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci        { GrColorType::kRG_88,            MTLPixelFormatRG8Unorm,        { 0.5f, 0.5f, 0, 1 } },
80cb93a386Sopenharmony_ci        { GrColorType::kAlpha_F16,        MTLPixelFormatR16Float,        { 1.0f, 0, 0, 0.5f } },
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci        { GrColorType::kAlpha_16,         MTLPixelFormatR16Unorm,        kTransCol            },
83cb93a386Sopenharmony_ci        { GrColorType::kRG_1616,          MTLPixelFormatRG16Unorm,       SkColors::kYellow    },
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci        { GrColorType::kRGBA_16161616,    MTLPixelFormatRGBA16Unorm,     SkColors::kLtGray    },
86cb93a386Sopenharmony_ci        { GrColorType::kRG_F16,           MTLPixelFormatRG16Float,       SkColors::kYellow    },
87cb93a386Sopenharmony_ci    };
88cb93a386Sopenharmony_ci
89cb93a386Sopenharmony_ci    for (auto combo : combinations) {
90cb93a386Sopenharmony_ci        GrBackendFormat format = GrBackendFormat::MakeMtl(combo.fFormat);
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci        if (!mtlCaps->isFormatTexturable(combo.fFormat)) {
93cb93a386Sopenharmony_ci            continue;
94cb93a386Sopenharmony_ci        }
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci        // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
97cb93a386Sopenharmony_ci        if (GrColorType::kRGBA_F32 == combo.fColorType) {
98cb93a386Sopenharmony_ci            continue;
99cb93a386Sopenharmony_ci        }
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci        for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
102cb93a386Sopenharmony_ci            if (GrMipmapped::kYes == mipMapped && !mtlCaps->mipmapSupport()) {
103cb93a386Sopenharmony_ci                continue;
104cb93a386Sopenharmony_ci            }
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci            for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_ci                if (GrRenderable::kYes == renderable) {
109cb93a386Sopenharmony_ci                    // We must also check whether we allow rendering to the format using the
110cb93a386Sopenharmony_ci                    // color type.
111cb93a386Sopenharmony_ci                    if (!mtlCaps->isFormatAsColorTypeRenderable(
112cb93a386Sopenharmony_ci                            combo.fColorType, GrBackendFormat::MakeMtl(combo.fFormat), 1)) {
113cb93a386Sopenharmony_ci                        continue;
114cb93a386Sopenharmony_ci                    }
115cb93a386Sopenharmony_ci                }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci                {
118cb93a386Sopenharmony_ci                    auto uninitCreateMtd = [format](GrDirectContext* dContext,
119cb93a386Sopenharmony_ci                                                    GrMipmapped mipMapped,
120cb93a386Sopenharmony_ci                                                    GrRenderable renderable) {
121cb93a386Sopenharmony_ci                        return ManagedBackendTexture::MakeWithoutData(dContext,
122cb93a386Sopenharmony_ci                                                                      32, 32,
123cb93a386Sopenharmony_ci                                                                      format,
124cb93a386Sopenharmony_ci                                                                      mipMapped,
125cb93a386Sopenharmony_ci                                                                      renderable,
126cb93a386Sopenharmony_ci                                                                      GrProtected::kNo);
127cb93a386Sopenharmony_ci                    };
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ci                    test_wrapping(dContext, reporter, uninitCreateMtd, combo.fColorType, mipMapped,
130cb93a386Sopenharmony_ci                                  renderable);
131cb93a386Sopenharmony_ci                }
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci                {
134cb93a386Sopenharmony_ci                    // We're creating backend textures without specifying a color type "view" of
135cb93a386Sopenharmony_ci                    // them at the public API level. Therefore, Ganesh will not apply any swizzles
136cb93a386Sopenharmony_ci                    // before writing the color to the texture. However, our validation code does
137cb93a386Sopenharmony_ci                    // rely on interpreting the texture contents via a SkColorType and therefore
138cb93a386Sopenharmony_ci                    // swizzles may be applied during the read step.
139cb93a386Sopenharmony_ci                    // Ideally we'd update our validation code to use a "raw" read that doesn't
140cb93a386Sopenharmony_ci                    // impose a color type but for now we just munge the data we upload to match the
141cb93a386Sopenharmony_ci                    // expectation.
142cb93a386Sopenharmony_ci                    GrSwizzle swizzle;
143cb93a386Sopenharmony_ci                    switch (combo.fColorType) {
144cb93a386Sopenharmony_ci                        case GrColorType::kAlpha_8:
145cb93a386Sopenharmony_ci                            swizzle = GrSwizzle("aaaa");
146cb93a386Sopenharmony_ci                            break;
147cb93a386Sopenharmony_ci                        case GrColorType::kAlpha_16:
148cb93a386Sopenharmony_ci                            swizzle = GrSwizzle("aaaa");
149cb93a386Sopenharmony_ci                            break;
150cb93a386Sopenharmony_ci                        case GrColorType::kAlpha_F16:
151cb93a386Sopenharmony_ci                            swizzle = GrSwizzle("aaaa");
152cb93a386Sopenharmony_ci                            break;
153cb93a386Sopenharmony_ci                        default:
154cb93a386Sopenharmony_ci                            break;
155cb93a386Sopenharmony_ci                    }
156cb93a386Sopenharmony_ci
157cb93a386Sopenharmony_ci                    auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
158cb93a386Sopenharmony_ci                                                                const SkColor4f& color,
159cb93a386Sopenharmony_ci                                                                GrMipmapped mipMapped,
160cb93a386Sopenharmony_ci                                                                GrRenderable renderable) {
161cb93a386Sopenharmony_ci                        auto swizzledColor = swizzle.applyTo(color);
162cb93a386Sopenharmony_ci                        return ManagedBackendTexture::MakeWithData(dContext,
163cb93a386Sopenharmony_ci                                                                   32, 32,
164cb93a386Sopenharmony_ci                                                                   format,
165cb93a386Sopenharmony_ci                                                                   swizzledColor,
166cb93a386Sopenharmony_ci                                                                   mipMapped,
167cb93a386Sopenharmony_ci                                                                   renderable,
168cb93a386Sopenharmony_ci                                                                   GrProtected::kNo);
169cb93a386Sopenharmony_ci                    };
170cb93a386Sopenharmony_ci                    test_color_init(dContext, reporter, createWithColorMtd, combo.fColorType,
171cb93a386Sopenharmony_ci                                    combo.fColor, mipMapped, renderable);
172cb93a386Sopenharmony_ci                }
173cb93a386Sopenharmony_ci            }
174cb93a386Sopenharmony_ci        }
175cb93a386Sopenharmony_ci    }
176cb93a386Sopenharmony_ci}
177