Flutter Engine
The Flutter Engine
GrMtlPipelineStateBuilder.mm
Go to the documentation of this file.
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
9
22
27
28#import <simd/simd.h>
29
30#if !__has_feature(objc_arc)
31#error This file must be compiled with Arc. Use -fobjc-arc flag
32#endif
33
34GR_NORETAIN_BEGIN
35
37 GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo,
38 const GrMtlPrecompiledLibraries* precompiledLibs) {
39 GrAutoLocaleSetter als("C");
40 GrMtlPipelineStateBuilder builder(gpu, desc, programInfo);
41
42 if (!builder.emitAndInstallProcs()) {
43 return nullptr;
44 }
45 return builder.finalize(desc, programInfo, precompiledLibs);
46}
47
48GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
49 const GrProgramDesc& desc,
50 const GrProgramInfo& programInfo)
51 : INHERITED(desc, programInfo)
52 , fGpu(gpu)
53 , fUniformHandler(this)
54 , fVaryingHandler(this) {
55}
56
57const GrCaps* GrMtlPipelineStateBuilder::caps() const {
58 return fGpu->caps();
59}
60
61void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
62 outputColor.addLayoutQualifier("location = 0, index = 1");
63}
64
65static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
66static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
67
68void GrMtlPipelineStateBuilder::storeShadersInCache(const std::string shaders[],
69 const SkSL::Program::Interface interfaces[],
71 sk_sp<SkData> pipelineData,
72 bool isSkSL) {
74 this->desc().keyLength());
75 SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
76 // cache metadata to allow for a complete precompile in either case
78 meta.fSettings = settings;
79 meta.fPlatformData = std::move(pipelineData);
80 SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag;
82 kGrShaderTypeCount, &meta);
83 fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description);
84}
85
86id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
87 const std::string& shader,
90 id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
91 if (shaderLibrary != nil &&
94 }
95 return shaderLibrary;
96}
97
98static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
99 switch (type) {
101 return MTLVertexFormatFloat;
103 return MTLVertexFormatFloat2;
105 return MTLVertexFormatFloat3;
107 return MTLVertexFormatFloat4;
109 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
110 return MTLVertexFormatHalf;
111 } else {
112 return MTLVertexFormatInvalid;
113 }
115 return MTLVertexFormatHalf2;
117 return MTLVertexFormatHalf4;
119 return MTLVertexFormatInt2;
121 return MTLVertexFormatInt3;
123 return MTLVertexFormatInt4;
125 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
126 return MTLVertexFormatChar;
127 } else {
128 return MTLVertexFormatInvalid;
129 }
131 return MTLVertexFormatChar2;
133 return MTLVertexFormatChar4;
135 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
136 return MTLVertexFormatUChar;
137 } else {
138 return MTLVertexFormatInvalid;
139 }
141 return MTLVertexFormatUChar2;
143 return MTLVertexFormatUChar4;
145 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
146 return MTLVertexFormatUCharNormalized;
147 } else {
148 return MTLVertexFormatInvalid;
149 }
151 return MTLVertexFormatUChar4Normalized;
153 return MTLVertexFormatShort2;
155 return MTLVertexFormatShort4;
157 return MTLVertexFormatUShort2;
159 return MTLVertexFormatUShort2Normalized;
161 return MTLVertexFormatInt;
163 return MTLVertexFormatUInt;
165 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
166 return MTLVertexFormatUShortNormalized;
167 } else {
168 return MTLVertexFormatInvalid;
169 }
171 return MTLVertexFormatUShort4Normalized;
172 }
173 SK_ABORT("Unknown vertex attribute type");
174}
175
176static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
177 SkBinaryWriteBuffer* writer) {
178 uint32_t vertexBinding = 0, instanceBinding = 0;
179
180 int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
181 if (geomProc.hasVertexAttributes()) {
182 vertexBinding = nextBinding++;
183 }
184
185 if (geomProc.hasInstanceAttributes()) {
186 instanceBinding = nextBinding;
187 }
188 if (writer) {
189 writer->writeUInt(vertexBinding);
190 writer->writeUInt(instanceBinding);
191 }
192
193 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
194 int attributeIndex = 0;
195
196 int vertexAttributeCount = geomProc.numVertexAttributes();
197 if (writer) {
198 writer->writeInt(vertexAttributeCount);
199 }
200 for (auto attribute : geomProc.vertexAttributes()) {
201 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
202 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
203 SkASSERT(MTLVertexFormatInvalid != format);
204 mtlAttribute.format = format;
205 mtlAttribute.offset = *attribute.offset();
206 mtlAttribute.bufferIndex = vertexBinding;
207 if (writer) {
208 writer->writeInt(format);
209 writer->writeUInt(*attribute.offset());
210 writer->writeUInt(vertexBinding);
211 }
212
213 attributeIndex++;
214 }
215
216 if (vertexAttributeCount) {
217 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
218 vertexDescriptor.layouts[vertexBinding];
219 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
220 vertexBufferLayout.stepRate = 1;
221 vertexBufferLayout.stride = geomProc.vertexStride();
222 if (writer) {
223 writer->writeUInt(geomProc.vertexStride());
224 }
225 }
226
227 int instanceAttributeCount = geomProc.numInstanceAttributes();
228 if (writer) {
229 writer->writeInt(instanceAttributeCount);
230 }
231 for (auto attribute : geomProc.instanceAttributes()) {
232 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
233 MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
234 SkASSERT(MTLVertexFormatInvalid != format);
235 mtlAttribute.format = format;
236 mtlAttribute.offset = *attribute.offset();
237 mtlAttribute.bufferIndex = instanceBinding;
238 if (writer) {
239 writer->writeInt(format);
240 writer->writeUInt(*attribute.offset());
241 writer->writeUInt(instanceBinding);
242 }
243
244 attributeIndex++;
245 }
246
247 if (instanceAttributeCount) {
248 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
249 vertexDescriptor.layouts[instanceBinding];
250 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
251 instanceBufferLayout.stepRate = 1;
252 instanceBufferLayout.stride = geomProc.instanceStride();
253 if (writer) {
254 writer->writeUInt(geomProc.instanceStride());
255 }
256 }
257 return vertexDescriptor;
258}
259
260static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff) {
261 switch (coeff) {
263 return MTLBlendFactorZero;
265 return MTLBlendFactorOne;
267 return MTLBlendFactorSourceColor;
269 return MTLBlendFactorOneMinusSourceColor;
271 return MTLBlendFactorDestinationColor;
273 return MTLBlendFactorOneMinusDestinationColor;
275 return MTLBlendFactorSourceAlpha;
277 return MTLBlendFactorOneMinusSourceAlpha;
279 return MTLBlendFactorDestinationAlpha;
281 return MTLBlendFactorOneMinusDestinationAlpha;
283 return MTLBlendFactorBlendColor;
285 return MTLBlendFactorOneMinusBlendColor;
287 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
288 return MTLBlendFactorSource1Color;
289 } else {
290 return MTLBlendFactorZero;
291 }
293 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
294 return MTLBlendFactorOneMinusSource1Color;
295 } else {
296 return MTLBlendFactorZero;
297 }
299 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
300 return MTLBlendFactorSource1Alpha;
301 } else {
302 return MTLBlendFactorZero;
303 }
305 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
306 return MTLBlendFactorOneMinusSource1Alpha;
307 } else {
308 return MTLBlendFactorZero;
309 }
311 return MTLBlendFactorZero;
312 }
313
314 SK_ABORT("Unknown blend coefficient");
315}
316
317static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation) {
318 static const MTLBlendOperation gTable[] = {
319 MTLBlendOperationAdd, // skgpu::BlendEquation::kAdd
320 MTLBlendOperationSubtract, // skgpu::BlendEquation::kSubtract
321 MTLBlendOperationReverseSubtract, // skgpu::BlendEquation::kReverseSubtract
322 };
323 static_assert(std::size(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
324 static_assert(0 == (int)skgpu::BlendEquation::kAdd);
325 static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
326 static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
327
328 SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
329 return gTable[(int)equation];
330}
331
332static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
333 MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
334 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
335
336 // pixel format
337 mtlColorAttachment.pixelFormat = format;
338 if (writer) {
339 writer->writeInt(format);
340 }
341
342 // blending
343 const skgpu::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
344
345 skgpu::BlendEquation equation = blendInfo.fEquation;
346 skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
347 skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
348 bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
349
350 mtlColorAttachment.blendingEnabled = blendOn;
351 if (writer) {
352 writer->writeBool(blendOn);
353 }
354 if (blendOn) {
355 mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
356 mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
357 mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
358 mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
359 mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
360 mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
361 if (writer) {
362 writer->writeInt(mtlColorAttachment.sourceRGBBlendFactor);
363 writer->writeInt(mtlColorAttachment.destinationRGBBlendFactor);
364 writer->writeInt(mtlColorAttachment.rgbBlendOperation);
365 writer->writeInt(mtlColorAttachment.sourceAlphaBlendFactor);
366 writer->writeInt(mtlColorAttachment.destinationAlphaBlendFactor);
367 writer->writeInt(mtlColorAttachment.alphaBlendOperation);
368 }
369 }
370
371 if (blendInfo.fWritesColor) {
372 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
373 } else {
374 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
375 }
376 if (writer) {
377 writer->writeBool(blendInfo.fWritesColor);
378 }
379 return mtlColorAttachment;
380}
381
382static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
383 // Metal expects the buffer to be padded at the end according to the alignment
384 // of the largest element in the buffer.
385 uint32_t offsetDiff = offset & maxAlignment;
386 if (offsetDiff != 0) {
387 offsetDiff = maxAlignment - offsetDiff + 1;
388 }
389 return offset + offsetDiff;
390}
391
392static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
393 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
394
395#ifdef SK_ENABLE_MTL_DEBUG_INFO
396 // set label
397 {
398 SkString description;
399 reader->readString(&description);
400 pipelineDescriptor.label = @(description.c_str());
401 }
402#endif
403
404 // set up vertex descriptor
405 {
406 auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
407 uint32_t vertexBinding = reader->readUInt();
408 uint32_t instanceBinding = reader->readUInt();
409
410 int attributeIndex = 0;
411
412 // vertex attributes
413 int vertexAttributeCount = reader->readInt();
414 for (int i = 0; i < vertexAttributeCount; ++i) {
415 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
416 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
417 mtlAttribute.offset = reader->readUInt();
418 mtlAttribute.bufferIndex = reader->readUInt();
419 ++attributeIndex;
420 }
421 if (vertexAttributeCount) {
422 MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
423 vertexDescriptor.layouts[vertexBinding];
424 vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
425 vertexBufferLayout.stepRate = 1;
426 vertexBufferLayout.stride = reader->readUInt();
427 }
428
429 // instance attributes
430 int instanceAttributeCount = reader->readInt();
431 for (int i = 0; i < instanceAttributeCount; ++i) {
432 MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
433 mtlAttribute.format = (MTLVertexFormat) reader->readInt();
434 mtlAttribute.offset = reader->readUInt();
435 mtlAttribute.bufferIndex = reader->readUInt();
436 ++attributeIndex;
437 }
438 if (instanceAttributeCount) {
439 MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
440 vertexDescriptor.layouts[instanceBinding];
441 instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
442 instanceBufferLayout.stepRate = 1;
443 instanceBufferLayout.stride = reader->readUInt();
444 }
445 pipelineDescriptor.vertexDescriptor = vertexDescriptor;
446 }
447
448 // set up color attachments
449 {
450 auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
451
452 mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt();
453 mtlColorAttachment.blendingEnabled = reader->readBool();
454 if (mtlColorAttachment.blendingEnabled) {
455 mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt();
456 mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt();
457 mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt();
458 mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
459 mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
460 mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt();
461 }
462 if (reader->readBool()) {
463 mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
464 } else {
465 mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
466 }
467
468 pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
469 }
470
471 pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();
472
473 return pipelineDescriptor;
474}
475
476GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
477 const GrProgramDesc& desc, const GrProgramInfo& programInfo,
478 const GrMtlPrecompiledLibraries* precompiledLibs) {
479 TRACE_EVENT0("skia.shaders", TRACE_FUNC);
480
481 // Set up for cache if needed
482 std::unique_ptr<SkBinaryWriteBuffer> writer;
483
484 sk_sp<SkData> cached;
485 auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
486 if (persistentCache && !precompiledLibs) {
488 cached = persistentCache->load(*key);
489 }
490 if (persistentCache && !cached) {
491 writer = std::make_unique<SkBinaryWriteBuffer>(SkSerialProcs{});
492 }
493
494 // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above.
495 auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
496#ifdef SK_ENABLE_MTL_DEBUG_INFO
497 SkString description = GrProgramDesc::Describe(programInfo, *fGpu->caps());
498 int split = description.find("\n");
499 description.resize(split);
500 pipelineDescriptor.label = @(description.c_str());
501 if (writer) {
502 writer->writeString(description.c_str());
503 }
504#endif
505
506 pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
507 writer.get());
508
509 MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
510 if (pixelFormat == MTLPixelFormatInvalid) {
511 return nullptr;
512 }
513
514 pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
515 programInfo.pipeline(),
516 writer.get());
517 pipelineDescriptor.rasterSampleCount = programInfo.numSamples();
518
519 const GrMtlCaps* mtlCaps = (const GrMtlCaps*)this->caps();
520 pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
521 if (writer) {
522 writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
523 }
524 SkASSERT(pipelineDescriptor.vertexDescriptor);
525 SkASSERT(pipelineDescriptor.colorAttachments[0]);
526
527 if (precompiledLibs) {
528 SkASSERT(precompiledLibs->fVertexLibrary);
529 SkASSERT(precompiledLibs->fFragmentLibrary);
530 pipelineDescriptor.vertexFunction =
531 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
532 pipelineDescriptor.fragmentFunction =
533 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
534 SkASSERT(pipelineDescriptor.vertexFunction);
535 SkASSERT(pipelineDescriptor.fragmentFunction);
536 if (precompiledLibs->fRTFlip) {
538 }
539 } else {
540 id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];
541
542 this->finalizeShaders();
543
545 settings.fSharpenTextures = true;
546 SkASSERT(!this->fragColorIsInOut());
547
548 SkReadBuffer reader;
549 SkFourByteTag shaderType = 0;
550 if (persistentCache && cached) {
551 reader.setMemory(cached->data(), cached->size());
552 shaderType = GrPersistentCacheUtils::GetType(&reader);
553 }
554
555 auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
556 std::string msl[kGrShaderTypeCount];
558
559 // Unpack any stored shaders from the persistent cache
560 if (cached) {
561 switch (shaderType) {
562 case kMSL_Tag: {
564 &reader, msl, interfaces, kGrShaderTypeCount);
565 break;
566 }
567
568 case kSKSL_Tag: {
569 std::string cached_sksl[kGrShaderTypeCount];
571 &reader, cached_sksl, interfaces, kGrShaderTypeCount)) {
572 bool success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
573 cached_sksl[kVertex_GrShaderType],
575 settings,
577 &interfaces[kVertex_GrShaderType],
578 errorHandler);
579 success = success && skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
580 cached_sksl[kFragment_GrShaderType],
582 settings,
584 &interfaces[kFragment_GrShaderType],
585 errorHandler);
586 if (!success) {
587 return nullptr;
588 }
589 }
590 break;
591 }
592
593 default: {
594 break;
595 }
596 }
597 }
598
599 // Create any MSL shaders from pipeline data if necessary and cache
601 bool success = true;
602 if (msl[kVertex_GrShaderType].empty()) {
603 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
606 settings,
608 &interfaces[kVertex_GrShaderType],
609 errorHandler);
610 }
611 if (success && msl[kFragment_GrShaderType].empty()) {
612 success = skgpu::SkSLToMSL(mtlCaps->shaderCaps(),
615 settings,
617 &interfaces[kFragment_GrShaderType],
618 errorHandler);
619 }
620 if (!success) {
621 return nullptr;
622 }
623
624 if (persistentCache && !cached) {
625 sk_sp<SkData> pipelineData = writer->snapshotAsData();
626 if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
628 std::string sksl[kGrShaderTypeCount];
631 this->storeShadersInCache(sksl, interfaces, &settings,
632 std::move(pipelineData), true);
633 } else {
634 /*** dump pipeline data here */
635 this->storeShadersInCache(msl, interfaces, nullptr,
636 std::move(pipelineData), false);
637 }
638 }
639 }
640
641 // Compile MSL to libraries
642 shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
644 interfaces[kVertex_GrShaderType],
645 errorHandler);
646 shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
648 interfaces[kFragment_GrShaderType],
649 errorHandler);
650 if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
651 return nullptr;
652 }
653
654 pipelineDescriptor.vertexFunction =
655 [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
656 pipelineDescriptor.fragmentFunction =
657 [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];
658 }
659
660 if (pipelineDescriptor.vertexFunction == nil) {
661 SkDebugf("Couldn't find vertexMain() in library\n");
662 return nullptr;
663 }
664 if (pipelineDescriptor.fragmentFunction == nil) {
665 SkDebugf("Couldn't find fragmentMain() in library\n");
666 return nullptr;
667 }
668 SkASSERT(pipelineDescriptor.vertexFunction);
669 SkASSERT(pipelineDescriptor.fragmentFunction);
670
671 NSError* error = nil;
672 id<MTLRenderPipelineState> pipelineState;
673 {
674 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
675 if (@available(macOS 10.15, *)) {
676 pipelineState = [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
677 error: &error];
678 } else {
680 fGpu->device(), pipelineDescriptor, &error);
681 }
682 }
683 if (error) {
684 SkDebugf("Error creating pipeline: %s\n",
685 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
686 return nullptr;
687 }
688 if (!pipelineState) {
689 return nullptr;
690 }
691
692 sk_sp<GrMtlRenderPipeline> renderPipeline = GrMtlRenderPipeline::Make(pipelineState);
693
694 uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
695 fUniformHandler.fCurrentUBOMaxAlignment);
696 return new GrMtlPipelineState(fGpu,
697 std::move(renderPipeline),
698 pipelineDescriptor.colorAttachments[0].pixelFormat,
700 fUniformHandler.fUniforms,
701 bufferSize,
702 (uint32_t)fUniformHandler.numSamplers(),
703 std::move(fGPImpl),
704 std::move(fXPImpl),
705 std::move(fFPImpls));
706}
707
708//////////////////////////////////////////////////////////////////////////////
709
711 GrMtlPrecompiledLibraries* precompiledLibs) {
712 SkASSERT(precompiledLibs);
713
714 SkReadBuffer reader(cachedData.data(), cachedData.size());
716
717 auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();
718
720 settings.fSharpenTextures = true;
722 meta.fSettings = &settings;
723
724 std::string shaders[kGrShaderTypeCount];
727 &reader, shaders, interfaces, kGrShaderTypeCount, &meta)) {
728 return false;
729 }
730
731 // skip the size
732 reader.readUInt();
733 auto pipelineDescriptor = read_pipeline_data(&reader);
734 if (!reader.isValid()) {
735 return false;
736 }
737
738 switch (shaderType) {
739 case kMSL_Tag: {
740 precompiledLibs->fVertexLibrary =
741 GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
742 precompiledLibs->fFragmentLibrary =
743 GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
744 break;
745 }
746
747 case kSKSL_Tag: {
748 std::string msl[kGrShaderTypeCount];
749 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(),
750 shaders[kVertex_GrShaderType],
752 settings,
754 &interfaces[kVertex_GrShaderType],
755 errorHandler)) {
756 return false;
757 }
758 if (!skgpu::SkSLToMSL(gpu->caps()->shaderCaps(),
759 shaders[kFragment_GrShaderType],
761 settings,
763 &interfaces[kFragment_GrShaderType],
764 errorHandler)) {
765 return false;
766 }
767 precompiledLibs->fVertexLibrary =
768 GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
769 precompiledLibs->fFragmentLibrary =
770 GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
771 break;
772 }
773
774 default: {
775 return false;
776 }
777 }
778
779 pipelineDescriptor.vertexFunction =
780 [precompiledLibs->fVertexLibrary newFunctionWithName: @"vertexMain"];
781 pipelineDescriptor.fragmentFunction =
782 [precompiledLibs->fFragmentLibrary newFunctionWithName: @"fragmentMain"];
783
784 {
785 TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
786 MTLNewRenderPipelineStateCompletionHandler completionHandler =
787 ^(id<MTLRenderPipelineState> state, NSError* error) {
788 if (error) {
789 SkDebugf("Error creating pipeline: %s\n",
790 [[error localizedDescription]
791 cStringUsingEncoding: NSASCIIStringEncoding]);
792 }
793 };
794
795 // kick off asynchronous pipeline build and depend on Apple's cache to manage it
796 [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
797 completionHandler: completionHandler];
798 }
799
800 precompiledLibs->fRTFlip = (interfaces[kFragment_GrShaderType].fRTFlipUniform !=
802 return true;
803}
804
805GR_NORETAIN_END
static MTLBlendOperation blend_equation_to_mtl_blend_op(skgpu::BlendEquation equation)
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static MTLRenderPipelineColorAttachmentDescriptor * create_color_attachment(MTLPixelFormat format, const GrPipeline &pipeline, SkBinaryWriteBuffer *writer)
static MTLBlendFactor blend_coeff_to_mtl_blend(skgpu::BlendCoeff coeff)
static MTLRenderPipelineDescriptor * read_pipeline_data(SkReadBuffer *reader)
static MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type)
static MTLVertexDescriptor * create_vertex_descriptor(const GrGeometryProcessor &geomProc, SkBinaryWriteBuffer *writer)
static constexpr SkFourByteTag kMSL_Tag
static constexpr SkFourByteTag kSKSL_Tag
id< MTLRenderPipelineState > GrMtlNewRenderPipelineStateWithDescriptor(id< MTLDevice >, MTLRenderPipelineDescriptor *, NSError **)
Definition: GrMtlUtil.mm:166
static MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat &format)
Definition: GrMtlUtil.h:106
id< MTLLibrary > GrCompileMtlShaderLibrary(const GrMtlGpu *gpu, const std::string &msl, GrContextOptions::ShaderErrorHandler *errorHandler)
Definition: GrMtlUtil.mm:52
@ kFragment_GrShaderType
Definition: GrTypesPriv.h:278
@ kVertex_GrShaderType
Definition: GrTypesPriv.h:277
GrVertexAttribType
Definition: GrTypesPriv.h:312
@ kUShort_norm_GrVertexAttribType
Definition: GrTypesPriv.h:346
@ kFloat2_GrVertexAttribType
Definition: GrTypesPriv.h:314
@ kUShort2_GrVertexAttribType
Definition: GrTypesPriv.h:340
@ kUInt_GrVertexAttribType
Definition: GrTypesPriv.h:344
@ kUByte4_norm_GrVertexAttribType
Definition: GrTypesPriv.h:334
@ kUByte_GrVertexAttribType
Definition: GrTypesPriv.h:329
@ kShort2_GrVertexAttribType
Definition: GrTypesPriv.h:337
@ kUShort4_norm_GrVertexAttribType
Definition: GrTypesPriv.h:348
@ kInt_GrVertexAttribType
Definition: GrTypesPriv.h:343
@ kByte_GrVertexAttribType
Definition: GrTypesPriv.h:326
@ kByte4_GrVertexAttribType
Definition: GrTypesPriv.h:328
@ kFloat3_GrVertexAttribType
Definition: GrTypesPriv.h:315
@ kFloat_GrVertexAttribType
Definition: GrTypesPriv.h:313
@ kByte2_GrVertexAttribType
Definition: GrTypesPriv.h:327
@ kFloat4_GrVertexAttribType
Definition: GrTypesPriv.h:316
@ kShort4_GrVertexAttribType
Definition: GrTypesPriv.h:338
@ kUShort2_norm_GrVertexAttribType
Definition: GrTypesPriv.h:341
@ kInt3_GrVertexAttribType
Definition: GrTypesPriv.h:322
@ kHalf2_GrVertexAttribType
Definition: GrTypesPriv.h:318
@ kHalf4_GrVertexAttribType
Definition: GrTypesPriv.h:319
@ kUByte4_GrVertexAttribType
Definition: GrTypesPriv.h:331
@ kUByte2_GrVertexAttribType
Definition: GrTypesPriv.h:330
@ kInt4_GrVertexAttribType
Definition: GrTypesPriv.h:323
@ kUByte_norm_GrVertexAttribType
Definition: GrTypesPriv.h:333
@ kInt2_GrVertexAttribType
Definition: GrTypesPriv.h:321
@ kHalf_GrVertexAttribType
Definition: GrTypesPriv.h:317
static const int kGrShaderTypeCount
Definition: GrTypesPriv.h:282
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
#define SKSL_RTFLIP_NAME
Definition: SkSLProgram.h:19
#define TRACE_FUNC
Definition: SkTraceEvent.h:30
uint32_t SkFourByteTag
Definition: SkTypes.h:166
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition: SkTypes.h:167
GLenum type
const GrContextOptions & options() const
GrContextOptions::ShaderErrorHandler * getShaderErrorHandler() const
Definition: GrCaps.h:57
const GrShaderCaps * shaderCaps() const
Definition: GrCaps.h:63
virtual void store(const SkData &, const SkData &)
GrContextOptions::PersistentCache * getPersistentCache()
GrDirectContextPriv priv()
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
GrGLSLVertexBuilder fVS
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
GrGLSLBuiltinUniformHandles fUniformHandles
const GrProgramInfo & fProgramInfo
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
int numInstanceAttributes() const
size_t vertexStride() const
bool hasInstanceAttributes() const
const AttributeSet & vertexAttributes() const
const AttributeSet & instanceAttributes() const
size_t instanceStride() const
bool hasVertexAttributes() const
const GrCaps * caps() const
Definition: GrGpu.h:73
GrDirectContext * getContext()
Definition: GrGpu.h:67
MTLPixelFormat getStencilPixelFormat(const GrProgramDesc &desc) const
Definition: GrMtlCaps.mm:1239
id< MTLDevice > device() const
Definition: GrMtlGpu.h:49
static GrMtlPipelineState * CreatePipelineState(GrMtlGpu *, const GrProgramDesc &, const GrProgramInfo &, const GrMtlPrecompiledLibraries *precompiledLibs=nullptr)
static bool PrecompileShaders(GrMtlGpu *, const SkData &, GrMtlPrecompiledLibraries *precompiledLibs)
static sk_sp< GrMtlRenderPipeline > Make(id< MTLRenderPipelineState > pso)
Definition: GrMtlPipeline.h:20
const GrXferProcessor & getXferProcessor() const
Definition: GrPipeline.h:116
uint32_t keyLength() const
Definition: GrProgramDesc.h:40
const uint32_t * asKey() const
Definition: GrProgramDesc.h:35
static SkString Describe(const GrProgramInfo &, const GrCaps &)
int numSamples() const
Definition: GrProgramInfo.h:29
const GrPipeline & pipeline() const
Definition: GrProgramInfo.h:39
const GrGeometryProcessor & geomProc() const
Definition: GrProgramInfo.h:40
const GrBackendFormat & backendFormat() const
Definition: GrProgramInfo.h:37
void addLayoutQualifier(const char *layoutQualifier)
Definition: GrShaderVar.h:103
skgpu::BlendInfo getBlendInfo() const
void writeBool(bool value) override
void writeUInt(uint32_t value) override
void writeInt(int32_t value) override
Definition: SkData.h:25
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition: SkData.h:116
const void * data() const
Definition: SkData.h:37
size_t size() const
Definition: SkData.h:30
void setMemory(const void *, size_t)
uint32_t readUInt()
bool isValid() const
Definition: SkReadBuffer.h:208
int32_t readInt()
void readString(SkString *string)
int find(const char substring[]) const
Definition: SkString.h:158
void resize(size_t len)
Definition: SkString.cpp:374
const char * c_str() const
Definition: SkString.h:133
EMSCRIPTEN_KEEPALIVE void empty()
AtkStateType state
const uint8_t uint32_t uint32_t GError ** error
uint32_t uint32_t * format
sk_sp< SkData > PackCachedShaders(SkFourByteTag shaderType, const std::string shaders[], const SkSL::Program::Interface interfaces[], int numInterfaces, const ShaderMetadata *meta)
bool UnpackCachedShaders(SkReadBuffer *reader, std::string shaders[], SkSL::Program::Interface interfaces[], int numInterfaces, ShaderMetadata *meta)
SkFourByteTag GetType(SkReadBuffer *reader)
static bool init()
std::string PrettyPrint(const std::string &string)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
bool SkSLToMSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *msl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
Definition: MtlUtilsPriv.h:30
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition: Blend.h:145
static const int kBlendEquationCnt
Definition: Blend.h:55
BlendEquation
Definition: Blend.h:26
BlendCoeff
Definition: Blend.h:60
SeparatedVector2 offset
ShaderCacheStrategy fShaderCacheStrategy
skgpu::BlendCoeff fDstBlend
Definition: Blend.h:96
bool fWritesColor
Definition: Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition: Blend.h:95
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131