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

#include "experimental/graphite/src/ProgramCache.h"

namespace skgpu::graphite {

////////////////////////////////////////////////////////////////////////////////////////////////////
ProgramCache::ProgramInfo::ProgramInfo(uint32_t uniqueID, Combination c)
    : fID(uniqueID)
    , fCombination(c) {
}

ProgramCache::ProgramInfo::~ProgramInfo() {}

std::string ProgramCache::ProgramInfo::getMSL() const {
    std::string msl = GetMSLUniformStruct(fCombination.fShaderType);

    switch (fCombination.fShaderType) {
        case ShaderCombo::ShaderType::kLinearGradient:
            // TODO: this MSL uses a 'rtSize' uniform that, presumably, we'll be getting from the
            // vertex shader side of things (still somewhat TBD)
            msl += std::string(
            "fragment float4 fragmentShader(VertexOut interpolated [[stage_in]],\n"
            "                               constant FragmentUniforms &uniforms [[buffer(0)]])\n"
            "{"
            "float2 screenPos = float2(2*interpolated.pos.x/uniforms.rtSize[0] - 1,\n"
            "                          2*interpolated.pos.y/uniforms.rtSize[1] - 1);\n"
            "float2 delta = uniforms.point1 - uniforms.point0;\n"
            "float2 pt = screenPos - uniforms.point0;\n"
            "float t = dot(pt, delta) / dot(delta, delta);\n"
            "float4 result = uniforms.colors[0];\n"
            "result = mix(result, uniforms.colors[1],\n"
            "             clamp((t-uniforms.offsets[0])/(uniforms.offsets[1]-uniforms.offsets[0]),\n"
            "                   0, 1));\n"
            "result = mix(result, uniforms.colors[2],\n"
            "             clamp((t-uniforms.offsets[1])/(uniforms.offsets[2]-uniforms.offsets[1]),\n"
            "                   0, 1));\n"
            "result = mix(result, uniforms.colors[3],\n"
            "             clamp((t-uniforms.offsets[2])/(uniforms.offsets[3]-uniforms.offsets[2]),\n"
            "             0, 1));\n"
            "return result;\n"
            "}\n");
            break;
        case ShaderCombo::ShaderType::kNone:
            // TODO: kNone is for depth-only draws, so should actually have a fragment output type
            // that only defines a [[depth]] attribute but no color calculation.
            msl +=
                    "fragment float4 fragmentMain(VertexOutput interpolated [[stage_in]]) {\n"
                    "    return float4(0.0, 0.0, 1.0, 1.0);\n"
                    "}\n";
            break;
        case ShaderCombo::ShaderType::kRadialGradient:
        case ShaderCombo::ShaderType::kSweepGradient:
        case ShaderCombo::ShaderType::kConicalGradient:
        case ShaderCombo::ShaderType::kSolidColor:
        default:
            msl += std::string(
            "fragment float4 fragmentShader(VertexOut interpolated [[stage_in]],\n"
            "                               constant FragmentUniforms &uniforms [[buffer(0)]])\n"
            "{\n"
            "return float4(uniforms.color);\n"
            "}\n");
            break;
    }

    return msl;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
ProgramCache::ProgramCache() {
    // kInvalidProgramID (aka 0) is reserved
    fProgramVector.push_back(nullptr);
}

size_t ProgramCache::Hash::operator()(Combination c) const {
    return static_cast<int>(c.fShaderType) +
           static_cast<int>(c.fTileMode) +
           static_cast<int>(c.fBlendMode);
}

sk_sp<ProgramCache::ProgramInfo> ProgramCache::findOrCreateProgram(Combination c) {
    auto iter = fProgramHash.find(c);
    if (iter != fProgramHash.end()) {
        SkASSERT(iter->second->id() != kInvalidProgramID);
        return iter->second;
    }

    sk_sp<ProgramInfo> pi(new ProgramInfo(fNextUniqueID++, c));
    fProgramHash.insert(std::make_pair(c, pi));
    fProgramVector.push_back(pi);
    SkASSERT(fProgramVector[pi->id()] == pi);
    return pi;
}

sk_sp<ProgramCache::ProgramInfo> ProgramCache::lookup(uint32_t uniqueID) {
    SkASSERT(uniqueID < fProgramVector.size());
    return fProgramVector[uniqueID];
}

} // namespace skgpu::graphite
