/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"

#include "include/gpu/GrDirectContext.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkWriteBuffer.h"
#include "src/gpu/GrAutoLocaleSetter.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrPersistentCacheUtils.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrShaderUtils.h"

#include "src/gpu/mtl/GrMtlGpu.h"
#include "src/gpu/mtl/GrMtlPipelineState.h"
#include "src/gpu/mtl/GrMtlUtil.h"

#import <simd/simd.h>

#if !__has_feature(objc_arc)
#error This file must be compiled with Arc. Use -fobjc-arc flag
#endif

GR_NORETAIN_BEGIN

GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
        GrMtlGpu* gpu, const GrProgramDesc& desc, const GrProgramInfo& programInfo,
        const GrMtlPrecompiledLibraries* precompiledLibs) {
    GrAutoLocaleSetter als("C");
    GrMtlPipelineStateBuilder builder(gpu, desc, programInfo);

    if (!builder.emitAndInstallProcs()) {
        return nullptr;
    }
    return builder.finalize(desc, programInfo, precompiledLibs);
}

GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
                                                     const GrProgramDesc& desc,
                                                     const GrProgramInfo& programInfo)
        : INHERITED(nullptr, desc, programInfo)
        , fGpu(gpu)
        , fUniformHandler(this)
        , fVaryingHandler(this) {
}

const GrCaps* GrMtlPipelineStateBuilder::caps() const {
    return fGpu->caps();
}

SkSL::Compiler* GrMtlPipelineStateBuilder::shaderCompiler() const {
    return fGpu->shaderCompiler();
}

void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 0");
}

void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
    outputColor.addLayoutQualifier("location = 0, index = 1");
}

static constexpr SkFourByteTag kMSL_Tag = SkSetFourByteTag('M', 'S', 'L', ' ');
static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');

void GrMtlPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
                                                    const SkSL::Program::Inputs inputs[],
                                                    SkSL::Program::Settings* settings,
                                                    sk_sp<SkData> pipelineData,
                                                    bool isSkSL) {
    sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(),
                                                this->desc().keyLength());
    SkString description = GrProgramDesc::Describe(fProgramInfo, *this->caps());
    // cache metadata to allow for a complete precompile in either case
    GrPersistentCacheUtils::ShaderMetadata meta;
    meta.fSettings = settings;
    meta.fPlatformData = std::move(pipelineData);
    SkFourByteTag tag = isSkSL ? kSKSL_Tag : kMSL_Tag;
    sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(tag, shaders, inputs,
                                                                   kGrShaderTypeCount, &meta);
    fGpu->getContext()->priv().getPersistentCache()->store(*key, *data, description);
}

id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
        const SkSL::String& shader, SkSL::Program::Inputs inputs,
        GrContextOptions::ShaderErrorHandler* errorHandler) {
    id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
    if (shaderLibrary != nil && inputs.fRTHeight) {
        this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
    }
    return shaderLibrary;
}

static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
    switch (type) {
        case kFloat_GrVertexAttribType:
            return MTLVertexFormatFloat;
        case kFloat2_GrVertexAttribType:
            return MTLVertexFormatFloat2;
        case kFloat3_GrVertexAttribType:
            return MTLVertexFormatFloat3;
        case kFloat4_GrVertexAttribType:
            return MTLVertexFormatFloat4;
        case kHalf_GrVertexAttribType:
            if (@available(macOS 10.13, iOS 11.0, *)) {
                return MTLVertexFormatHalf;
            } else {
                return MTLVertexFormatInvalid;
            }
        case kHalf2_GrVertexAttribType:
            return MTLVertexFormatHalf2;
        case kHalf4_GrVertexAttribType:
            return MTLVertexFormatHalf4;
        case kInt2_GrVertexAttribType:
            return MTLVertexFormatInt2;
        case kInt3_GrVertexAttribType:
            return MTLVertexFormatInt3;
        case kInt4_GrVertexAttribType:
            return MTLVertexFormatInt4;
        case kByte_GrVertexAttribType:
            if (@available(macOS 10.13, iOS 11.0, *)) {
                return MTLVertexFormatChar;
            } else {
                return MTLVertexFormatInvalid;
            }
        case kByte2_GrVertexAttribType:
            return MTLVertexFormatChar2;
        case kByte4_GrVertexAttribType:
            return MTLVertexFormatChar4;
        case kUByte_GrVertexAttribType:
            if (@available(macOS 10.13, iOS 11.0, *)) {
                return MTLVertexFormatUChar;
            } else {
                return MTLVertexFormatInvalid;
            }
        case kUByte2_GrVertexAttribType:
            return MTLVertexFormatUChar2;
        case kUByte4_GrVertexAttribType:
            return MTLVertexFormatUChar4;
        case kUByte_norm_GrVertexAttribType:
            if (@available(macOS 10.13, iOS 11.0, *)) {
                return MTLVertexFormatUCharNormalized;
            } else {
                return MTLVertexFormatInvalid;
            }
        case kUByte4_norm_GrVertexAttribType:
            return MTLVertexFormatUChar4Normalized;
        case kShort2_GrVertexAttribType:
            return MTLVertexFormatShort2;
        case kShort4_GrVertexAttribType:
            return MTLVertexFormatShort4;
        case kUShort2_GrVertexAttribType:
            return MTLVertexFormatUShort2;
        case kUShort2_norm_GrVertexAttribType:
            return MTLVertexFormatUShort2Normalized;
        case kInt_GrVertexAttribType:
            return MTLVertexFormatInt;
        case kUint_GrVertexAttribType:
            return MTLVertexFormatUInt;
        case kUShort_norm_GrVertexAttribType:
            if (@available(macOS 10.13, iOS 11.0, *)) {
                return MTLVertexFormatUShortNormalized;
            } else {
                return MTLVertexFormatInvalid;
            }
        case kUShort4_norm_GrVertexAttribType:
            return MTLVertexFormatUShort4Normalized;
    }
    SK_ABORT("Unknown vertex attribute type");
}

static MTLVertexDescriptor* create_vertex_descriptor(const GrGeometryProcessor& geomProc,
                                                     SkBinaryWriteBuffer* writer) {
    uint32_t vertexBinding = 0, instanceBinding = 0;

    int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
    if (geomProc.hasVertexAttributes()) {
        vertexBinding = nextBinding++;
    }

    if (geomProc.hasInstanceAttributes()) {
        instanceBinding = nextBinding;
    }
    if (writer) {
        writer->writeUInt(vertexBinding);
        writer->writeUInt(instanceBinding);
    }

    auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
    int attributeIndex = 0;

    int vertexAttributeCount = geomProc.numVertexAttributes();
    if (writer) {
        writer->writeInt(vertexAttributeCount);
    }
    size_t vertexAttributeOffset = 0;
    for (const auto& attribute : geomProc.vertexAttributes()) {
        MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
        MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
        SkASSERT(MTLVertexFormatInvalid != format);
        mtlAttribute.format = format;
        mtlAttribute.offset = vertexAttributeOffset;
        mtlAttribute.bufferIndex = vertexBinding;
        if (writer) {
            writer->writeInt(format);
            writer->writeUInt(vertexAttributeOffset);
            writer->writeUInt(vertexBinding);
        }

        vertexAttributeOffset += attribute.sizeAlign4();
        attributeIndex++;
    }
    SkASSERT(vertexAttributeOffset == geomProc.vertexStride());

    if (vertexAttributeCount) {
        MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
                vertexDescriptor.layouts[vertexBinding];
        vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
        vertexBufferLayout.stepRate = 1;
        vertexBufferLayout.stride = vertexAttributeOffset;
        if (writer) {
            writer->writeUInt(vertexAttributeOffset);
        }
    }

    int instanceAttributeCount = geomProc.numInstanceAttributes();
    if (writer) {
        writer->writeInt(instanceAttributeCount);
    }
    size_t instanceAttributeOffset = 0;
    for (const auto& attribute : geomProc.instanceAttributes()) {
        MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
        MTLVertexFormat format = attribute_type_to_mtlformat(attribute.cpuType());
        SkASSERT(MTLVertexFormatInvalid != format);
        mtlAttribute.format = format;
        mtlAttribute.offset = instanceAttributeOffset;
        mtlAttribute.bufferIndex = instanceBinding;
        if (writer) {
            writer->writeInt(format);
            writer->writeUInt(instanceAttributeOffset);
            writer->writeUInt(instanceBinding);
        }

        instanceAttributeOffset += attribute.sizeAlign4();
        attributeIndex++;
    }
    SkASSERT(instanceAttributeOffset == geomProc.instanceStride());

    if (instanceAttributeCount) {
        MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
                vertexDescriptor.layouts[instanceBinding];
        instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
        instanceBufferLayout.stepRate = 1;
        instanceBufferLayout.stride = instanceAttributeOffset;
        if (writer) {
            writer->writeUInt(instanceAttributeOffset);
        }
    }
    return vertexDescriptor;
}

static MTLBlendFactor blend_coeff_to_mtl_blend(GrBlendCoeff coeff) {
    switch (coeff) {
        case kZero_GrBlendCoeff:
            return MTLBlendFactorZero;
        case kOne_GrBlendCoeff:
            return MTLBlendFactorOne;
        case kSC_GrBlendCoeff:
            return MTLBlendFactorSourceColor;
        case kISC_GrBlendCoeff:
            return MTLBlendFactorOneMinusSourceColor;
        case kDC_GrBlendCoeff:
            return MTLBlendFactorDestinationColor;
        case kIDC_GrBlendCoeff:
            return MTLBlendFactorOneMinusDestinationColor;
        case kSA_GrBlendCoeff:
            return MTLBlendFactorSourceAlpha;
        case kISA_GrBlendCoeff:
            return MTLBlendFactorOneMinusSourceAlpha;
        case kDA_GrBlendCoeff:
            return MTLBlendFactorDestinationAlpha;
        case kIDA_GrBlendCoeff:
            return MTLBlendFactorOneMinusDestinationAlpha;
        case kConstC_GrBlendCoeff:
            return MTLBlendFactorBlendColor;
        case kIConstC_GrBlendCoeff:
            return MTLBlendFactorOneMinusBlendColor;
        case kS2C_GrBlendCoeff:
            if (@available(macOS 10.12, iOS 11.0, *)) {
                return MTLBlendFactorSource1Color;
            } else {
                return MTLBlendFactorZero;
            }
        case kIS2C_GrBlendCoeff:
            if (@available(macOS 10.12, iOS 11.0, *)) {
                return MTLBlendFactorOneMinusSource1Color;
            } else {
                return MTLBlendFactorZero;
            }
        case kS2A_GrBlendCoeff:
            if (@available(macOS 10.12, iOS 11.0, *)) {
                return MTLBlendFactorSource1Alpha;
            } else {
                return MTLBlendFactorZero;
            }
        case kIS2A_GrBlendCoeff:
            if (@available(macOS 10.12, iOS 11.0, *)) {
                return MTLBlendFactorOneMinusSource1Alpha;
            } else {
                return MTLBlendFactorZero;
            }
        case kIllegal_GrBlendCoeff:
            return MTLBlendFactorZero;
    }

    SK_ABORT("Unknown blend coefficient");
}

static MTLBlendOperation blend_equation_to_mtl_blend_op(GrBlendEquation equation) {
    static const MTLBlendOperation gTable[] = {
        MTLBlendOperationAdd,              // kAdd_GrBlendEquation
        MTLBlendOperationSubtract,         // kSubtract_GrBlendEquation
        MTLBlendOperationReverseSubtract,  // kReverseSubtract_GrBlendEquation
    };
    static_assert(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation);
    static_assert(0 == kAdd_GrBlendEquation);
    static_assert(1 == kSubtract_GrBlendEquation);
    static_assert(2 == kReverseSubtract_GrBlendEquation);

    SkASSERT((unsigned)equation < kGrBlendEquationCnt);
    return gTable[equation];
}

static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
        MTLPixelFormat format, const GrPipeline& pipeline, SkBinaryWriteBuffer* writer) {
    auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];

    // pixel format
    mtlColorAttachment.pixelFormat = format;
    if (writer) {
        writer->writeInt(format);
    }

    // blending
    const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();

    GrBlendEquation equation = blendInfo.fEquation;
    GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
    GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
    bool blendOn = !GrBlendShouldDisable(equation, srcCoeff, dstCoeff);

    mtlColorAttachment.blendingEnabled = blendOn;
    if (writer) {
        writer->writeBool(blendOn);
    }
    if (blendOn) {
        mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
        mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
        mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
        mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
        mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
        mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
        if (writer) {
            writer->writeInt(mtlColorAttachment.sourceRGBBlendFactor);
            writer->writeInt(mtlColorAttachment.destinationRGBBlendFactor);
            writer->writeInt(mtlColorAttachment.rgbBlendOperation);
            writer->writeInt(mtlColorAttachment.sourceAlphaBlendFactor);
            writer->writeInt(mtlColorAttachment.destinationAlphaBlendFactor);
            writer->writeInt(mtlColorAttachment.alphaBlendOperation);
        }
    }

    if (blendInfo.fWriteColor) {
        mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
    } else {
        mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
    }
    if (writer) {
        writer->writeBool(blendInfo.fWriteColor);
    }
    return mtlColorAttachment;
}

static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
    // Metal expects the buffer to be padded at the end according to the alignment
    // of the largest element in the buffer.
    uint32_t offsetDiff = offset & maxAlignment;
    if (offsetDiff != 0) {
        offsetDiff = maxAlignment - offsetDiff + 1;
    }
    return offset + offsetDiff;
}

static MTLRenderPipelineDescriptor* read_pipeline_data(SkReadBuffer* reader) {
    auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];

    // set up vertex descriptor
    {
        auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
        uint32_t vertexBinding = reader->readUInt();
        uint32_t instanceBinding = reader->readUInt();

        int attributeIndex = 0;

        // vertex attributes
        int vertexAttributeCount = reader->readInt();
        for (int i = 0; i < vertexAttributeCount; ++i) {
            MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
            mtlAttribute.format = (MTLVertexFormat) reader->readInt();
            mtlAttribute.offset = reader->readUInt();
            mtlAttribute.bufferIndex = reader->readUInt();
            ++attributeIndex;
        }
        if (vertexAttributeCount) {
            MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
                    vertexDescriptor.layouts[vertexBinding];
            vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
            vertexBufferLayout.stepRate = 1;
            vertexBufferLayout.stride = reader->readUInt();
        }

        // instance attributes
        int instanceAttributeCount = reader->readInt();
        for (int i = 0; i < instanceAttributeCount; ++i) {
            MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
            mtlAttribute.format = (MTLVertexFormat) reader->readInt();
            mtlAttribute.offset = reader->readUInt();
            mtlAttribute.bufferIndex = reader->readUInt();
            ++attributeIndex;
        }
        if (instanceAttributeCount) {
            MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
                    vertexDescriptor.layouts[instanceBinding];
            instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
            instanceBufferLayout.stepRate = 1;
            instanceBufferLayout.stride = reader->readUInt();
        }
        pipelineDescriptor.vertexDescriptor = vertexDescriptor;
    }

    // set up color attachments
    {
        auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];

        mtlColorAttachment.pixelFormat = (MTLPixelFormat) reader->readInt();
        mtlColorAttachment.blendingEnabled = reader->readBool();
        if (mtlColorAttachment.blendingEnabled) {
            mtlColorAttachment.sourceRGBBlendFactor = (MTLBlendFactor) reader->readInt();
            mtlColorAttachment.destinationRGBBlendFactor = (MTLBlendFactor) reader->readInt();
            mtlColorAttachment.rgbBlendOperation = (MTLBlendOperation) reader->readInt();
            mtlColorAttachment.sourceAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
            mtlColorAttachment.destinationAlphaBlendFactor = (MTLBlendFactor) reader->readInt();
            mtlColorAttachment.alphaBlendOperation = (MTLBlendOperation) reader->readInt();
        }
        if (reader->readBool()) {
            mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
        } else {
            mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
        }

        pipelineDescriptor.colorAttachments[0] = mtlColorAttachment;
    }

    pipelineDescriptor.stencilAttachmentPixelFormat = (MTLPixelFormat) reader->readInt();

    return pipelineDescriptor;
}

GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(
        const GrProgramDesc& desc, const GrProgramInfo& programInfo,
        const GrMtlPrecompiledLibraries* precompiledLibs) {
    TRACE_EVENT0("skia.shaders", TRACE_FUNC);

    // Geometry shaders are not supported
    SkASSERT(!this->geometryProcessor().willUseGeoShader());

    if (precompiledLibs) {
        SkASSERT(precompiledLibs->fPipelineState);
        if (precompiledLibs->fRTHeight) {
            this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
        }
        uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
                                          fUniformHandler.fCurrentUBOMaxAlignment);
        return new GrMtlPipelineState(fGpu,
                                      precompiledLibs->fPipelineState,
                                      GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat()),
                                      fUniformHandles,
                                      fUniformHandler.fUniforms,
                                      bufferSize,
                                      (uint32_t)fUniformHandler.numSamplers(),
                                      std::move(fGeometryProcessor),
                                      std::move(fXferProcessor),
                                      std::move(fFPImpls));
    }

    // build from scratch
    std::unique_ptr<SkBinaryWriteBuffer> writer;

    sk_sp<SkData> cached;
    auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
    if (persistentCache) {
        sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.keyLength());
        cached = persistentCache->load(*key);
    }
    if (persistentCache && !cached) {
        writer.reset(new SkBinaryWriteBuffer());
    }

    // Ordering in how we set these matters. If it changes adjust read_pipeline_data, above.
    auto pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
    pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.geomProc(),
                                                                   writer.get());

    MTLPixelFormat pixelFormat = GrBackendFormatAsMTLPixelFormat(programInfo.backendFormat());
    if (pixelFormat == MTLPixelFormatInvalid) {
        return nullptr;
    }

    pipelineDescriptor.colorAttachments[0] = create_color_attachment(pixelFormat,
                                                                     programInfo.pipeline(),
                                                                     writer.get());
    pipelineDescriptor.sampleCount = programInfo.numRasterSamples();
    GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
    pipelineDescriptor.stencilAttachmentPixelFormat = mtlCaps->getStencilPixelFormat(desc);
    if (writer) {
        writer->writeInt(pipelineDescriptor.stencilAttachmentPixelFormat);
    }
    SkASSERT(pipelineDescriptor.vertexDescriptor);
    SkASSERT(pipelineDescriptor.colorAttachments[0]);

    id<MTLLibrary> shaderLibraries[kGrShaderTypeCount];

    fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");

    this->finalizeShaders();

    SkSL::Program::Settings settings;
    settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
    settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures;
    SkASSERT(!this->fragColorIsInOut());

    SkReadBuffer reader;
    SkFourByteTag shaderType = 0;
    if (persistentCache && cached) {
        reader.setMemory(cached->data(), cached->size());
        shaderType = GrPersistentCacheUtils::GetType(&reader);
    }

    auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
    SkSL::String msl[kGrShaderTypeCount];
    SkSL::Program::Inputs inputs[kGrShaderTypeCount];

    // Unpack any stored shaders from the persistent cache
    if (cached) {
        switch (shaderType) {
            case kMSL_Tag: {
                GrPersistentCacheUtils::UnpackCachedShaders(&reader, msl, inputs,
                                                            kGrShaderTypeCount);
                break;
            }

            case kSKSL_Tag: {
                SkSL::String cached_sksl[kGrShaderTypeCount];
                if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, inputs,
                                                                kGrShaderTypeCount)) {
                    bool success = GrSkSLToMSL(fGpu,
                                               cached_sksl[kVertex_GrShaderType],
                                               SkSL::ProgramKind::kVertex,
                                               settings,
                                               &msl[kVertex_GrShaderType],
                                               &inputs[kVertex_GrShaderType],
                                               errorHandler);
                    success = success && GrSkSLToMSL(fGpu,
                                                     cached_sksl[kFragment_GrShaderType],
                                                     SkSL::ProgramKind::kFragment,
                                                     settings,
                                                     &msl[kFragment_GrShaderType],
                                                     &inputs[kFragment_GrShaderType],
                                                     errorHandler);
                    if (!success) {
                        return nullptr;
                    }
                }
                break;
            }

            default: {
                break;
            }
        }
    }

    // Create any MSL shaders from pipeline data if necessary and cache
    if (msl[kVertex_GrShaderType].empty() || msl[kFragment_GrShaderType].empty()) {
        bool success = true;
        if (msl[kVertex_GrShaderType].empty()) {
            success = GrSkSLToMSL(fGpu,
                                  fVS.fCompilerString,
                                  SkSL::ProgramKind::kVertex,
                                  settings,
                                  &msl[kVertex_GrShaderType],
                                  &inputs[kVertex_GrShaderType],
                                  errorHandler);
        }
        if (success && msl[kFragment_GrShaderType].empty()) {
            success = GrSkSLToMSL(fGpu,
                                  fFS.fCompilerString,
                                  SkSL::ProgramKind::kFragment,
                                  settings,
                                  &msl[kFragment_GrShaderType],
                                  &inputs[kFragment_GrShaderType],
                                  errorHandler);
        }
        if (!success) {
            return nullptr;
        }

        if (persistentCache && !cached) {
            sk_sp<SkData> pipelineData = writer->snapshotAsData();
            if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
                    GrContextOptions::ShaderCacheStrategy::kSkSL) {
                SkSL::String sksl[kGrShaderTypeCount];
                sksl[kVertex_GrShaderType] = GrShaderUtils::PrettyPrint(fVS.fCompilerString);
                sksl[kFragment_GrShaderType] = GrShaderUtils::PrettyPrint(fFS.fCompilerString);
                this->storeShadersInCache(sksl, inputs, &settings,
                                          std::move(pipelineData), true);
            } else {
                /*** dump pipeline data here */
                this->storeShadersInCache(msl, inputs, nullptr,
                                          std::move(pipelineData), false);
            }
        }
    }

    // Compile MSL to libraries
    shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
                                                    msl[kVertex_GrShaderType],
                                                    inputs[kVertex_GrShaderType],
                                                    errorHandler);
    shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
                                                    msl[kFragment_GrShaderType],
                                                    inputs[kFragment_GrShaderType],
                                                    errorHandler);
    if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
        return nullptr;
    }

    pipelineDescriptor.vertexFunction =
            [shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
    pipelineDescriptor.fragmentFunction =
            [shaderLibraries[kFragment_GrShaderType] newFunctionWithName: @"fragmentMain"];

    if (pipelineDescriptor.vertexFunction == nil) {
        SkDebugf("Couldn't find vertexMain() in library\n");
        return nullptr;
    }
    if (pipelineDescriptor.fragmentFunction == nil) {
        SkDebugf("Couldn't find fragmentMain() in library\n");
        return nullptr;
    }
    SkASSERT(pipelineDescriptor.vertexFunction);
    SkASSERT(pipelineDescriptor.fragmentFunction);

    NSError* error = nil;
#if GR_METAL_SDK_VERSION >= 230
    if (@available(macOS 11.0, iOS 14.0, *)) {
        id<MTLBinaryArchive> archive = fGpu->binaryArchive();
        if (archive) {
            NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
            pipelineDescriptor.binaryArchives = archiveArray;
            BOOL result;
            {
                TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
                result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
                                                                            error: &error];
            }
            if (!result && error) {
                SkDebugf("Error storing pipeline: %s\n",
                        [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
            }
        }
    }
#endif
    id<MTLRenderPipelineState> pipelineState;
    {
        TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
#if defined(SK_BUILD_FOR_MAC)
        pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
                                                     fGpu->device(), pipelineDescriptor, &error);
#else
        pipelineState =
            [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
                                                           error: &error];
#endif
    }
    if (error) {
        SkDebugf("Error creating pipeline: %s\n",
                 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
        return nullptr;
    }
    if (!pipelineState) {
        return nullptr;
    }

    uint32_t bufferSize = buffer_size(fUniformHandler.fCurrentUBOOffset,
                                      fUniformHandler.fCurrentUBOMaxAlignment);
    return new GrMtlPipelineState(fGpu,
                                  pipelineState,
                                  pipelineDescriptor.colorAttachments[0].pixelFormat,
                                  fUniformHandles,
                                  fUniformHandler.fUniforms,
                                  bufferSize,
                                  (uint32_t)fUniformHandler.numSamplers(),
                                  std::move(fGeometryProcessor),
                                  std::move(fXferProcessor),
                                  std::move(fFPImpls));
}

//////////////////////////////////////////////////////////////////////////////

bool GrMtlPipelineStateBuilder::PrecompileShaders(GrMtlGpu* gpu, const SkData& cachedData,
                                                  GrMtlPrecompiledLibraries* precompiledLibs) {
    SkASSERT(precompiledLibs);

    SkReadBuffer reader(cachedData.data(), cachedData.size());
    SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);

    auto errorHandler = gpu->getContext()->priv().getShaderErrorHandler();

    SkSL::Program::Settings settings;
    settings.fSharpenTextures = gpu->getContext()->priv().options().fSharpenMipmappedTextures;
    GrPersistentCacheUtils::ShaderMetadata meta;
    meta.fSettings = &settings;

    SkSL::String shaders[kGrShaderTypeCount];
    SkSL::Program::Inputs inputs[kGrShaderTypeCount];
    if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount,
                                                     &meta)) {
        return false;
    }

    // skip the size
    reader.readUInt();
    auto pipelineDescriptor = read_pipeline_data(&reader);
    if (!reader.isValid()) {
        return false;
    }

    id<MTLLibrary> vertexLibrary;
    id<MTLLibrary> fragmentLibrary;
    switch (shaderType) {
        case kMSL_Tag: {
            vertexLibrary =
                    GrCompileMtlShaderLibrary(gpu, shaders[kVertex_GrShaderType], errorHandler);
            fragmentLibrary =
                    GrCompileMtlShaderLibrary(gpu, shaders[kFragment_GrShaderType], errorHandler);
            break;
        }

        case kSKSL_Tag: {
            SkSL::String msl[kGrShaderTypeCount];
            if (!GrSkSLToMSL(gpu,
                           shaders[kVertex_GrShaderType],
                           SkSL::ProgramKind::kVertex,
                           settings,
                           &msl[kVertex_GrShaderType],
                           &inputs[kVertex_GrShaderType],
                           errorHandler)) {
                return false;
            }
            if (!GrSkSLToMSL(gpu,
                           shaders[kFragment_GrShaderType],
                           SkSL::ProgramKind::kFragment,
                           settings,
                           &msl[kFragment_GrShaderType],
                           &inputs[kFragment_GrShaderType],
                           errorHandler)) {
                return false;
            }
            vertexLibrary =
                    GrCompileMtlShaderLibrary(gpu, msl[kVertex_GrShaderType], errorHandler);
            fragmentLibrary =
                    GrCompileMtlShaderLibrary(gpu, msl[kFragment_GrShaderType], errorHandler);
            break;
        }

        default: {
            return false;
        }
    }

    pipelineDescriptor.vertexFunction =
            [vertexLibrary newFunctionWithName: @"vertexMain"];
    pipelineDescriptor.fragmentFunction =
            [fragmentLibrary newFunctionWithName: @"fragmentMain"];

    NSError* error = nil;
#if GR_METAL_SDK_VERSION >= 230
    if (@available(macOS 11.0, iOS 14.0, *)) {
        id<MTLBinaryArchive> archive = gpu->binaryArchive();
        if (archive) {
            NSArray* archiveArray = [NSArray arrayWithObjects:archive, nil];
            pipelineDescriptor.binaryArchives = archiveArray;
            BOOL result;
            {
                TRACE_EVENT0("skia.shaders", "addRenderPipelineFunctionsWithDescriptor");
                result = [archive addRenderPipelineFunctionsWithDescriptor: pipelineDescriptor
                                                                            error: &error];
            }
            if (!result && error) {
                SkDebugf("Error storing pipeline: %s\n",
                        [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
            }
        }
    }
#endif
    {
        TRACE_EVENT0("skia.shaders", "newRenderPipelineStateWithDescriptor");
#if defined(SK_BUILD_FOR_MAC)
        precompiledLibs->fPipelineState =
            GrMtlNewRenderPipelineStateWithDescriptor(gpu->device(), pipelineDescriptor, &error);
#else
        precompiledLibs->fPipelineState =
            [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
                                                           error: &error];
#endif
    }
    if (error) {
        SkDebugf("Error creating pipeline: %s\n",
                 [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
        return false;
    }

    precompiledLibs->fRTHeight = inputs[kFragment_GrShaderType].fRTHeight;
    return true;
}

GR_NORETAIN_END
