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