xref: /third_party/skia/src/gpu/mtl/GrMtlUtil.mm (revision cb93a386)
1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 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 "src/gpu/mtl/GrMtlUtil.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h"
11cb93a386Sopenharmony_ci#include "include/private/GrTypesPriv.h"
12cb93a386Sopenharmony_ci#include "include/private/SkMutex.h"
13cb93a386Sopenharmony_ci#include "src/core/SkTraceEvent.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrShaderUtils.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrSurface.h"
16cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlGpu.h"
17cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlRenderTarget.h"
18cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlTexture.h"
19cb93a386Sopenharmony_ci#include "src/sksl/SkSLCompiler.h"
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci#import <Metal/Metal.h>
22cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
23cb93a386Sopenharmony_ci#import <UIKit/UIApplication.h>
24cb93a386Sopenharmony_ci#endif
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci#if !__has_feature(objc_arc)
27cb93a386Sopenharmony_ci#error This file must be compiled with Arc. Use -fobjc-arc flag
28cb93a386Sopenharmony_ci#endif
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ciGR_NORETAIN_BEGIN
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ciNSError* GrCreateMtlError(NSString* description, GrMtlErrorCode errorCode) {
33cb93a386Sopenharmony_ci    NSDictionary* userInfo = [NSDictionary dictionaryWithObject:description
34cb93a386Sopenharmony_ci                                                         forKey:NSLocalizedDescriptionKey];
35cb93a386Sopenharmony_ci    return [NSError errorWithDomain:@"org.skia.ganesh"
36cb93a386Sopenharmony_ci                               code:(NSInteger)errorCode
37cb93a386Sopenharmony_ci                           userInfo:userInfo];
38cb93a386Sopenharmony_ci}
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ciMTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
41cb93a386Sopenharmony_ci    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
42cb93a386Sopenharmony_ci    texDesc.textureType = mtlTexture.textureType;
43cb93a386Sopenharmony_ci    texDesc.pixelFormat = mtlTexture.pixelFormat;
44cb93a386Sopenharmony_ci    texDesc.width = mtlTexture.width;
45cb93a386Sopenharmony_ci    texDesc.height = mtlTexture.height;
46cb93a386Sopenharmony_ci    texDesc.depth = mtlTexture.depth;
47cb93a386Sopenharmony_ci    texDesc.mipmapLevelCount = mtlTexture.mipmapLevelCount;
48cb93a386Sopenharmony_ci    texDesc.arrayLength = mtlTexture.arrayLength;
49cb93a386Sopenharmony_ci    texDesc.sampleCount = mtlTexture.sampleCount;
50cb93a386Sopenharmony_ci    if (@available(macOS 10.11, iOS 9.0, *)) {
51cb93a386Sopenharmony_ci        texDesc.usage = mtlTexture.usage;
52cb93a386Sopenharmony_ci    }
53cb93a386Sopenharmony_ci    return texDesc;
54cb93a386Sopenharmony_ci}
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci// Print the source code for all shaders generated.
57cb93a386Sopenharmony_cistatic const bool gPrintSKSL = false;
58cb93a386Sopenharmony_cistatic const bool gPrintMSL = false;
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_cibool GrSkSLToMSL(const GrMtlGpu* gpu,
61cb93a386Sopenharmony_ci                 const SkSL::String& sksl,
62cb93a386Sopenharmony_ci                 SkSL::ProgramKind programKind,
63cb93a386Sopenharmony_ci                 const SkSL::Program::Settings& settings,
64cb93a386Sopenharmony_ci                 SkSL::String* msl,
65cb93a386Sopenharmony_ci                 SkSL::Program::Inputs* outInputs,
66cb93a386Sopenharmony_ci                 GrContextOptions::ShaderErrorHandler* errorHandler) {
67cb93a386Sopenharmony_ci#ifdef SK_DEBUG
68cb93a386Sopenharmony_ci    SkSL::String src = GrShaderUtils::PrettyPrint(sksl);
69cb93a386Sopenharmony_ci#else
70cb93a386Sopenharmony_ci    const SkSL::String& src = sksl;
71cb93a386Sopenharmony_ci#endif
72cb93a386Sopenharmony_ci    SkSL::Compiler* compiler = gpu->shaderCompiler();
73cb93a386Sopenharmony_ci    std::unique_ptr<SkSL::Program> program =
74cb93a386Sopenharmony_ci            gpu->shaderCompiler()->convertProgram(programKind,
75cb93a386Sopenharmony_ci                                                  src,
76cb93a386Sopenharmony_ci                                                  settings);
77cb93a386Sopenharmony_ci    if (!program || !compiler->toMetal(*program, msl)) {
78cb93a386Sopenharmony_ci        errorHandler->compileError(src.c_str(), compiler->errorText().c_str());
79cb93a386Sopenharmony_ci        return false;
80cb93a386Sopenharmony_ci    }
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    if (gPrintSKSL || gPrintMSL) {
83cb93a386Sopenharmony_ci        GrShaderUtils::PrintShaderBanner(programKind);
84cb93a386Sopenharmony_ci        if (gPrintSKSL) {
85cb93a386Sopenharmony_ci            SkDebugf("SKSL:\n");
86cb93a386Sopenharmony_ci            GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(sksl));
87cb93a386Sopenharmony_ci        }
88cb93a386Sopenharmony_ci        if (gPrintMSL) {
89cb93a386Sopenharmony_ci            SkDebugf("MSL:\n");
90cb93a386Sopenharmony_ci            GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(*msl));
91cb93a386Sopenharmony_ci        }
92cb93a386Sopenharmony_ci    }
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci    *outInputs = program->fInputs;
95cb93a386Sopenharmony_ci    return true;
96cb93a386Sopenharmony_ci}
97cb93a386Sopenharmony_ci
98cb93a386Sopenharmony_ciid<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
99cb93a386Sopenharmony_ci                                         const SkSL::String& msl,
100cb93a386Sopenharmony_ci                                         GrContextOptions::ShaderErrorHandler* errorHandler) {
101cb93a386Sopenharmony_ci    TRACE_EVENT0("skia.shaders", "driver_compile_shader");
102cb93a386Sopenharmony_ci    auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
103cb93a386Sopenharmony_ci                                                   length:msl.size()
104cb93a386Sopenharmony_ci                                                 encoding:NSUTF8StringEncoding
105cb93a386Sopenharmony_ci                                             freeWhenDone:NO];
106cb93a386Sopenharmony_ci    MTLCompileOptions* options = [[MTLCompileOptions alloc] init];
107cb93a386Sopenharmony_ci    // array<> is supported in MSL 2.0 on MacOS 10.13+ and iOS 11+,
108cb93a386Sopenharmony_ci    // and in MSL 1.2 on iOS 10+ (but not MacOS).
109cb93a386Sopenharmony_ci    if (@available(macOS 10.13, iOS 11.0, *)) {
110cb93a386Sopenharmony_ci        options.languageVersion = MTLLanguageVersion2_0;
111cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_IOS)
112cb93a386Sopenharmony_ci    } else if (@available(macOS 10.12, iOS 10.0, *)) {
113cb93a386Sopenharmony_ci        options.languageVersion = MTLLanguageVersion1_2;
114cb93a386Sopenharmony_ci#endif
115cb93a386Sopenharmony_ci    }
116cb93a386Sopenharmony_ci    if (gpu->caps()->shaderCaps()->canUseFastMath()) {
117cb93a386Sopenharmony_ci        options.fastMathEnabled = YES;
118cb93a386Sopenharmony_ci    }
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci    NSError* error = nil;
121cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_MAC)
122cb93a386Sopenharmony_ci    id<MTLLibrary> compiledLibrary = GrMtlNewLibraryWithSource(gpu->device(), nsSource,
123cb93a386Sopenharmony_ci                                                               options, &error);
124cb93a386Sopenharmony_ci#else
125cb93a386Sopenharmony_ci    id<MTLLibrary> compiledLibrary = [gpu->device() newLibraryWithSource:nsSource
126cb93a386Sopenharmony_ci                                                                 options:options
127cb93a386Sopenharmony_ci                                                                   error:&error];
128cb93a386Sopenharmony_ci#endif
129cb93a386Sopenharmony_ci    if (!compiledLibrary) {
130cb93a386Sopenharmony_ci        errorHandler->compileError(msl.c_str(), error.debugDescription.UTF8String);
131cb93a386Sopenharmony_ci        return nil;
132cb93a386Sopenharmony_ci    }
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci    return compiledLibrary;
135cb93a386Sopenharmony_ci}
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_civoid GrPrecompileMtlShaderLibrary(const GrMtlGpu* gpu,
138cb93a386Sopenharmony_ci                                  const SkSL::String& msl) {
139cb93a386Sopenharmony_ci    auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
140cb93a386Sopenharmony_ci                                                   length:msl.size()
141cb93a386Sopenharmony_ci                                                 encoding:NSUTF8StringEncoding
142cb93a386Sopenharmony_ci                                             freeWhenDone:NO];
143cb93a386Sopenharmony_ci    // Do nothing after completion for now.
144cb93a386Sopenharmony_ci    // TODO: cache the result somewhere so we can use it later.
145cb93a386Sopenharmony_ci    MTLNewLibraryCompletionHandler completionHandler =
146cb93a386Sopenharmony_ci            ^(id<MTLLibrary> library, NSError* error) {};
147cb93a386Sopenharmony_ci    [gpu->device() newLibraryWithSource:nsSource
148cb93a386Sopenharmony_ci                                options:nil
149cb93a386Sopenharmony_ci                      completionHandler:completionHandler];
150cb93a386Sopenharmony_ci}
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_ci// Wrapper to get atomic assignment for compiles and pipeline creation
153cb93a386Sopenharmony_ciclass MtlCompileResult : public SkRefCnt {
154cb93a386Sopenharmony_cipublic:
155cb93a386Sopenharmony_ci    MtlCompileResult() : fCompiledObject(nil), fError(nil) {}
156cb93a386Sopenharmony_ci    void set(id compiledObject, NSError* error) {
157cb93a386Sopenharmony_ci        SkAutoMutexExclusive automutex(fMutex);
158cb93a386Sopenharmony_ci        fCompiledObject = compiledObject;
159cb93a386Sopenharmony_ci        fError = error;
160cb93a386Sopenharmony_ci    }
161cb93a386Sopenharmony_ci    std::pair<id, NSError*> get() {
162cb93a386Sopenharmony_ci        SkAutoMutexExclusive automutex(fMutex);
163cb93a386Sopenharmony_ci        return std::make_pair(fCompiledObject, fError);
164cb93a386Sopenharmony_ci    }
165cb93a386Sopenharmony_ciprivate:
166cb93a386Sopenharmony_ci    SkMutex fMutex;
167cb93a386Sopenharmony_ci    id fCompiledObject SK_GUARDED_BY(fMutex);
168cb93a386Sopenharmony_ci    NSError* fError SK_GUARDED_BY(fMutex);
169cb93a386Sopenharmony_ci};
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_ciid<MTLLibrary> GrMtlNewLibraryWithSource(id<MTLDevice> device, NSString* mslCode,
172cb93a386Sopenharmony_ci                                         MTLCompileOptions* options, NSError** error) {
173cb93a386Sopenharmony_ci    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
174cb93a386Sopenharmony_ci    sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
175cb93a386Sopenharmony_ci    // We have to increment the ref for the Obj-C block manually because it won't do it for us
176cb93a386Sopenharmony_ci    compileResult->ref();
177cb93a386Sopenharmony_ci    MTLNewLibraryCompletionHandler completionHandler =
178cb93a386Sopenharmony_ci            ^(id<MTLLibrary> library, NSError* compileError) {
179cb93a386Sopenharmony_ci                compileResult->set(library, compileError);
180cb93a386Sopenharmony_ci                dispatch_semaphore_signal(semaphore);
181cb93a386Sopenharmony_ci                compileResult->unref();
182cb93a386Sopenharmony_ci            };
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci    [device newLibraryWithSource: mslCode
185cb93a386Sopenharmony_ci                         options: options
186cb93a386Sopenharmony_ci               completionHandler: completionHandler];
187cb93a386Sopenharmony_ci
188cb93a386Sopenharmony_ci    // Wait 1 second for the compiler
189cb93a386Sopenharmony_ci    constexpr auto kTimeoutNS = 1000000000UL;
190cb93a386Sopenharmony_ci    if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
191cb93a386Sopenharmony_ci        if (error) {
192cb93a386Sopenharmony_ci            constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
193cb93a386Sopenharmony_ci            NSString* description =
194cb93a386Sopenharmony_ci                    [NSString stringWithFormat:@"Compilation took longer than %lu ms",
195cb93a386Sopenharmony_ci                                               kTimeoutMS];
196cb93a386Sopenharmony_ci            *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
197cb93a386Sopenharmony_ci        }
198cb93a386Sopenharmony_ci        return nil;
199cb93a386Sopenharmony_ci    }
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    id<MTLLibrary> compiledLibrary;
202cb93a386Sopenharmony_ci    std::tie(compiledLibrary, *error) = compileResult->get();
203cb93a386Sopenharmony_ci
204cb93a386Sopenharmony_ci    return compiledLibrary;
205cb93a386Sopenharmony_ci}
206cb93a386Sopenharmony_ci
207cb93a386Sopenharmony_ciid<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
208cb93a386Sopenharmony_ci        id<MTLDevice> device, MTLRenderPipelineDescriptor* pipelineDescriptor, NSError** error) {
209cb93a386Sopenharmony_ci    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
210cb93a386Sopenharmony_ci    sk_sp<MtlCompileResult> compileResult(new MtlCompileResult);
211cb93a386Sopenharmony_ci    // We have to increment the ref for the Obj-C block manually because it won't do it for us
212cb93a386Sopenharmony_ci    compileResult->ref();
213cb93a386Sopenharmony_ci    MTLNewRenderPipelineStateCompletionHandler completionHandler =
214cb93a386Sopenharmony_ci            ^(id<MTLRenderPipelineState> state, NSError* compileError) {
215cb93a386Sopenharmony_ci                compileResult->set(state, compileError);
216cb93a386Sopenharmony_ci                dispatch_semaphore_signal(semaphore);
217cb93a386Sopenharmony_ci                compileResult->unref();
218cb93a386Sopenharmony_ci            };
219cb93a386Sopenharmony_ci
220cb93a386Sopenharmony_ci    [device newRenderPipelineStateWithDescriptor: pipelineDescriptor
221cb93a386Sopenharmony_ci                               completionHandler: completionHandler];
222cb93a386Sopenharmony_ci
223cb93a386Sopenharmony_ci    // Wait 1 second for pipeline creation
224cb93a386Sopenharmony_ci    constexpr auto kTimeoutNS = 1000000000UL;
225cb93a386Sopenharmony_ci    if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, kTimeoutNS))) {
226cb93a386Sopenharmony_ci        if (error) {
227cb93a386Sopenharmony_ci            constexpr auto kTimeoutMS = kTimeoutNS/1000000UL;
228cb93a386Sopenharmony_ci            NSString* description =
229cb93a386Sopenharmony_ci                    [NSString stringWithFormat:@"Pipeline creation took longer than %lu ms",
230cb93a386Sopenharmony_ci                                               kTimeoutMS];
231cb93a386Sopenharmony_ci            *error = GrCreateMtlError(description, GrMtlErrorCode::kTimeout);
232cb93a386Sopenharmony_ci        }
233cb93a386Sopenharmony_ci        return nil;
234cb93a386Sopenharmony_ci    }
235cb93a386Sopenharmony_ci
236cb93a386Sopenharmony_ci    id<MTLRenderPipelineState> pipelineState;
237cb93a386Sopenharmony_ci    std::tie(pipelineState, *error) = compileResult->get();
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_ci    return pipelineState;
240cb93a386Sopenharmony_ci}
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ciid<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface) {
243cb93a386Sopenharmony_ci    id<MTLTexture> mtlTexture = nil;
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci    GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
246cb93a386Sopenharmony_ci    GrMtlTexture* texture;
247cb93a386Sopenharmony_ci    if (renderTarget) {
248cb93a386Sopenharmony_ci        // We should not be using this for multisampled rendertargets with a separate resolve
249cb93a386Sopenharmony_ci        // texture.
250cb93a386Sopenharmony_ci        if (renderTarget->resolveAttachment()) {
251cb93a386Sopenharmony_ci            SkASSERT(renderTarget->numSamples() > 1);
252cb93a386Sopenharmony_ci            SkASSERT(false);
253cb93a386Sopenharmony_ci            return nil;
254cb93a386Sopenharmony_ci        }
255cb93a386Sopenharmony_ci        mtlTexture = renderTarget->colorMTLTexture();
256cb93a386Sopenharmony_ci    } else {
257cb93a386Sopenharmony_ci        texture = static_cast<GrMtlTexture*>(surface->asTexture());
258cb93a386Sopenharmony_ci        if (texture) {
259cb93a386Sopenharmony_ci            mtlTexture = texture->mtlTexture();
260cb93a386Sopenharmony_ci        }
261cb93a386Sopenharmony_ci    }
262cb93a386Sopenharmony_ci    return mtlTexture;
263cb93a386Sopenharmony_ci}
264cb93a386Sopenharmony_ci
265cb93a386Sopenharmony_ci
266cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////
267cb93a386Sopenharmony_ci// CPP Utils
268cb93a386Sopenharmony_ci
269cb93a386Sopenharmony_ciGrMTLPixelFormat GrGetMTLPixelFormatFromMtlTextureInfo(const GrMtlTextureInfo& info) {
270cb93a386Sopenharmony_ci    id<MTLTexture> GR_NORETAIN mtlTexture = GrGetMTLTexture(info.fTexture.get());
271cb93a386Sopenharmony_ci    return static_cast<GrMTLPixelFormat>(mtlTexture.pixelFormat);
272cb93a386Sopenharmony_ci}
273cb93a386Sopenharmony_ci
274cb93a386Sopenharmony_ciuint32_t GrMtlFormatChannels(GrMTLPixelFormat mtlFormat) {
275cb93a386Sopenharmony_ci    switch (mtlFormat) {
276cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm:      return kRGBA_SkColorChannelFlags;
277cb93a386Sopenharmony_ci        case MTLPixelFormatR8Unorm:         return kRed_SkColorChannelFlag;
278cb93a386Sopenharmony_ci        case MTLPixelFormatA8Unorm:         return kAlpha_SkColorChannelFlag;
279cb93a386Sopenharmony_ci        case MTLPixelFormatBGRA8Unorm:      return kRGBA_SkColorChannelFlags;
280cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
281cb93a386Sopenharmony_ci        case MTLPixelFormatB5G6R5Unorm:     return kRGB_SkColorChannelFlags;
282cb93a386Sopenharmony_ci#endif
283cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Float:     return kRGBA_SkColorChannelFlags;
284cb93a386Sopenharmony_ci        case MTLPixelFormatR16Float:        return kRed_SkColorChannelFlag;
285cb93a386Sopenharmony_ci        case MTLPixelFormatRG8Unorm:        return kRG_SkColorChannelFlags;
286cb93a386Sopenharmony_ci        case MTLPixelFormatRGB10A2Unorm:    return kRGBA_SkColorChannelFlags;
287cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
288cb93a386Sopenharmony_ci        case MTLPixelFormatBGR10A2Unorm:    return kRGBA_SkColorChannelFlags;
289cb93a386Sopenharmony_ci#endif
290cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
291cb93a386Sopenharmony_ci        case MTLPixelFormatABGR4Unorm:      return kRGBA_SkColorChannelFlags;
292cb93a386Sopenharmony_ci#endif
293cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm_sRGB: return kRGBA_SkColorChannelFlags;
294cb93a386Sopenharmony_ci        case MTLPixelFormatR16Unorm:        return kRed_SkColorChannelFlag;
295cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Unorm:       return kRG_SkColorChannelFlags;
296cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
297cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8:       return kRGB_SkColorChannelFlags;
298cb93a386Sopenharmony_ci#else
299cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:        return kRGBA_SkColorChannelFlags;
300cb93a386Sopenharmony_ci#endif
301cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Unorm:     return kRGBA_SkColorChannelFlags;
302cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Float:       return kRG_SkColorChannelFlags;
303cb93a386Sopenharmony_ci        case MTLPixelFormatStencil8:        return 0;
304cb93a386Sopenharmony_ci
305cb93a386Sopenharmony_ci        default:                            return 0;
306cb93a386Sopenharmony_ci    }
307cb93a386Sopenharmony_ci}
308cb93a386Sopenharmony_ci
309cb93a386Sopenharmony_ciGrColorFormatDesc GrMtlFormatDesc(GrMTLPixelFormat mtlFormat)  {
310cb93a386Sopenharmony_ci    switch (mtlFormat) {
311cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm:
312cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
313cb93a386Sopenharmony_ci        case MTLPixelFormatR8Unorm:
314cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
315cb93a386Sopenharmony_ci        case MTLPixelFormatA8Unorm:
316cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
317cb93a386Sopenharmony_ci        case MTLPixelFormatBGRA8Unorm:
318cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
319cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
320cb93a386Sopenharmony_ci        case MTLPixelFormatB5G6R5Unorm:
321cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
322cb93a386Sopenharmony_ci#endif
323cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Float:
324cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
325cb93a386Sopenharmony_ci        case MTLPixelFormatR16Float:
326cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
327cb93a386Sopenharmony_ci        case MTLPixelFormatRG8Unorm:
328cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
329cb93a386Sopenharmony_ci        case MTLPixelFormatRGB10A2Unorm:
330cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
331cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
332cb93a386Sopenharmony_ci        case MTLPixelFormatBGR10A2Unorm:
333cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
334cb93a386Sopenharmony_ci#endif
335cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_IOS) && !TARGET_OS_SIMULATOR
336cb93a386Sopenharmony_ci        case MTLPixelFormatABGR4Unorm:
337cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
338cb93a386Sopenharmony_ci#endif
339cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm_sRGB:
340cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
341cb93a386Sopenharmony_ci        case MTLPixelFormatR16Unorm:
342cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
343cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Unorm:
344cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
345cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Unorm:
346cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
347cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Float:
348cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
349cb93a386Sopenharmony_ci
350cb93a386Sopenharmony_ci        // Compressed texture formats are not expected to have a description.
351cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
352cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8: return GrColorFormatDesc::MakeInvalid();
353cb93a386Sopenharmony_ci#else
354cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:  return GrColorFormatDesc::MakeInvalid();
355cb93a386Sopenharmony_ci#endif
356cb93a386Sopenharmony_ci
357cb93a386Sopenharmony_ci        // This type only describes color channels.
358cb93a386Sopenharmony_ci        case MTLPixelFormatStencil8: return GrColorFormatDesc::MakeInvalid();
359cb93a386Sopenharmony_ci
360cb93a386Sopenharmony_ci        default:
361cb93a386Sopenharmony_ci            return GrColorFormatDesc::MakeInvalid();
362cb93a386Sopenharmony_ci    }
363cb93a386Sopenharmony_ci}
364cb93a386Sopenharmony_ci
365cb93a386Sopenharmony_ciSkImage::CompressionType GrMtlBackendFormatToCompressionType(const GrBackendFormat& format) {
366cb93a386Sopenharmony_ci    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
367cb93a386Sopenharmony_ci    return GrMtlFormatToCompressionType(mtlFormat);
368cb93a386Sopenharmony_ci}
369cb93a386Sopenharmony_ci
370cb93a386Sopenharmony_cibool GrMtlFormatIsCompressed(MTLPixelFormat mtlFormat) {
371cb93a386Sopenharmony_ci    switch (mtlFormat) {
372cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
373cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8:
374cb93a386Sopenharmony_ci            return true;
375cb93a386Sopenharmony_ci#else
376cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:
377cb93a386Sopenharmony_ci            return true;
378cb93a386Sopenharmony_ci#endif
379cb93a386Sopenharmony_ci        default:
380cb93a386Sopenharmony_ci            return false;
381cb93a386Sopenharmony_ci    }
382cb93a386Sopenharmony_ci}
383cb93a386Sopenharmony_ci
384cb93a386Sopenharmony_ciSkImage::CompressionType GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat) {
385cb93a386Sopenharmony_ci    switch (mtlFormat) {
386cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
387cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8: return SkImage::CompressionType::kETC2_RGB8_UNORM;
388cb93a386Sopenharmony_ci#else
389cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:  return SkImage::CompressionType::kBC1_RGBA8_UNORM;
390cb93a386Sopenharmony_ci#endif
391cb93a386Sopenharmony_ci        default:                      return SkImage::CompressionType::kNone;
392cb93a386Sopenharmony_ci    }
393cb93a386Sopenharmony_ci
394cb93a386Sopenharmony_ci    SkUNREACHABLE;
395cb93a386Sopenharmony_ci}
396cb93a386Sopenharmony_ci
397cb93a386Sopenharmony_ciint GrMtlTextureInfoSampleCount(const GrMtlTextureInfo& info) {
398cb93a386Sopenharmony_ci    id<MTLTexture> texture = GrGetMTLTexture(info.fTexture.get());
399cb93a386Sopenharmony_ci    if (!texture) {
400cb93a386Sopenharmony_ci        return 0;
401cb93a386Sopenharmony_ci    }
402cb93a386Sopenharmony_ci    return texture.sampleCount;
403cb93a386Sopenharmony_ci}
404cb93a386Sopenharmony_ci
405cb93a386Sopenharmony_cisize_t GrMtlBackendFormatBytesPerBlock(const GrBackendFormat& format) {
406cb93a386Sopenharmony_ci    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
407cb93a386Sopenharmony_ci    return GrMtlFormatBytesPerBlock(mtlFormat);
408cb93a386Sopenharmony_ci}
409cb93a386Sopenharmony_ci
410cb93a386Sopenharmony_cisize_t GrMtlFormatBytesPerBlock(MTLPixelFormat mtlFormat) {
411cb93a386Sopenharmony_ci    switch (mtlFormat) {
412cb93a386Sopenharmony_ci        case MTLPixelFormatInvalid:         return 0;
413cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm:      return 4;
414cb93a386Sopenharmony_ci        case MTLPixelFormatR8Unorm:         return 1;
415cb93a386Sopenharmony_ci        case MTLPixelFormatA8Unorm:         return 1;
416cb93a386Sopenharmony_ci        case MTLPixelFormatBGRA8Unorm:      return 4;
417cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
418cb93a386Sopenharmony_ci        case MTLPixelFormatB5G6R5Unorm:     return 2;
419cb93a386Sopenharmony_ci#endif
420cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Float:     return 8;
421cb93a386Sopenharmony_ci        case MTLPixelFormatR16Float:        return 2;
422cb93a386Sopenharmony_ci        case MTLPixelFormatRG8Unorm:        return 2;
423cb93a386Sopenharmony_ci        case MTLPixelFormatRGB10A2Unorm:    return 4;
424cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
425cb93a386Sopenharmony_ci        case MTLPixelFormatBGR10A2Unorm:    return 4;
426cb93a386Sopenharmony_ci#endif
427cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
428cb93a386Sopenharmony_ci        case MTLPixelFormatABGR4Unorm:      return 2;
429cb93a386Sopenharmony_ci#endif
430cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm_sRGB: return 4;
431cb93a386Sopenharmony_ci        case MTLPixelFormatR16Unorm:        return 2;
432cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Unorm:       return 4;
433cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
434cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8:       return 8;
435cb93a386Sopenharmony_ci#else
436cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:        return 8;
437cb93a386Sopenharmony_ci#endif
438cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Unorm:     return 8;
439cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Float:       return 4;
440cb93a386Sopenharmony_ci        case MTLPixelFormatStencil8:        return 1;
441cb93a386Sopenharmony_ci
442cb93a386Sopenharmony_ci        default:                            return 0;
443cb93a386Sopenharmony_ci    }
444cb93a386Sopenharmony_ci}
445cb93a386Sopenharmony_ci
446cb93a386Sopenharmony_ciint GrMtlBackendFormatStencilBits(const GrBackendFormat& format) {
447cb93a386Sopenharmony_ci    MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
448cb93a386Sopenharmony_ci    return GrMtlFormatStencilBits(mtlFormat);
449cb93a386Sopenharmony_ci}
450cb93a386Sopenharmony_ci
451cb93a386Sopenharmony_ciint GrMtlFormatStencilBits(MTLPixelFormat mtlFormat) {
452cb93a386Sopenharmony_ci    switch(mtlFormat) {
453cb93a386Sopenharmony_ci     case MTLPixelFormatStencil8:
454cb93a386Sopenharmony_ci         return 8;
455cb93a386Sopenharmony_ci     default:
456cb93a386Sopenharmony_ci         return 0;
457cb93a386Sopenharmony_ci    }
458cb93a386Sopenharmony_ci}
459cb93a386Sopenharmony_ci
460cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
461cb93a386Sopenharmony_cibool GrMtlIsAppInBackground() {
462cb93a386Sopenharmony_ci    return [NSThread isMainThread] &&
463cb93a386Sopenharmony_ci           ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground);
464cb93a386Sopenharmony_ci}
465cb93a386Sopenharmony_ci#endif
466cb93a386Sopenharmony_ci
467cb93a386Sopenharmony_ci#if defined(SK_DEBUG) || GR_TEST_UTILS
468cb93a386Sopenharmony_cibool GrMtlFormatIsBGRA8(GrMTLPixelFormat mtlFormat) {
469cb93a386Sopenharmony_ci    return mtlFormat == MTLPixelFormatBGRA8Unorm;
470cb93a386Sopenharmony_ci}
471cb93a386Sopenharmony_ci
472cb93a386Sopenharmony_ciconst char* GrMtlFormatToStr(GrMTLPixelFormat mtlFormat) {
473cb93a386Sopenharmony_ci    switch (mtlFormat) {
474cb93a386Sopenharmony_ci        case MTLPixelFormatInvalid:         return "Invalid";
475cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm:      return "RGBA8Unorm";
476cb93a386Sopenharmony_ci        case MTLPixelFormatR8Unorm:         return "R8Unorm";
477cb93a386Sopenharmony_ci        case MTLPixelFormatA8Unorm:         return "A8Unorm";
478cb93a386Sopenharmony_ci        case MTLPixelFormatBGRA8Unorm:      return "BGRA8Unorm";
479cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
480cb93a386Sopenharmony_ci        case MTLPixelFormatB5G6R5Unorm:     return "B5G6R5Unorm";
481cb93a386Sopenharmony_ci#endif
482cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Float:     return "RGBA16Float";
483cb93a386Sopenharmony_ci        case MTLPixelFormatR16Float:        return "R16Float";
484cb93a386Sopenharmony_ci        case MTLPixelFormatRG8Unorm:        return "RG8Unorm";
485cb93a386Sopenharmony_ci        case MTLPixelFormatRGB10A2Unorm:    return "RGB10A2Unorm";
486cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
487cb93a386Sopenharmony_ci        case MTLPixelFormatBGR10A2Unorm:    return "BGR10A2Unorm";
488cb93a386Sopenharmony_ci#endif
489cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
490cb93a386Sopenharmony_ci        case MTLPixelFormatABGR4Unorm:      return "ABGR4Unorm";
491cb93a386Sopenharmony_ci#endif
492cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA8Unorm_sRGB: return "RGBA8Unorm_sRGB";
493cb93a386Sopenharmony_ci        case MTLPixelFormatR16Unorm:        return "R16Unorm";
494cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Unorm:       return "RG16Unorm";
495cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS
496cb93a386Sopenharmony_ci        case MTLPixelFormatETC2_RGB8:       return "ETC2_RGB8";
497cb93a386Sopenharmony_ci#else
498cb93a386Sopenharmony_ci        case MTLPixelFormatBC1_RGBA:        return "BC1_RGBA";
499cb93a386Sopenharmony_ci#endif
500cb93a386Sopenharmony_ci        case MTLPixelFormatRGBA16Unorm:     return "RGBA16Unorm";
501cb93a386Sopenharmony_ci        case MTLPixelFormatRG16Float:       return "RG16Float";
502cb93a386Sopenharmony_ci        case MTLPixelFormatStencil8:        return "Stencil8";
503cb93a386Sopenharmony_ci
504cb93a386Sopenharmony_ci        default:                            return "Unknown";
505cb93a386Sopenharmony_ci    }
506cb93a386Sopenharmony_ci}
507cb93a386Sopenharmony_ci
508cb93a386Sopenharmony_ci#endif
509cb93a386Sopenharmony_ci
510cb93a386Sopenharmony_ciGR_NORETAIN_END
511