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