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