1*c8dee2aaSAndroid Build Coastguard Worker/* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlResourceProvider.h" 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/GrContextOptions.h" 11*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/GrDirectContext.h" 12*c8dee2aaSAndroid Build Coastguard Worker#include "src/core/SkTraceEvent.h" 13*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/GrDirectContextPriv.h" 14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/GrProgramDesc.h" 15*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlCommandBuffer.h" 16*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlPipelineState.h" 18*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlUtil.h" 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker#include "src/sksl/SkSLCompiler.h" 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Worker#if !__has_feature(objc_arc) 23*c8dee2aaSAndroid Build Coastguard Worker#error This file must be compiled with Arc. Use -fobjc-arc flag 24*c8dee2aaSAndroid Build Coastguard Worker#endif 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_BEGIN 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard WorkerGrMtlResourceProvider::GrMtlResourceProvider(GrMtlGpu* gpu) 29*c8dee2aaSAndroid Build Coastguard Worker : fGpu(gpu) { 30*c8dee2aaSAndroid Build Coastguard Worker fPipelineStateCache = std::make_unique<PipelineStateCache>(gpu); 31*c8dee2aaSAndroid Build Coastguard Worker} 32*c8dee2aaSAndroid Build Coastguard Worker 33*c8dee2aaSAndroid Build Coastguard WorkerGrMtlPipelineState* GrMtlResourceProvider::findOrCreateCompatiblePipelineState( 34*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& programDesc, 35*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& programInfo, 36*c8dee2aaSAndroid Build Coastguard Worker GrThreadSafePipelineBuilder::Stats::ProgramCacheResult* stat) { 37*c8dee2aaSAndroid Build Coastguard Worker return fPipelineStateCache->refPipelineState(programDesc, programInfo, stat); 38*c8dee2aaSAndroid Build Coastguard Worker} 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Workerbool GrMtlResourceProvider::precompileShader(const SkData& key, const SkData& data) { 41*c8dee2aaSAndroid Build Coastguard Worker return fPipelineStateCache->precompileShader(key, data); 42*c8dee2aaSAndroid Build Coastguard Worker} 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker//////////////////////////////////////////////////////////////////////////////////////////////// 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard WorkerGrMtlDepthStencil* GrMtlResourceProvider::findOrCreateCompatibleDepthStencilState( 47*c8dee2aaSAndroid Build Coastguard Worker const GrStencilSettings& stencil, GrSurfaceOrigin origin) { 48*c8dee2aaSAndroid Build Coastguard Worker GrMtlDepthStencil* depthStencilState; 49*c8dee2aaSAndroid Build Coastguard Worker GrMtlDepthStencil::Key key = GrMtlDepthStencil::GenerateKey(stencil, origin); 50*c8dee2aaSAndroid Build Coastguard Worker depthStencilState = fDepthStencilStates.find(key); 51*c8dee2aaSAndroid Build Coastguard Worker if (!depthStencilState) { 52*c8dee2aaSAndroid Build Coastguard Worker depthStencilState = GrMtlDepthStencil::Create(fGpu, stencil, origin); 53*c8dee2aaSAndroid Build Coastguard Worker fDepthStencilStates.add(depthStencilState); 54*c8dee2aaSAndroid Build Coastguard Worker } 55*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(depthStencilState); 56*c8dee2aaSAndroid Build Coastguard Worker return depthStencilState; 57*c8dee2aaSAndroid Build Coastguard Worker} 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard WorkerGrMtlSampler* GrMtlResourceProvider::findOrCreateCompatibleSampler(GrSamplerState params) { 60*c8dee2aaSAndroid Build Coastguard Worker GrMtlSampler* sampler; 61*c8dee2aaSAndroid Build Coastguard Worker sampler = fSamplers.find(GrMtlSampler::GenerateKey(params)); 62*c8dee2aaSAndroid Build Coastguard Worker if (!sampler) { 63*c8dee2aaSAndroid Build Coastguard Worker sampler = GrMtlSampler::Create(fGpu, params); 64*c8dee2aaSAndroid Build Coastguard Worker fSamplers.add(sampler); 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(sampler); 67*c8dee2aaSAndroid Build Coastguard Worker return sampler; 68*c8dee2aaSAndroid Build Coastguard Worker} 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Workerconst GrMtlRenderPipeline* GrMtlResourceProvider::findOrCreateMSAALoadPipeline( 71*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat colorFormat, int sampleCount, MTLPixelFormat stencilFormat) { 72*c8dee2aaSAndroid Build Coastguard Worker if (!fMSAALoadLibrary) { 73*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia", TRACE_FUNC); 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker std::string shaderText; 76*c8dee2aaSAndroid Build Coastguard Worker shaderText.append( 77*c8dee2aaSAndroid Build Coastguard Worker "#include <metal_stdlib>\n" 78*c8dee2aaSAndroid Build Coastguard Worker "#include <simd/simd.h>\n" 79*c8dee2aaSAndroid Build Coastguard Worker "using namespace metal;\n" 80*c8dee2aaSAndroid Build Coastguard Worker "\n" 81*c8dee2aaSAndroid Build Coastguard Worker "typedef struct {\n" 82*c8dee2aaSAndroid Build Coastguard Worker " float4 position [[position]];\n" 83*c8dee2aaSAndroid Build Coastguard Worker "} VertexOutput;\n" 84*c8dee2aaSAndroid Build Coastguard Worker "\n" 85*c8dee2aaSAndroid Build Coastguard Worker "typedef struct {\n" 86*c8dee2aaSAndroid Build Coastguard Worker " float4 uPosXform;\n" 87*c8dee2aaSAndroid Build Coastguard Worker " uint2 uTextureSize;\n" 88*c8dee2aaSAndroid Build Coastguard Worker "} VertexUniforms;\n" 89*c8dee2aaSAndroid Build Coastguard Worker "\n" 90*c8dee2aaSAndroid Build Coastguard Worker "vertex VertexOutput vertexMain(constant VertexUniforms& uniforms [[buffer(0)]],\n" 91*c8dee2aaSAndroid Build Coastguard Worker " uint vertexID [[vertex_id]]) {\n" 92*c8dee2aaSAndroid Build Coastguard Worker " VertexOutput out;\n" 93*c8dee2aaSAndroid Build Coastguard Worker " float2 position = float2(float(vertexID >> 1), float(vertexID & 1));\n" 94*c8dee2aaSAndroid Build Coastguard Worker " out.position.xy = position * uniforms.uPosXform.xy + uniforms.uPosXform.zw;\n" 95*c8dee2aaSAndroid Build Coastguard Worker " out.position.zw = float2(0.0, 1.0);\n" 96*c8dee2aaSAndroid Build Coastguard Worker " return out;\n" 97*c8dee2aaSAndroid Build Coastguard Worker "}\n" 98*c8dee2aaSAndroid Build Coastguard Worker "\n" 99*c8dee2aaSAndroid Build Coastguard Worker "fragment float4 fragmentMain(VertexOutput in [[stage_in]],\n" 100*c8dee2aaSAndroid Build Coastguard Worker " texture2d<half> colorMap [[texture(0)]]) {\n" 101*c8dee2aaSAndroid Build Coastguard Worker " uint2 coords = uint2(in.position.x, in.position.y);" 102*c8dee2aaSAndroid Build Coastguard Worker " half4 colorSample = colorMap.read(coords);\n" 103*c8dee2aaSAndroid Build Coastguard Worker " return float4(colorSample);\n" 104*c8dee2aaSAndroid Build Coastguard Worker "}" 105*c8dee2aaSAndroid Build Coastguard Worker ); 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler(); 108*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadLibrary = GrCompileMtlShaderLibrary(fGpu, shaderText, errorHandler); 109*c8dee2aaSAndroid Build Coastguard Worker if (!fMSAALoadLibrary) { 110*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 111*c8dee2aaSAndroid Build Coastguard Worker } 112*c8dee2aaSAndroid Build Coastguard Worker } 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fMSAALoadPipelines.size(); ++i) { 115*c8dee2aaSAndroid Build Coastguard Worker if (fMSAALoadPipelines[i].fColorFormat == colorFormat && 116*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadPipelines[i].fSampleCount == sampleCount && 117*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadPipelines[i].fStencilFormat == stencilFormat) { 118*c8dee2aaSAndroid Build Coastguard Worker return fMSAALoadPipelines[i].fPipeline.get(); 119*c8dee2aaSAndroid Build Coastguard Worker } 120*c8dee2aaSAndroid Build Coastguard Worker } 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard Worker auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.label = @"loadMSAAFromResolve"; 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.vertexFunction = 127*c8dee2aaSAndroid Build Coastguard Worker [fMSAALoadLibrary newFunctionWithName: @"vertexMain"]; 128*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.fragmentFunction = 129*c8dee2aaSAndroid Build Coastguard Worker [fMSAALoadLibrary newFunctionWithName: @"fragmentMain"]; 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init]; 132*c8dee2aaSAndroid Build Coastguard Worker 133*c8dee2aaSAndroid Build Coastguard Worker mtlColorAttachment.pixelFormat = colorFormat; 134*c8dee2aaSAndroid Build Coastguard Worker mtlColorAttachment.blendingEnabled = FALSE; 135*c8dee2aaSAndroid Build Coastguard Worker mtlColorAttachment.writeMask = MTLColorWriteMaskAll; 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.colorAttachments[0] = mtlColorAttachment; 138*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.rasterSampleCount = sampleCount; 139*c8dee2aaSAndroid Build Coastguard Worker 140*c8dee2aaSAndroid Build Coastguard Worker pipelineDescriptor.stencilAttachmentPixelFormat = stencilFormat; 141*c8dee2aaSAndroid Build Coastguard Worker 142*c8dee2aaSAndroid Build Coastguard Worker NSError* error; 143*c8dee2aaSAndroid Build Coastguard Worker auto pso = 144*c8dee2aaSAndroid Build Coastguard Worker [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor 145*c8dee2aaSAndroid Build Coastguard Worker error: &error]; 146*c8dee2aaSAndroid Build Coastguard Worker if (!pso) { 147*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Error creating pipeline: %s\n", 148*c8dee2aaSAndroid Build Coastguard Worker [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]); 149*c8dee2aaSAndroid Build Coastguard Worker } 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker auto renderPipeline = GrMtlRenderPipeline::Make(pso); 152*c8dee2aaSAndroid Build Coastguard Worker 153*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadPipelines.push_back({renderPipeline, colorFormat, sampleCount, stencilFormat}); 154*c8dee2aaSAndroid Build Coastguard Worker return fMSAALoadPipelines[fMSAALoadPipelines.size()-1].fPipeline.get(); 155*c8dee2aaSAndroid Build Coastguard Worker} 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlResourceProvider::destroyResources() { 158*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadLibrary = nil; 159*c8dee2aaSAndroid Build Coastguard Worker fMSAALoadPipelines.clear(); 160*c8dee2aaSAndroid Build Coastguard Worker 161*c8dee2aaSAndroid Build Coastguard Worker fSamplers.foreach([&](GrMtlSampler* sampler) { sampler->unref(); }); 162*c8dee2aaSAndroid Build Coastguard Worker fSamplers.reset(); 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker fDepthStencilStates.foreach([&](GrMtlDepthStencil* stencil) { stencil->unref(); }); 165*c8dee2aaSAndroid Build Coastguard Worker fDepthStencilStates.reset(); 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker fPipelineStateCache->release(); 168*c8dee2aaSAndroid Build Coastguard Worker} 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker//////////////////////////////////////////////////////////////////////////////////////////////// 171*c8dee2aaSAndroid Build Coastguard Worker 172*c8dee2aaSAndroid Build Coastguard Workerstruct GrMtlResourceProvider::PipelineStateCache::Entry { 173*c8dee2aaSAndroid Build Coastguard Worker Entry(GrMtlPipelineState* pipelineState) 174*c8dee2aaSAndroid Build Coastguard Worker : fPipelineState(pipelineState) {} 175*c8dee2aaSAndroid Build Coastguard Worker Entry(const GrMtlPrecompiledLibraries& precompiledLibraries) 176*c8dee2aaSAndroid Build Coastguard Worker : fPipelineState(nullptr) 177*c8dee2aaSAndroid Build Coastguard Worker , fPrecompiledLibraries(precompiledLibraries) {} 178*c8dee2aaSAndroid Build Coastguard Worker 179*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrMtlPipelineState> fPipelineState; 180*c8dee2aaSAndroid Build Coastguard Worker 181*c8dee2aaSAndroid Build Coastguard Worker // TODO: change to one library once we can build that 182*c8dee2aaSAndroid Build Coastguard Worker GrMtlPrecompiledLibraries fPrecompiledLibraries; 183*c8dee2aaSAndroid Build Coastguard Worker}; 184*c8dee2aaSAndroid Build Coastguard Worker 185*c8dee2aaSAndroid Build Coastguard WorkerGrMtlResourceProvider::PipelineStateCache::PipelineStateCache(GrMtlGpu* gpu) 186*c8dee2aaSAndroid Build Coastguard Worker : fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize) 187*c8dee2aaSAndroid Build Coastguard Worker , fGpu(gpu) {} 188*c8dee2aaSAndroid Build Coastguard Worker 189*c8dee2aaSAndroid Build Coastguard WorkerGrMtlResourceProvider::PipelineStateCache::~PipelineStateCache() { 190*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0 == fMap.count()); 191*c8dee2aaSAndroid Build Coastguard Worker} 192*c8dee2aaSAndroid Build Coastguard Worker 193*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlResourceProvider::PipelineStateCache::release() { 194*c8dee2aaSAndroid Build Coastguard Worker fMap.reset(); 195*c8dee2aaSAndroid Build Coastguard Worker} 196*c8dee2aaSAndroid Build Coastguard Worker 197*c8dee2aaSAndroid Build Coastguard WorkerGrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::refPipelineState( 198*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& desc, 199*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& programInfo, 200*c8dee2aaSAndroid Build Coastguard Worker Stats::ProgramCacheResult* statPtr) { 201*c8dee2aaSAndroid Build Coastguard Worker 202*c8dee2aaSAndroid Build Coastguard Worker if (!statPtr) { 203*c8dee2aaSAndroid Build Coastguard Worker // If stat is NULL we are using inline compilation rather than through DDL, 204*c8dee2aaSAndroid Build Coastguard Worker // so we need to track those stats as well. 205*c8dee2aaSAndroid Build Coastguard Worker GrThreadSafePipelineBuilder::Stats::ProgramCacheResult stat; 206*c8dee2aaSAndroid Build Coastguard Worker auto tmp = this->onRefPipelineState(desc, programInfo, &stat); 207*c8dee2aaSAndroid Build Coastguard Worker if (!tmp) { 208*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumInlineCompilationFailures(); 209*c8dee2aaSAndroid Build Coastguard Worker } else { 210*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumInlineProgramCacheResult(stat); 211*c8dee2aaSAndroid Build Coastguard Worker } 212*c8dee2aaSAndroid Build Coastguard Worker return tmp; 213*c8dee2aaSAndroid Build Coastguard Worker } else { 214*c8dee2aaSAndroid Build Coastguard Worker return this->onRefPipelineState(desc, programInfo, statPtr); 215*c8dee2aaSAndroid Build Coastguard Worker } 216*c8dee2aaSAndroid Build Coastguard Worker} 217*c8dee2aaSAndroid Build Coastguard Worker 218*c8dee2aaSAndroid Build Coastguard WorkerGrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::onRefPipelineState( 219*c8dee2aaSAndroid Build Coastguard Worker const GrProgramDesc& desc, 220*c8dee2aaSAndroid Build Coastguard Worker const GrProgramInfo& programInfo, 221*c8dee2aaSAndroid Build Coastguard Worker Stats::ProgramCacheResult* stat) { 222*c8dee2aaSAndroid Build Coastguard Worker *stat = Stats::ProgramCacheResult::kHit; 223*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Entry>* entry = fMap.find(desc); 224*c8dee2aaSAndroid Build Coastguard Worker if (entry && !(*entry)->fPipelineState) { 225*c8dee2aaSAndroid Build Coastguard Worker // We've pre-compiled the MSL shaders but don't yet have the pipelineState 226*c8dee2aaSAndroid Build Coastguard Worker const GrMtlPrecompiledLibraries* precompiledLibs = &((*entry)->fPrecompiledLibraries); 227*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(precompiledLibs->fVertexLibrary); 228*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(precompiledLibs->fFragmentLibrary); 229*c8dee2aaSAndroid Build Coastguard Worker (*entry)->fPipelineState.reset( 230*c8dee2aaSAndroid Build Coastguard Worker GrMtlPipelineStateBuilder::CreatePipelineState(fGpu, desc, programInfo, 231*c8dee2aaSAndroid Build Coastguard Worker precompiledLibs)); 232*c8dee2aaSAndroid Build Coastguard Worker if (!(*entry)->fPipelineState) { 233*c8dee2aaSAndroid Build Coastguard Worker // Should we purge the precompiled shaders from the cache at this point? 234*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGFAIL("Couldn't create pipelineState from precompiled shaders"); 235*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumCompilationFailures(); 236*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 237*c8dee2aaSAndroid Build Coastguard Worker } 238*c8dee2aaSAndroid Build Coastguard Worker // release the libraries 239*c8dee2aaSAndroid Build Coastguard Worker (*entry)->fPrecompiledLibraries.fVertexLibrary = nil; 240*c8dee2aaSAndroid Build Coastguard Worker (*entry)->fPrecompiledLibraries.fFragmentLibrary = nil; 241*c8dee2aaSAndroid Build Coastguard Worker 242*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumPartialCompilationSuccesses(); 243*c8dee2aaSAndroid Build Coastguard Worker *stat = Stats::ProgramCacheResult::kPartial; 244*c8dee2aaSAndroid Build Coastguard Worker } else if (!entry) { 245*c8dee2aaSAndroid Build Coastguard Worker GrMtlPipelineState* pipelineState( 246*c8dee2aaSAndroid Build Coastguard Worker GrMtlPipelineStateBuilder::CreatePipelineState(fGpu, desc, programInfo)); 247*c8dee2aaSAndroid Build Coastguard Worker if (!pipelineState) { 248*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumCompilationFailures(); 249*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 250*c8dee2aaSAndroid Build Coastguard Worker } 251*c8dee2aaSAndroid Build Coastguard Worker fStats.incNumCompilationSuccesses(); 252*c8dee2aaSAndroid Build Coastguard Worker entry = fMap.insert(desc, std::make_unique<Entry>(pipelineState)); 253*c8dee2aaSAndroid Build Coastguard Worker *stat = Stats::ProgramCacheResult::kMiss; 254*c8dee2aaSAndroid Build Coastguard Worker return (*entry)->fPipelineState.get(); 255*c8dee2aaSAndroid Build Coastguard Worker } 256*c8dee2aaSAndroid Build Coastguard Worker return (*entry)->fPipelineState.get(); 257*c8dee2aaSAndroid Build Coastguard Worker} 258*c8dee2aaSAndroid Build Coastguard Worker 259*c8dee2aaSAndroid Build Coastguard Workerbool GrMtlResourceProvider::PipelineStateCache::precompileShader(const SkData& key, 260*c8dee2aaSAndroid Build Coastguard Worker const SkData& data) { 261*c8dee2aaSAndroid Build Coastguard Worker GrProgramDesc desc; 262*c8dee2aaSAndroid Build Coastguard Worker if (!GrProgramDesc::BuildFromData(&desc, key.data(), key.size())) { 263*c8dee2aaSAndroid Build Coastguard Worker return false; 264*c8dee2aaSAndroid Build Coastguard Worker } 265*c8dee2aaSAndroid Build Coastguard Worker 266*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Entry>* entry = fMap.find(desc); 267*c8dee2aaSAndroid Build Coastguard Worker if (entry) { 268*c8dee2aaSAndroid Build Coastguard Worker // We've already seen/compiled this shader 269*c8dee2aaSAndroid Build Coastguard Worker return true; 270*c8dee2aaSAndroid Build Coastguard Worker } 271*c8dee2aaSAndroid Build Coastguard Worker 272*c8dee2aaSAndroid Build Coastguard Worker GrMtlPrecompiledLibraries precompiledLibraries; 273*c8dee2aaSAndroid Build Coastguard Worker if (!GrMtlPipelineStateBuilder::PrecompileShaders(fGpu, data, &precompiledLibraries)) { 274*c8dee2aaSAndroid Build Coastguard Worker return false; 275*c8dee2aaSAndroid Build Coastguard Worker } 276*c8dee2aaSAndroid Build Coastguard Worker 277*c8dee2aaSAndroid Build Coastguard Worker fMap.insert(desc, std::make_unique<Entry>(precompiledLibraries)); 278*c8dee2aaSAndroid Build Coastguard Worker return true; 279*c8dee2aaSAndroid Build Coastguard Worker 280*c8dee2aaSAndroid Build Coastguard Worker} 281*c8dee2aaSAndroid Build Coastguard Worker 282*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_END 283