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

#include "src/gpu/graphite/render/SDFTextRenderStep.h"

#include "include/gpu/graphite/Recorder.h"
#include "include/private/SkSLString.h"
#include "src/gpu/graphite/DrawParams.h"
#include "src/gpu/graphite/DrawWriter.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
#include "src/gpu/graphite/text/AtlasManager.h"
#include "src/text/gpu/SubRunContainer.h"

namespace skgpu::graphite {

namespace {

// We are expecting to sample from up to 4 textures
constexpr int kNumSDFAtlasTextures = 4;

}  // namespace

SDFTextRenderStep::SDFTextRenderStep(bool isA8)
        : RenderStep("SDFTextRenderStep",
                     isA8 ? "A8" : "565",
                     Flags::kPerformsShading | Flags::kHasTextures | Flags::kEmitsCoverage,
                     /*uniforms=*/{{"deviceMatrix", SkSLType::kFloat4x4},
                                   {"atlasSizeInv", SkSLType::kFloat2},
                                   {"distanceAdjust", SkSLType::kFloat}},
                     PrimitiveType::kTriangleStrip,
                     kDirectDepthGEqualPass,
                     /*vertexAttrs=*/ {},
                     /*instanceAttrs=*/
                     {{"size", VertexAttribType::kUShort2, SkSLType::kUShort2},
                      {"uvPos", VertexAttribType::kUShort2, SkSLType::kUShort2},
                      {"xyPos", VertexAttribType::kFloat2, SkSLType::kFloat2},
                      {"indexAndFlags", VertexAttribType::kUShort2, SkSLType::kUShort2},
                      {"strikeToSourceScale", VertexAttribType::kFloat, SkSLType::kFloat},
                      {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
                      {"ssboIndex", VertexAttribType::kInt, SkSLType::kInt}},
                     /*varyings=*/
                     {{"unormTexCoords", SkSLType::kFloat2},
                      {"textureCoords", SkSLType::kFloat2},
                      {"texIndex", SkSLType::kFloat}}) {
    // TODO: store if it's A8 and adjust shader
}

SDFTextRenderStep::~SDFTextRenderStep() {}

const char* SDFTextRenderStep::vertexSkSL() const {
    return R"(
        float2 baseCoords = float2(float(sk_VertexID >> 1), float(sk_VertexID & 1));
        baseCoords.xy *= float2(size);

        stepLocalCoords = strikeToSourceScale*baseCoords + float2(xyPos);
        float4 position = deviceMatrix*float4(stepLocalCoords, 0, 1);

        unormTexCoords = baseCoords + float2(uvPos);
        textureCoords = unormTexCoords * atlasSizeInv;
        texIndex = float(indexAndFlags.x);

        float4 devPosition = float4(position.xy, depth, position.w);
    )";
}

std::string SDFTextRenderStep::texturesAndSamplersSkSL(int binding) const {
    std::string result;

    for (unsigned int i = 0; i < kNumSDFAtlasTextures; ++i) {
        SkSL::String::appendf(&result,
                              "layout(binding=%d) uniform sampler2D sdf_atlas_%d;\n", binding, i);
        binding++;
    }

    return result;
}

const char* SDFTextRenderStep::fragmentCoverageSkSL() const {
    // TODO: To minimize the number of shaders generated this is the full affine shader.
    // For best performance it may be worth creating the uniform scale shader as well,
    // as that's the most common case.
    // TODO: Need to add 565 support.
    // TODO: Need aliased and possibly sRGB support.
    return R"(
        half texColor;
        if (texIndex == 0) {
           texColor = sample(sdf_atlas_0, textureCoords).r;
        } else if (texIndex == 1) {
           texColor = sample(sdf_atlas_1, textureCoords).r;
        } else if (texIndex == 2) {
           texColor = sample(sdf_atlas_2, textureCoords).r;
        } else if (texIndex == 3) {
           texColor = sample(sdf_atlas_3, textureCoords).r;
        } else {
           texColor = sample(sdf_atlas_0, textureCoords).r;
        }
        // The distance field is constructed as uchar8_t values, so that the zero value is at 128,
        // and the supported range of distances is [-4 * 127/128, 4].
        // Hence to convert to floats our multiplier (width of the range) is 4 * 255/128 = 7.96875
        // and zero threshold is 128/255 = 0.50196078431.
        half distance = 7.96875*(texColor - 0.50196078431);

        // We may further adjust the distance for gamma correction.
        distance -= half(distanceAdjust);

        // After the distance is unpacked, we need to correct it by a factor dependent on the
        // current transformation. For general transforms, to determine the amount of correction
        // we multiply a unit vector pointing along the SDF gradient direction by the Jacobian of
        // unormTexCoords (which is the inverse transform for this fragment) and take the length of
        // the result.
        half2 dist_grad = half2(float2(dFdx(distance), dFdy(distance)));
        half dg_len2 = dot(dist_grad, dist_grad);

        // The length of the gradient may be near 0, so we need to check for that. This also
        // compensates for the Adreno, which likes to drop tiles on division by 0
        if (dg_len2 < 0.0001) {
            dist_grad = half2(0.7071, 0.7071);
        } else {
            dist_grad = dist_grad*half(inversesqrt(dg_len2));
        }

        // Computing the Jacobian and multiplying by the gradient.
        half2 Jdx = half2(dFdx(unormTexCoords));
        half2 Jdy = half2(dFdy(unormTexCoords));
        half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,
                           dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);

        // This gives us a smooth step across approximately one fragment.
        half afwidth = 0.65*length(grad);
        // TODO: handle aliased and sRGB rendering
        half val = smoothstep(-afwidth, afwidth, distance);
        outputCoverage = half4(val);
    )";
}

void SDFTextRenderStep::writeVertices(DrawWriter* dw,
                                      const DrawParams& params,
                                      int ssboIndex) const {
    const SubRunData& subRunData = params.geometry().subRunData();
    subRunData.subRun()->fillInstanceData(dw, subRunData.startGlyphIndex(), subRunData.glyphCount(),
                                          ssboIndex, params.order().depthAsFloat());
}

void SDFTextRenderStep::writeUniformsAndTextures(const DrawParams& params,
                                                 PipelineDataGatherer* gatherer) const {
    SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)

    const SubRunData& subRunData = params.geometry().subRunData();
    unsigned int numProxies;
    Recorder* recorder = subRunData.recorder();
    const sk_sp<TextureProxy>* proxies =
            recorder->priv().atlasManager()->getProxies(subRunData.subRun()->maskFormat(),
                                                        &numProxies);
    SkASSERT(proxies && numProxies > 0);

    // write uniforms
    gatherer->write(params.transform());
    skvx::float2 atlasDimensionsInverse = {1.f/proxies[0]->dimensions().width(),
                                           1.f/proxies[0]->dimensions().height()};
    gatherer->write(atlasDimensionsInverse);

    // TODO: get this from DistanceFieldAdjustTable and luminance color (set in SubRunData?)
    float gammaCorrection = 0.f;
    gatherer->write(gammaCorrection);

    // write textures and samplers
    const SkSamplingOptions kSamplingOptions(SkFilterMode::kLinear);
    constexpr SkTileMode kTileModes[2] = { SkTileMode::kClamp, SkTileMode::kClamp };
    for (unsigned int i = 0; i < numProxies; ++i) {
        gatherer->add(kSamplingOptions, kTileModes, proxies[i]);
    }
    // If the atlas has less than 4 active proxies we still need to set up samplers for the shader.
    for (unsigned int i = numProxies; i < kNumSDFAtlasTextures; ++i) {
        gatherer->add(kSamplingOptions, kTileModes, proxies[0]);
    }
}

}  // namespace skgpu::graphite
