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

#include "GrCircleBlurFragmentProcessor.h"

#if SK_SUPPORT_GPU

#include "GrContext.h"
#include "GrInvariantOutput.h"
#include "GrTextureProvider.h"

#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"

class GrGLCircleBlurFragmentProcessor : public GrGLSLFragmentProcessor {
public:
    void emitCode(EmitArgs&) override;

protected:
    void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;

private:
    GrGLSLProgramDataManager::UniformHandle fDataUniform;

    typedef GrGLSLFragmentProcessor INHERITED;
};

void GrGLCircleBlurFragmentProcessor::emitCode(EmitArgs& args) {

    const char *dataName;

    // The data is formatted as:
    // x,y  - the center of the circle
    // z    - the distance at which the intensity starts falling off (e.g., the start of the table)
    // w    - the inverse of the profile texture size
    fDataUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
                                                    kVec4f_GrSLType,
                                                    kDefault_GrSLPrecision,
                                                    "data",
                                                    &dataName);

    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    const char *fragmentPos = fragBuilder->fragmentPosition();

    if (args.fInputColor) {
        fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
    } else {
        fragBuilder->codeAppendf("vec4 src=vec4(1);");
    }

    // We just want to compute "length(vec) - %s.z + 0.5) * %s.w" but need to rearrange
    // for precision
    fragBuilder->codeAppendf("vec2 vec = vec2( (%s.x - %s.x) * %s.w , (%s.y - %s.y) * %s.w );", 
                             fragmentPos, dataName, dataName,
                             fragmentPos, dataName, dataName);
    fragBuilder->codeAppendf("float dist = length(vec) + ( 0.5 - %s.z ) * %s.w;",
                             dataName, dataName);

    fragBuilder->codeAppendf("float intensity = ");
    fragBuilder->appendTextureLookup(args.fSamplers[0], "vec2(dist, 0.5)");
    fragBuilder->codeAppend(".a;");

    fragBuilder->codeAppendf("%s = src * intensity;\n", args.fOutputColor );
}

void GrGLCircleBlurFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman,
                                                const GrProcessor& proc) {
    const GrCircleBlurFragmentProcessor& cbfp = proc.cast<GrCircleBlurFragmentProcessor>();
    const SkRect& circle = cbfp.circle();

    // The data is formatted as:
    // x,y  - the center of the circle
    // z    - the distance at which the intensity starts falling off (e.g., the start of the table)
    // w    - the inverse of the profile texture size
    pdman.set4f(fDataUniform, circle.centerX(), circle.centerY(), cbfp.offset(),
                1.0f / cbfp.profileSize());
}

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

GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circle,
                                                             float sigma,
                                                             float offset,
                                                             GrTexture* blurProfile) 
    : fCircle(circle)
    , fSigma(sigma)
    , fOffset(offset)
    , fBlurProfileAccess(blurProfile, GrTextureParams::kBilerp_FilterMode) {
    this->initClassID<GrCircleBlurFragmentProcessor>();
    this->addTextureAccess(&fBlurProfileAccess);
    this->setWillReadFragmentPosition();
}

GrGLSLFragmentProcessor* GrCircleBlurFragmentProcessor::onCreateGLSLInstance() const {
    return new GrGLCircleBlurFragmentProcessor;
}

void GrCircleBlurFragmentProcessor::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
                                                          GrProcessorKeyBuilder* b) const {
    GrGLCircleBlurFragmentProcessor::GenKey(*this, caps, b);
}

void GrCircleBlurFragmentProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const {
    inout->mulByUnknownSingleComponent();
}

// Evaluate an AA circle function centered at the origin with 'radius' at (x,y)
static inline float disk(float x, float y, float radius) {
    float distSq = x*x + y*y;
    if (distSq <= (radius-0.5f)*(radius-0.5f)) {
        return 1.0f;
    } else if (distSq >= (radius+0.5f)*(radius+0.5f)) {
        return 0.0f;
    } else {
        float ramp = radius + 0.5f - sqrtf(distSq);
        SkASSERT(ramp >= 0.0f && ramp <= 1.0f);
        return ramp;
    }
}

// Create the top half of an even-sized Gaussian kernel
static void make_half_kernel(float* kernel, int kernelWH, float sigma) {
    SkASSERT(!(kernelWH & 1));

    const float kernelOff = (kernelWH-1)/2.0f;

    float b = 1.0f / (2.0f * sigma * sigma);
    // omit the scale term since we're just going to renormalize

    float tot = 0.0f;
    for (int y = 0; y < kernelWH/2; ++y) {
        for (int x = 0; x < kernelWH/2; ++x) {
            // TODO: use a cheap approximation of the 2D Guassian?
            float x2 = (x-kernelOff) * (x-kernelOff);
            float y2 = (y-kernelOff) * (y-kernelOff);
            // The kernel is symmetric so only compute it once for both sides
            kernel[y*kernelWH+(kernelWH-x-1)] = kernel[y*kernelWH+x] = expf(-(x2 + y2) * b);
            tot += 2.0f * kernel[y*kernelWH+x];
        }
    }
    // Still normalize the half kernel to 1.0 (rather than 0.5) so we don't
    // have to scale by 2.0 after convolution.
    for (int y = 0; y < kernelWH/2; ++y) {
        for (int x = 0; x < kernelWH; ++x) {
            kernel[y*kernelWH+x] /= tot;
        }
    }
}

// Apply the half-kernel at 't' away from the center of the circle
static uint8_t eval_at(float t, float halfWidth, float* halfKernel, int kernelWH) {
    SkASSERT(!(kernelWH & 1));

    const float kernelOff = (kernelWH-1)/2.0f;

    float acc = 0;

    for (int y = 0; y < kernelWH/2; ++y) {
        if (kernelOff-y > halfWidth+0.5f) {
            // All disk() samples in this row will be 0.0f
            continue;
        }

        for (int x = 0; x < kernelWH; ++x) {
            float image = disk(t - kernelOff + x, -kernelOff + y, halfWidth);
            float kernel = halfKernel[y*kernelWH+x];
            acc += kernel * image;
        }
    }

    return SkUnitScalarClampToByte(acc);
}

static inline void compute_profile_offset_and_size(float halfWH, float sigma,
                                                   float* offset, int* size) {

    if (3*sigma <= halfWH) {
        // The circle is bigger than the Gaussian. In this case we know the interior of the
        // blurred circle is solid.
        *offset = halfWH - 3 * sigma; // This location maps to 0.5f in the weights texture.
                                      // It should always be 255.
        *size = SkScalarCeilToInt(6*sigma);
    } else {
        // The Gaussian is bigger than the circle.
        *offset = 0.0f;
        *size = SkScalarCeilToInt(halfWH + 3*sigma);
    }
}

static uint8_t* create_profile(float halfWH, float sigma) {

    int kernelWH = SkScalarCeilToInt(6.0f*sigma);
    kernelWH = (kernelWH + 1) & ~1; // make it the next even number up

    SkAutoTArray<float> halfKernel(kernelWH*kernelWH/2);

    make_half_kernel(halfKernel.get(), kernelWH, sigma);

    float offset;
    int numSteps;

    compute_profile_offset_and_size(halfWH, sigma, &offset, &numSteps);

    uint8_t* weights = new uint8_t[numSteps];
    for (int i = 0; i < numSteps - 1; ++i) {
        weights[i] = eval_at(offset+i, halfWH, halfKernel.get(), kernelWH);
    }
    // Ensure the tail of the Gaussian goes to zero.
    weights[numSteps-1] = 0;

    return weights;
}

GrTexture* GrCircleBlurFragmentProcessor::CreateCircleBlurProfileTexture(
                                                                GrTextureProvider* textureProvider,
                                                                const SkRect& circle,
                                                                float sigma,
                                                                float* offset) {
    float halfWH = circle.width() / 2.0f;

    int size;
    compute_profile_offset_and_size(halfWH, sigma, offset, &size);

    GrSurfaceDesc texDesc;
    texDesc.fWidth = size;
    texDesc.fHeight = 1;
    texDesc.fConfig = kAlpha_8_GrPixelConfig;

    static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
    GrUniqueKey key;
    GrUniqueKey::Builder builder(&key, kDomain, 2);
    // The profile curve varies with both the sigma of the Gaussian and the size of the
    // disk. Quantizing to 16.16 should be close enough though.
    builder[0] = SkScalarToFixed(sigma);
    builder[1] = SkScalarToFixed(halfWH);
    builder.finish();

    GrTexture *blurProfile = textureProvider->findAndRefTextureByUniqueKey(key);

    if (!blurProfile) {
        SkAutoTDeleteArray<uint8_t> profile(create_profile(halfWH, sigma));

        blurProfile = textureProvider->createTexture(texDesc, SkBudgeted::kYes, profile.get(), 0);
        if (blurProfile) {
            textureProvider->assignUniqueKeyToTexture(key, blurProfile);
        }
    }

    return blurProfile;
}

GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor);

const GrFragmentProcessor* GrCircleBlurFragmentProcessor::TestCreate(GrProcessorTestData* d) {
    SkScalar wh = d->fRandom->nextRangeScalar(100.f, 1000.f);
    SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f);
    SkRect circle = SkRect::MakeWH(wh, wh);
    return GrCircleBlurFragmentProcessor::Create(d->fContext->textureProvider(), circle, sigma);
}

#endif
