/*
 * 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 {

////////////////////////////////////////////////////////////////////////////////////////////////////
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::kRadialGradient:
        case ShaderCombo::ShaderType::kSweepGradient:
        case ShaderCombo::ShaderType::kConicalGradient:
        case ShaderCombo::ShaderType::kNone:
        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
