Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / mtl / GrMtlPipelineStateBuilder.mm
1 /*
2  * Copyright 2018 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 "src/gpu/ganesh/mtl/GrMtlPipelineStateBuilder.h"
9
10 #include "include/gpu/GrDirectContext.h"
11 #include "src/core/SkReadBuffer.h"
12 #include "src/core/SkTraceEvent.h"
13 #include "src/core/SkWriteBuffer.h"
14 #include "src/gpu/ganesh/GrAutoLocaleSetter.h"
15 #include "src/gpu/ganesh/GrDirectContextPriv.h"
16 #include "src/gpu/ganesh/GrPersistentCacheUtils.h"
17 #include "src/gpu/ganesh/GrRenderTarget.h"
18 #include "src/utils/SkShaderUtils.h"
19
20 #include "src/gpu/ganesh/mtl/GrMtlGpu.h"
21 #include "src/gpu/ganesh/mtl/GrMtlPipelineState.h"
22 #include "src/gpu/ganesh/mtl/GrMtlUtil.h"
23
24 #import <simd/simd.h>
25
26 #if !__has_feature(objc_arc)
27 #error This file must be compiled with Arc. Use -fobjc-arc flag
28 #endif
29
30 GR_NORETAIN_BEGIN
31
32 GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
33         GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo,
34         const GrMtlPrecompiledLibraries* precompiledLibs) {
35     GrAutoLocaleSetter als("C");
36     GrMtlPipelineStateBuilder builder(gpu, desc, programInfo);
37
38     if (!builder.emitAndInstallProcs()) {
39         return nullptr;
40     }
41     return builder.finalize(desc, programInfo, precompiledLibs);
42 }
43
44 GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
45                                                      const GrProgramDesc& desc,
46                                                      const GrProgramInfo& programInfo)
47         : INHERITED(desc, programInfo)
48         , fGpu(gpu)
49         , fUniformHandler(this)
50         , fVaryingHandler(this) {
51 }
52
53 const GrCaps* GrMtlPipelineStateBuilder::caps() const {
54     return fGpu->caps();
55 }
56
57 SkSL::Compiler* GrMtlPipelineStateBuilder::shaderCompiler() const {
58     return fGpu->shaderCompiler();
59 }
60
61 void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
62     outputColor.addLayoutQualifier("location = 0, index = 0");
63 }
64
65 void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
66     outputColor.addLayoutQualifier("location = 0, index = 1");
67 }
68
69 static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
70 static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
71
72 void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[],
73                                                     const SkSL::Program::Inputs inputs[],
74                                                     SkSL::Program::Settings* settings,
75                                                     sk_sp<SkData> pipelineData,
76                                                     bool isSkSL) {
77     sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(),
78                                                 this->desc().keyLength());
79     SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
80     // cache metadata to allow for a complete precompile in either case
81     GrPersistentCacheUtils::ShaderMetadata meta;
82     meta.fSettings = settings;
83     meta.fPlatformData = std::move(pipelineData);
84     SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag;
85     sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(tag, shaders, inputs,
86                                                                    kGrShaderTypeCount, &meta);
87     fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description);
88 }
89
90 id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
91         const std::string& shader, SkSL::Program::Inputs inputs,
92         GrContextOptions::ShaderErrorHandler* errorHandler) {
93     id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
94     if (shaderLibrary != nil && inputs.fUseFlipRTUniform) {
95         this->addRTFlipUniform(SKSL_RTFLIP_NAME);
96     }
97     return shaderLibrary;
98 }
99
100 static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
101     switch (type) {
102         case kFloat_GrVertexAttribType:
103             return MTLVertexFormatFloat;
104         case kFloat2_GrVertexAttribType:
105             return MTLVertexFormatFloat2;
106         case kFloat3_GrVertexAttribType:
107             return MTLVertexFormatFloat3;
108         case kFloat4_GrVertexAttribType:
109             return MTLVertexFormatFloat4;
110         case kHalf_GrVertexAttribType:
111             if (@available(macOS 10.13, iOS 11.0, *)) {
112                 return MTLVertexFormatHalf;
113             } else {
114                 return MTLVertexFormatInvalid;
115             }
116         case kHalf2_GrVertexAttribType:
117             return MTLVertexFormatHalf2;
118         case kHalf4_GrVertexAttribType:
119             return MTLVertexFormatHalf4;
120         case kInt2_GrVertexAttribType:
121             return MTLVertexFormatInt2;
122         case kInt3_GrVertexAttribType:
123             return MTLVertexFormatInt3;
124         case kInt4_GrVertexAttribType:
125             return MTLVertexFormatInt4;
126         case kByte_GrVertexAttribType:
127             if (@available(macOS 10.13, iOS 11.0, *)) {
128                 return MTLVertexFormatChar;
129             } else {
130                 return MTLVertexFormatInvalid;
131             }
132         case kByte2_GrVertexAttribType:
133             return MTLVertexFormatChar2;
134         case kByte4_GrVertexAttribType:
135             return MTLVertexFormatChar4;
136         case kUByte_GrVertexAttribType:
137             if (@available(macOS 10.13, iOS 11.0, *)) {
138                 return MTLVertexFormatUChar;
139             } else {
140                 return MTLVertexFormatInvalid;
141             }
142         case kUByte2_GrVertexAttribType:
143             return MTLVertexFormatUChar2;
144         case kUByte4_GrVertexAttribType:
145             return MTLVertexFormatUChar4;
146         case kUByte_norm_GrVertexAttribType:
147             if (@available(macOS 10.13, iOS 11.0, *)) {
148                 return MTLVertexFormatUCharNormalized;
149             } else {
150                 return MTLVertexFormatInvalid;
151             }
152         case kUByte4_norm_GrVertexAttribType:
153             return MTLVertexFormatUChar4Normalized;
154         case kShort2_GrVertexAttribType:
155             return MTLVertexFormatShort2;
156         case kShort4_GrVertexAttribType:
157             return MTLVertexFormatShort4;
158         case kUShort2_GrVertexAttribType:
159             return MTLVertexFormatUShort2;
160         case kUShort2_norm_GrVertexAttribType:
161             return MTLVertexFormatUShort2Normalized;
162         case kInt_GrVertexAttribType:
163             return MTLVertexFormatInt;
164         case kUInt_GrVertexAttribType:
165             return MTLVertexFormatUInt;
166         case kUShort_norm_GrVertexAttribType:
167             if (@available(macOS 10.13, iOS 11.0, *)) {
168                 return MTLVertexFormatUShortNormalized;
169             } else {
170                 return MTLVertexFormatInvalid;
171             }
172         case kUShort4_norm_GrVertexAttribType:
173             return MTLVertexFormatUShort4Normalized;
174     }
175     SK_ABORT("Unknown vertex attribute type");
176 }
177
178 static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
179                                                      SkBinaryWriteBuffer* writer) {
180     uint32_t vertexBinding = 0, instanceBinding = 0;
181
182     int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
183     if (geomProc.hasVertexAttributes()) {
184         vertexBinding = nextBinding++;
185     }
186
187     if (geomProc.hasInstanceAttributes()) {
188         instanceBinding = nextBinding;
189     }
190     if (writer) {
191         writer->writeUInt(vertexBinding);
192         writer->writeUInt(instanceBinding);
193     }
194
195     auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
196     int attributeIndex = 0;
197
198     int vertexAttributeCount = geomProc.numVertexAttributes();
199     if (writer) {
200         writer->writeInt(vertexAttributeCount);
201     }
202     for (auto attribute : geomProc.vertexAttributes()) {
203         MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
204         MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
205         SkASSERT(MTLVertexFormatInvalid != format);
206         mtlAttribute.format = format;
207         mtlAttribute.offset = *attribute.offset();
208         mtlAttribute.bufferIndex = vertexBinding;
209         if (writer) {
210             writer->writeInt(format);
211             writer->writeUInt(*attribute.offset());
212             writer->writeUInt(vertexBinding);
213         }
214
215         attributeIndex++;
216     }
217
218     if (vertexAttributeCount) {
219         MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
220                 vertexDescriptor.layouts[vertexBinding];
221         vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
222         vertexBufferLayout.stepRate = 1;
223         vertexBufferLayout.stride = geomProc.vertexStride();
224         if (writer) {
225             writer->writeUInt(geomProc.vertexStride());
226         }
227     }
228
229     int instanceAttributeCount = geomProc.numInstanceAttributes();
230     if (writer) {
231         writer->writeInt(instanceAttributeCount);
232     }
233     for (auto attribute : geomProc.instanceAttributes()) {
234         MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
235         MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
236         SkASSERT(MTLVertexFormatInvalid != format);
237         mtlAttribute.format = format;
238         mtlAttribute.offset = *attribute.offset();
239         mtlAttribute.bufferIndex = instanceBinding;
240         if (writer) {
241             writer->writeInt(format);
242             writer->writeUInt(*attribute.offset());
243             writer->writeUInt(instanceBinding);
244         }
245
246         attributeIndex++;
247     }
248
249     if (instanceAttributeCount) {
250         MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
251                 vertexDescriptor.layouts[instanceBinding];
252         instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
253         instanceBufferLayout.stepRate = 1;
254         instanceBufferLayout.stride = geomProc.instanceStride();
255         if (writer) {
256             writer->writeUInt(geomProc.instanceStride());
257         }
258     }
259     return vertexDescriptor;
260 }
261
262 static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff) {
263     switch (coeff) {
264         case skgpu::BlendCoeff::kZero:
265             return MTLBlendFactorZero;
266         case skgpu::BlendCoeff::kOne:
267             return MTLBlendFactorOne;
268         case skgpu::BlendCoeff::kSC:
269             return MTLBlendFactorSourceColor;
270         case skgpu::BlendCoeff::kISC:
271             return MTLBlendFactorOneMinusSourceColor;
272         case skgpu::BlendCoeff::kDC:
273             return MTLBlendFactorDestinationColor;
274         case skgpu::BlendCoeff::kIDC:
275             return MTLBlendFactorOneMinusDestinationColor;
276         case skgpu::BlendCoeff::kSA:
277             return MTLBlendFactorSourceAlpha;
278         case skgpu::BlendCoeff::kISA:
279             return MTLBlendFactorOneMinusSourceAlpha;
280         case skgpu::BlendCoeff::kDA:
281             return MTLBlendFactorDestinationAlpha;
282         case skgpu::BlendCoeff::kIDA:
283             return MTLBlendFactorOneMinusDestinationAlpha;
284         case skgpu::BlendCoeff::kConstC:
285             return MTLBlendFactorBlendColor;
286         case skgpu::BlendCoeff::kIConstC:
287             return MTLBlendFactorOneMinusBlendColor;
288         case skgpu::BlendCoeff::kS2C:
289             if (@available(macOS 10.12, iOS 11.0, *)) {
290                 return MTLBlendFactorSource1Color;
291             } else {
292                 return MTLBlendFactorZero;
293             }
294         case skgpu::BlendCoeff::kIS2C:
295             if (@available(macOS 10.12, iOS 11.0, *)) {
296                 return MTLBlendFactorOneMinusSource1Color;
297             } else {
298                 return MTLBlendFactorZero;
299             }
300         case skgpu::BlendCoeff::kS2A:
301             if (@available(macOS 10.12, iOS 11.0, *)) {
302                 return MTLBlendFactorSource1Alpha;
303             } else {
304                 return MTLBlendFactorZero;
305             }
306         case skgpu::BlendCoeff::kIS2A:
307             if (@available(macOS 10.12, iOS 11.0, *)) {
308                 return MTLBlendFactorOneMinusSource1Alpha;
309             } else {
310                 return MTLBlendFactorZero;
311             }
312         case skgpu::BlendCoeff::kIllegal:
313             return MTLBlendFactorZero;
314     }
315
316     SK_ABORT("Unknown blend coefficient");
317 }
318
319 static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation) {
320     static const MTLBlendOperation gTable[] = {
321         MTLBlendOperationAdd,              // skgpu::BlendEquation::kAdd
322         MTLBlendOperationSubtract,         // skgpu::BlendEquation::kSubtract
323         MTLBlendOperationReverseSubtract,  // skgpu::BlendEquation::kReverseSubtract
324     };
325     static_assert(SK_ARRAY_COUNT(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
326     static_assert(0 == (int)skgpu::BlendEquation::kAdd);
327     static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
328     static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
329
330     SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
331     return gTable[(int)equation];
332 }
333
334 static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
335         MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
336     auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
337
338     // pixel format
339     mtlColorAttachment.pixelFormat = format;
340     if (writer) {
341         writer->writeInt(format);
342     }
343
344     // blending
345     const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
346
347     skgpu::BlendEquation equation = blendInfo.fEquation;
348     skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
349     skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
350     bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
351
352     mtlColorAttachment.blendingEnabled = blendOn;
353     if (writer) {
354         writer->writeBool(blendOn);
355     }
356     if (blendOn) {
357         mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
358         mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
359         mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
360         mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
361         mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
362         mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
363         if (writer) {
364             writer->writeInt(mtlColorAttachment.sourceRGBBlendFactor);
365             writer->writeInt(mtlColorAttachment.destinationRGBBlendFactor);
366             writer->writeInt(mtlColorAttachment.rgbBlendOperation);
367             writer->writeInt(mtlColorAttachment.sourceAlphaBlendFactor);
368             writer->writeInt(mtlColorAttachment.destinationAlphaBlendFactor);
369             writer->writeInt(mtlColorAttachment.alphaBlendOperation);
370         }
371     }
372
373     if (blendInfo.fWriteColor) {
374         mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
375     } else {
376         mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
377     }
378     if (writer) {
379         writer->writeBool(blendInfo.fWriteColor);
380     }
381     return mtlColorAttachment;
382 }
383
384 static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
385     // Metal expects the buffer to be padded at the end according to the alignment
386     // of the largest element in the buffer.
387     uint32_t offsetDiff = offset & maxAlignment;
388     if (offsetDiff != 0) {
389         offsetDiff = maxAlignment - offsetDiff + 1;
390     }
391     return offset + offsetDiff;
392 }
393
394 static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
395     auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
396
397 #ifdef SK_ENABLE_MTL_DEBUG_INFO
398     // set label
399     {
400         SkString description;
401         reader->readString(&description);
402         pipelineDescriptor.label = @(description.c_str());
403     }
404 #endif
405
406     // set up vertex descriptor
407     {
408         auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
409         uint32_t vertexBinding = reader->readUInt();
410         uint32_t instanceBinding = reader->readUInt();
411
412         int attributeIndex = 0;
413
414         // vertex attributes
415         int vertexAttributeCount = reader->readInt();
416         for (int i = 0; i < vertexAttributeCount; ++i) {
417             MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
418             mtlAttribute.format = (MTLVertexFormat) reader->readInt();
419             mtlAttribute.offset = reader->readUInt();
420             mtlAttribute.bufferIndex = reader->readUInt();
421             ++attributeIndex;
422         }
423         if (vertexAttributeCount) {
424             MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
425                     vertexDescriptor.layouts[vertexBinding];
426             vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
427             vertexBufferLayout.stepRate = 1;
428             vertexBufferLayout.stride = reader->readUInt();
429         }
430
431         // instance attributes
432         int instanceAttributeCount = reader->readInt();
433         for (int i = 0; i < instanceAttributeCount; ++i) {
434             MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
435             mtlAttribute.format = (MTLVertexFormat) reader->readInt();
436             mtlAttribute.offset = reader->readUInt();
437             mtlAttribute.bufferIndex = reader->readUInt();
438             ++attributeIndex;
439         }
440         if (instanceAttributeCount) {
441             MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
442                     vertexDescriptor.layouts[instanceBinding];
443             instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
444             instanceBufferLayout.stepRate = 1;
445             instanceBufferLayout.stride = reader->readUInt();
446         }
447         pipelineDescriptor.vertexDescriptor = vertexDescriptor;
448     }
449
450     // set up color attachments
451     {
452         auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
453
454         mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt();
455         mtlColorAttachment.blendingEnabled = reader->readBool();
456         if (mtlColorAttachment.blendingEnabled) {
457             mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt();
458             mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt();
459             mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt();
460             mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
461             mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
462             mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt();
463         }
464         if (reader->readBool()) {
465             mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
466         } else {
467             mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
468         }
469
470         pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
471     }
472
473     pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();
474
475     return pipelineDescriptor;
476 }
477
478 GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
479         const GrProgramDesc& desc, const GrProgramInfo& programInfo,
480         const GrMtlPrecompiledLibraries* precompiledLibs) {
481     TRACE_EVENT0("skia.shaders", TRACE_FUNC);
482
483     // Set up for cache if needed
484     std::unique_ptr<SkBinaryWriteBuffer> writer;
485
486     sk_sp<SkData> cached;
487     auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
488     if (persistentCache && !precompiledLibs) {
489         sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.keyLength());
490         cached = persistentCache->load(*key);
491     }
492     if (persistentCache && !cached) {
493         writer.reset(new SkBinaryWriteBuffer());
494     }
495
496     // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above.
497     auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
498 #ifdef SK_ENABLE_MTL_DEBUG_INFO
499     SkString description = GrProgramDesc::Describe(programInfo, *fGpu->caps());
500     int split = description.find("\n");
501     description.resize(split);
502     pipelineDescriptor.label = @(description.c_str());
503     if (writer) {
504         writer->writeString(description.c_str());
505     }
506 #endif
507
508     pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
509                                                                    writer.get());
510
511     MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
512     if (pixelFormat == MTLPixelFormatInvalid) {
513         return nullptr;
514     }
515
516     pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
517                                                                      programInfo.pipeline(),
518                                                                      writer.get());
519     pipelineDescriptor.sampleCount = programInfo.numSamples();
520     GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
521     pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
522     if (writer) {
523         writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
524     }
525     SkASSERT(pipelineDescriptor.vertexDescriptor);
526     SkASSERT(pipelineDescriptor.colorAttachments[0]);
527
528     if (precompiledLibs) {
529         SkASSERT(precompiledLibs->fVertexLibrary);
530         SkASSERT(precompiledLibs->fFragmentLibrary);
531         pipelineDescriptor.vertexFunction =
532                 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
533         pipelineDescriptor.fragmentFunction =
534                 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
535         SkASSERT(pipelineDescriptor.vertexFunction);
536         SkASSERT(pipelineDescriptor.fragmentFunction);
537         if (precompiledLibs->fRTFlip) {
538             this->addRTFlipUniform(SKSL_RTFLIP_NAME);
539         }
540     } else {
541         id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
542
543         this->finalizeShaders();
544
545         SkSL::Program::Settings settings;
546         settings.fSharpenTextures = true;
547         SkASSERT(!this->fragColorIsInOut());
548
549         SkReadBuffer reader;
550         SkFourByteTag shaderType = 0;
551         if (persistentCache && cached) {
552             reader.setMemory(cached->data(), cached->size());
553             shaderType = GrPersistentCacheUtils::GetType(&reader);
554         }
555
556         auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
557         std::string msl[kGrShaderTypeCount];
558         SkSL::Program::Inputs inputs[kGrShaderTypeCount];
559
560         // Unpack any stored shaders from the persistent cache
561         if (cached) {
562             switch (shaderType) {
563                 case kMSL_Tag: {
564                     GrPersistentCacheUtils::UnpackCachedShaders(&reader, msl, inputs,
565                                                                 kGrShaderTypeCount);
566                     break;
567                 }
568
569                 case kSKSL_Tag: {
570                     std::string cached_sksl[kGrShaderTypeCount];
571                     if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs,
572                                                                     kGrShaderTypeCount)) {
573                         bool success = GrSkSLToMSL(fGpu,
574                                                    cached_sksl[kVertex_GrShaderType],
575                                                    SkSL::ProgramKind::kVertex,
576                                                    settings,
577                                                    &msl[kVertex_GrShaderType],
578                                                    &inputs[kVertex_GrShaderType],
579                                                    errorHandler);
580                         success = success && GrSkSLToMSL(fGpu,
581                                                          cached_sksl[kFragment_GrShaderType],
582                                                          SkSL::ProgramKind::kFragment,
583                                                          settings,
584                                                          &msl[kFragment_GrShaderType],
585                                                          &inputs[kFragment_GrShaderType],
586                                                          errorHandler);
587                         if (!success) {
588                             return nullptr;
589                         }
590                     }
591                     break;
592                 }
593
594                 default: {
595                     break;
596                 }
597             }
598         }
599
600         // Create any MSL shaders from pipeline data if necessary and cache
601         if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) {
602             bool success = true;
603             if (msl[kVertex_GrShaderType].empty()) {
604                 success = GrSkSLToMSL(fGpu,
605                                       fVS.fCompilerString,
606                                       SkSL::ProgramKind::kVertex,
607                                       settings,
608                                       &msl[kVertex_GrShaderType],
609                                       &inputs[kVertex_GrShaderType],
610                                       errorHandler);
611             }
612             if (success && msl[kFragment_GrShaderType].empty()) {
613                 success = GrSkSLToMSL(fGpu,
614                                       fFS.fCompilerString,
615                                       SkSL::ProgramKind::kFragment,
616                                       settings,
617                                       &msl[kFragment_GrShaderType],
618                                       &inputs[kFragment_GrShaderType],
619                                       errorHandler);
620             }
621             if (!success) {
622                 return nullptr;
623             }
624
625             if (persistentCache && !cached) {
626                 sk_sp<SkData> pipelineData = writer->snapshotAsData();
627                 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
628                         GrContextOptions::ShaderCacheStrategy::kSkSL) {
629                     std::string sksl[kGrShaderTypeCount];
630                     sksl[kVertex_GrShaderType] = SkShaderUtils::PrettyPrint(fVS.fCompilerString);
631                     sksl[kFragment_GrShaderType] = SkShaderUtils::PrettyPrint(fFS.fCompilerString);
632                     this->storeShadersInCache(sksl, inputs, &settings,
633                                               std::move(pipelineData), true);
634                 } else {
635                     /*** dump pipeline data here */
636                     this->storeShadersInCache(msl, inputs, nullptr,
637                                               std::move(pipelineData), false);
638                 }
639             }
640         }
641
642         // Compile MSL to libraries
643         shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
644                                                         msl[kVertex_GrShaderType],
645                                                         inputs[kVertex_GrShaderType],
646                                                         errorHandler);
647         shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
648                                                         msl[kFragment_GrShaderType],
649                                                         inputs[kFragment_GrShaderType],
650                                                         errorHandler);
651         if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
652             return nullptr;
653         }
654
655         pipelineDescriptor.vertexFunction =
656                 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
657         pipelineDescriptor.fragmentFunction =
658                 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
659     }
660
661     if (pipelineDescriptor.vertexFunction == nil) {
662         SkDebugf("Couldn't find vertexMain() in library\n");
663         return nullptr;
664     }
665     if (pipelineDescriptor.fragmentFunction == nil) {
666         SkDebugf("Couldn't find fragmentMain() in library\n");
667         return nullptr;
668     }
669     SkASSERT(pipelineDescriptor.vertexFunction);
670     SkASSERT(pipelineDescriptor.fragmentFunction);
671
672     NSError* error = nil;
673 #if GR_METAL_SDK_VERSION >= 230
674     if (@available(macOS 11.0, iOS 14.0, *)) {
675         id<MTLBinaryArchive> archive = fGpu->binaryArchive();
676         if (archive) {
677             NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
678             pipelineDescriptor.binaryArchives = archiveArray;
679             BOOL result;
680             {
681                 TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
682                 result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
683                                                                             error: &error];
684             }
685             if (!result && error) {
686                 SkDebugf("Error storing pipeline: %s\n",
687                         [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
688             }
689         }
690     }
691 #endif
692
693     id<MTLRenderPipelineState> pipelineState;
694     {
695         TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
696 #if defined(SK_BUILD_FOR_MAC)
697         pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
698                                                      fGpu->device(), pipelineDescriptor, &error);
699 #else
700         pipelineState =
701             [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
702                                                            error: &error];
703 #endif
704     }
705     if (error) {
706         SkDebugf("Error creating pipeline: %s\n",
707                  [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
708         return nullptr;
709     }
710     if (!pipelineState) {
711         return nullptr;
712     }
713
714     sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState);
715
716     uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
717                                       fUniformHandler.fCurrentUBOMaxAlignment);
718     return new GrMtlPipelineState(fGpu,
719                                   std::move(renderPipeline),
720                                   pipelineDescriptor.colorAttachments[0].pixelFormat,
721                                   fUniformHandles,
722                                   fUniformHandler.fUniforms,
723                                   bufferSize,
724                                   (uint32_t)fUniformHandler.numSamplers(),
725                                   std::move(fGPImpl),
726                                   std::move(fXPImpl),
727                                   std::move(fFPImpls));
728 }
729
730 //////////////////////////////////////////////////////////////////////////////
731
732 bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData,
733                                                   GrMtlPrecompiledLibraries* precompiledLibs) {
734     SkASSERT(precompiledLibs);
735
736     SkReadBuffer reader(cachedData.data(), cachedData.size());
737     SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);
738
739     auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();
740
741     SkSL::Program::Settings settings;
742     settings.fSharpenTextures = true;
743     GrPersistentCacheUtils::ShaderMetadata meta;
744     meta.fSettings = &settings;
745
746     std::string shaders[kGrShaderTypeCount];
747     SkSL::Program::Inputs inputs[kGrShaderTypeCount];
748     if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount,
749                                                      &meta)) {
750         return false;
751     }
752
753     // skip the size
754     reader.readUInt();
755     auto pipelineDescriptor = read_pipeline_data(&reader);
756     if (!reader.isValid()) {
757         return false;
758     }
759
760     switch (shaderType) {
761         case kMSL_Tag: {
762             precompiledLibs->fVertexLibrary =
763                     GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
764             precompiledLibs->fFragmentLibrary =
765                     GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
766             break;
767         }
768
769         case kSKSL_Tag: {
770             std::string msl[kGrShaderTypeCount];
771             if (!GrSkSLToMSL(gpu,
772                            shaders[kVertex_GrShaderType],
773                            SkSL::ProgramKind::kVertex,
774                            settings,
775                            &msl[kVertex_GrShaderType],
776                            &inputs[kVertex_GrShaderType],
777                            errorHandler)) {
778                 return false;
779             }
780             if (!GrSkSLToMSL(gpu,
781                            shaders[kFragment_GrShaderType],
782                            SkSL::ProgramKind::kFragment,
783                            settings,
784                            &msl[kFragment_GrShaderType],
785                            &inputs[kFragment_GrShaderType],
786                            errorHandler)) {
787                 return false;
788             }
789             precompiledLibs->fVertexLibrary =
790                     GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
791             precompiledLibs->fFragmentLibrary =
792                     GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
793             break;
794         }
795
796         default: {
797             return false;
798         }
799     }
800
801     pipelineDescriptor.vertexFunction =
802             [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
803     pipelineDescriptor.fragmentFunction =
804             [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
805
806 #if GR_METAL_SDK_VERSION >= 230
807     if (@available(macOS 11.0, iOS 14.0, *)) {
808         id<MTLBinaryArchive> archive = gpu->binaryArchive();
809         if (archive) {
810             NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
811             pipelineDescriptor.binaryArchives = archiveArray;
812             BOOL result;
813             NSError* error = nil;
814             {
815                 TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
816                 result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
817                                                                             error: &error];
818             }
819             if (!result && error) {
820                 SkDebugf("Error storing pipeline: %s\n",
821                         [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
822             }
823         }
824     }
825 #endif
826     {
827         TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
828         MTLNewRenderPipelineStateCompletionHandler completionHandler =
829                  ^(id<MTLRenderPipelineState> state, NSError* error) {
830                      if (error) {
831                          SkDebugf("Error creating pipeline: %s\n",
832                                   [[error localizedDescription]
833                                            cStringUsingEncoding: NSASCIIStringEncoding]);
834                      }
835                  };
836
837         // kick off asynchronous pipeline build and depend on Apple's cache to manage it
838         [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
839                                           completionHandler: completionHandler];
840     }
841
842     precompiledLibs->fRTFlip = inputs[kFragment_GrShaderType].fUseFlipRTUniform;
843     return true;
844 }
845
846 GR_NORETAIN_END