/*
 * Copyright 2023 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/BlurUtils.h"

#include "include/effects/SkRuntimeEffect.h"
#include "src/base/SkMathPriv.h"
#include "src/core/SkRuntimeEffectPriv.h"

#include <array>

namespace skgpu {

void Compute2DBlurKernel(SkSize sigma,
                         SkISize radius,
                         SkSpan<float> kernel) {
    // Callers likely had to calculate the radius prior to filling out the kernel value, which is
    // why it's provided; but make sure it's consistent with expectations.
    SkASSERT(BlurSigmaRadius(sigma.width()) == radius.width() &&
             BlurSigmaRadius(sigma.height()) == radius.height());

    // Callers are responsible for downscaling large sigmas to values that can be processed by the
    // effects, so ensure the radius won't overflow 'kernel'
    const int width = BlurKernelWidth(radius.width());
    const int height = BlurKernelWidth(radius.height());
    const size_t kernelSize = SkTo<size_t>(sk_64_mul(width, height));
    SkASSERT(kernelSize <= kernel.size());

    // And the definition of an identity blur should be sufficient that 2sigma^2 isn't near zero
    // when there's a non-trivial radius.
    const float twoSigmaSqrdX = 2.0f * sigma.width() * sigma.width();
    const float twoSigmaSqrdY = 2.0f * sigma.height() * sigma.height();
    SkASSERT((radius.width() == 0 || !SkScalarNearlyZero(twoSigmaSqrdX)) &&
             (radius.height() == 0 || !SkScalarNearlyZero(twoSigmaSqrdY)));

    // Setting the denominator to 1 when the radius is 0 automatically converts the remaining math
    // to the 1D Gaussian distribution. When both radii are 0, it correctly computes a weight of 1.0
    const float sigmaXDenom = radius.width() > 0 ? 1.0f / twoSigmaSqrdX : 1.f;
    const float sigmaYDenom = radius.height() > 0 ? 1.0f / twoSigmaSqrdY : 1.f;

    float sum = 0.0f;
    for (int x = 0; x < width; x++) {
        float xTerm = static_cast<float>(x - radius.width());
        xTerm = xTerm * xTerm * sigmaXDenom;
        for (int y = 0; y < height; y++) {
            float yTerm = static_cast<float>(y - radius.height());
            float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
            // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
            // is dropped here, since we renormalize the kernel below.
            kernel[y * width + x] = xyTerm;
            sum += xyTerm;
        }
    }
    // Normalize the kernel
    float scale = 1.0f / sum;
    for (size_t i = 0; i < kernelSize; ++i) {
        kernel[i] *= scale;
    }
    // Zero remainder of the array
    memset(kernel.data() + kernelSize, 0, sizeof(float)*(kernel.size() - kernelSize));
}

void Compute2DBlurKernel(SkSize sigma,
                         SkISize radii,
                         std::array<SkV4, kMaxBlurSamples/4>& kernel) {
    static_assert(sizeof(kernel) == sizeof(std::array<float, kMaxBlurSamples>));
    static_assert(alignof(float) == alignof(SkV4));
    float* data = kernel[0].ptr();
    Compute2DBlurKernel(sigma, radii, SkSpan<float>(data, kMaxBlurSamples));
}

void Compute2DBlurOffsets(SkISize radius, std::array<SkV4, kMaxBlurSamples/2>& offsets) {
    const int kernelArea = BlurKernelWidth(radius.width()) * BlurKernelWidth(radius.height());
    SkASSERT(kernelArea <= kMaxBlurSamples);

    SkSpan<float> offsetView{offsets[0].ptr(), kMaxBlurSamples*2};

    int i = 0;
    for (int y = -radius.height(); y <= radius.height(); ++y) {
        for (int x = -radius.width(); x <= radius.width(); ++x) {
            offsetView[2*i]   = x;
            offsetView[2*i+1] = y;
            ++i;
        }
    }
    SkASSERT(i == kernelArea);
    const int lastValidOffset = 2*(kernelArea - 1);
    for (; i < kMaxBlurSamples; ++i) {
        offsetView[2*i]   = offsetView[lastValidOffset];
        offsetView[2*i+1] = offsetView[lastValidOffset+1];
    }
}

void Compute1DBlurLinearKernel(float sigma,
                               int radius,
                               std::array<SkV4, kMaxBlurSamples/2>& offsetsAndKernel) {
    SkASSERT(sigma <= kMaxLinearBlurSigma);
    SkASSERT(radius == BlurSigmaRadius(sigma));
    SkASSERT(BlurLinearKernelWidth(radius) <= kMaxBlurSamples);

    // Given 2 adjacent gaussian points, they are blended as: Wi * Ci + Wj * Cj.
    // The GPU will mix Ci and Cj as Ci * (1 - x) + Cj * x during sampling.
    // Compute W', x such that W' * (Ci * (1 - x) + Cj * x) = Wi * Ci + Wj * Cj.
    // Solving W' * x = Wj, W' * (1 - x) = Wi:
    // W' = Wi + Wj
    // x = Wj / (Wi + Wj)
    auto get_new_weight = [](float* new_w, float* offset, float wi, float wj) {
        *new_w = wi + wj;
        *offset = wj / (wi + wj);
    };

    // Create a temporary standard kernel. The maximum blur radius that can be passed to this
    // function is (kMaxBlurSamples-1), so make an array large enough to hold the full kernel width.
    static constexpr int kMaxKernelWidth = BlurKernelWidth(kMaxBlurSamples - 1);
    SkASSERT(BlurKernelWidth(radius) <= kMaxKernelWidth);
    std::array<float, kMaxKernelWidth> fullKernel;
    Compute1DBlurKernel(sigma, radius, SkSpan<float>{fullKernel.data(), BlurKernelWidth(radius)});

    std::array<float, kMaxBlurSamples> kernel;
    std::array<float, kMaxBlurSamples> offsets;
    // Note that halfsize isn't just size / 2, but radius + 1. This is the size of the output array.
    int halfSize = skgpu::BlurLinearKernelWidth(radius);
    int halfRadius = halfSize / 2;
    int lowIndex = halfRadius - 1;

    // Compute1DGaussianKernel produces a full 2N + 1 kernel. Since the kernel can be mirrored,
    // compute only the upper half and mirror to the lower half.

    int index = radius;
    if (radius & 1) {
        // If N is odd, then use two samples.
        // The centre texel gets sampled twice, so halve its influence for each sample.
        // We essentially sample like this:
        // Texel edges
        // v    v    v    v
        // |    |    |    |
        // \-----^---/ Lower sample
        //      \---^-----/ Upper sample
        get_new_weight(&kernel[halfRadius],
                       &offsets[halfRadius],
                       fullKernel[index] * 0.5f,
                       fullKernel[index + 1]);
        kernel[lowIndex] = kernel[halfRadius];
        offsets[lowIndex] = -offsets[halfRadius];
        index++;
        lowIndex--;
    } else {
        // If N is even, then there are an even number of texels on either side of the centre texel.
        // Sample the centre texel directly.
        kernel[halfRadius] = fullKernel[index];
        offsets[halfRadius] = 0.0f;
    }
    index++;

    // Every other pair gets one sample.
    for (int i = halfRadius + 1; i < halfSize; index += 2, i++, lowIndex--) {
        get_new_weight(&kernel[i], &offsets[i], fullKernel[index], fullKernel[index + 1]);
        offsets[i] += static_cast<float>(index - radius);

        // Mirror to lower half.
        kernel[lowIndex] = kernel[i];
        offsets[lowIndex] = -offsets[i];
    }

    // Zero out remaining values in the kernel
    memset(kernel.data() + halfSize, 0, sizeof(float)*(kMaxBlurSamples - halfSize));
    // But copy the last valid offset into the remaining offsets, to increase the chance that
    // over-iteration in a fragment shader will have a cache hit.
    for (int i = halfSize; i < kMaxBlurSamples; ++i) {
        offsets[i] = offsets[halfSize - 1];
    }

    // Interleave into the output array to match the 1D SkSL effect
    for (int i = 0; i < skgpu::kMaxBlurSamples / 2; ++i) {
        offsetsAndKernel[i] = SkV4{offsets[2*i], kernel[2*i], offsets[2*i+1], kernel[2*i+1]};
    }
}

template<typename MakeEffectFn>
static const SkRuntimeEffect* get_effect(int kernelWidth, MakeEffectFn makeEffect) {
    SkASSERT(kernelWidth >= 2 && kernelWidth <= kMaxBlurSamples);
    switch(kernelWidth) {
        // Batch on multiples of 4 (skipping width=1, since that can't happen)
        case 2:  [[fallthrough]];
        case 3:  [[fallthrough]];
        case 4:  { static const SkRuntimeEffect* effect = makeEffect(4);  return effect; }
        case 5:  [[fallthrough]];
        case 6:  [[fallthrough]];
        case 7:  [[fallthrough]];
        case 8:  { static const SkRuntimeEffect* effect = makeEffect(8);  return effect; }
        case 9:  [[fallthrough]];
        case 10: [[fallthrough]];
        case 11: [[fallthrough]];
        case 12: { static const SkRuntimeEffect* effect = makeEffect(12); return effect; }
        case 13: [[fallthrough]];
        case 14: [[fallthrough]];
        case 15: [[fallthrough]];
        case 16: { static const SkRuntimeEffect* effect = makeEffect(16); return effect; }
        case 17: [[fallthrough]];
        case 18: [[fallthrough]];
        case 19: [[fallthrough]];
        // With larger kernels, batch on multiples of eight so up to 7 wasted samples.
        case 20: { static const SkRuntimeEffect* effect = makeEffect(20); return effect; }
        case 21: [[fallthrough]];
        case 22: [[fallthrough]];
        case 23: [[fallthrough]];
        case 24: [[fallthrough]];
        case 25: [[fallthrough]];
        case 26: [[fallthrough]];
        case 27: [[fallthrough]];
        case 28: { static const SkRuntimeEffect* effect = makeEffect(28); return effect; }
        default:
            SkUNREACHABLE;
    }
}

const SkRuntimeEffect* GetLinearBlur1DEffect(int radius) {
    static const auto make1DEffect = [](int kernelWidth) {
        SkASSERT(kernelWidth <= kMaxBlurSamples);
        // The SkSL structure performs two kernel taps; if the kernel has an odd width the last
        // sample will be skipped with the current loop limit calculation.
        SkASSERT(kernelWidth % 2 == 0);
        return SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
                SkStringPrintf(
                        // The coefficients are always stored for the max radius to keep the
                        // uniform block consistent across all effects.
                        "const int kMaxUniformKernelSize = %d / 2;"
                        // But we generate an exact loop over the kernel size. Note that this
                        // program can be used for kernels smaller than the constructed max as long
                        // as the kernel weights for excess entries are set to 0.
                        "const int kMaxLoopLimit = %d / 2;"

                        "uniform half4 offsetsAndKernel[kMaxUniformKernelSize];"
                        "uniform half2 dir;"

                        "uniform shader child;"

                        "half4 main(float2 coord) {"
                            "half4 sum = half4(0);"
                            "for (int i = 0; i < kMaxLoopLimit; ++i) {"
                                "half4 s = offsetsAndKernel[i];"
                                "sum += s.y * child.eval(coord + s.x*dir);"
                                "sum += s.w * child.eval(coord + s.z*dir);"
                            "}"
                            "return sum;"
                        "}", kMaxBlurSamples, kernelWidth).c_str());
    };

    return get_effect(BlurLinearKernelWidth(radius), make1DEffect);
}

const SkRuntimeEffect* GetBlur2DEffect(const SkISize& radii) {
    static const auto make2DEffect = [](int maxKernelSize) {
        SkASSERT(maxKernelSize % 4 == 0);
        return SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
                SkStringPrintf(
                        // The coefficients are always stored for the max radius to keep the
                        // uniform block consistent across all effects.
                        "const int kMaxUniformKernelSize = %d / 4;"
                        "const int kMaxUniformOFfsetsSize = 2*kMaxUniformKernelSize;"
                        // But we generate an exact loop over the kernel size. Note that this
                        // program can be used for kernels smaller than the constructed max as long
                        // as the kernel weights for excess entries are set to 0.
                        "const int kMaxLoopLimit = %d / 4;"

                        // Pack scalar coefficients into half4 for better packing on std140, and
                        // upload offsets to avoid having to transform the 1D index into a 2D coord
                        "uniform half4 kernel[kMaxUniformKernelSize];"
                        "uniform half4 offsets[kMaxUniformOFfsetsSize];"

                        "uniform shader child;"

                        "half4 main(float2 coord) {"
                            "half4 sum = half4(0);"

                            "for (int i = 0; i < kMaxLoopLimit; ++i) {"
                                "half4 k = kernel[i];"
                                "half4 o = offsets[2*i];"
                                "sum += k.x * child.eval(coord + o.xy);"
                                "sum += k.y * child.eval(coord + o.zw);"
                                "o = offsets[2*i + 1];"
                                "sum += k.z * child.eval(coord + o.xy);"
                                "sum += k.w * child.eval(coord + o.zw);"
                            "}"
                            "return sum;"
                        "}", kMaxBlurSamples, maxKernelSize).c_str());
    };

    int kernelArea = BlurKernelWidth(radii.width()) * BlurKernelWidth(radii.height());
    return get_effect(kernelArea, make2DEffect);
}

} // namespace skgpu
