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