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

layout(key) in GrClipEdgeType edgeType;
in float2 center;
in float radius;

float2 prevCenter;
float prevRadius = -1;
// The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular
// fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills.
uniform float4 circle;

@make {
    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkPoint center,
                                                     float radius) {
        // A radius below half causes the implicit insetting done by this processor to become
        // inverted. We could handle this case by making the processor code more complicated.
        if (radius < .5f && GrProcessorEdgeTypeIsInverseFill(edgeType)) {
            return nullptr;
        }
        return std::unique_ptr<GrFragmentProcessor>(new GrCircleEffect(edgeType, center, radius));
    }
}

@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag }

@setData(pdman) {
    if (radius != prevRadius || center != prevCenter) {
        SkScalar effectiveRadius = radius;
        if (GrProcessorEdgeTypeIsInverseFill((GrClipEdgeType) edgeType)) {
            effectiveRadius -= 0.5f;
            // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the shader.
            effectiveRadius = std::max(0.001f, effectiveRadius);
        } else {
            effectiveRadius += 0.5f;
        }
        pdman.set4f(circle, center.fX, center.fY, effectiveRadius,
                    SkScalarInvert(effectiveRadius));
        prevCenter = center;
        prevRadius = radius;
    }
}

void main() {
    // TODO: Right now the distance to circle calculation is performed in a space normalized to the
    // radius and then denormalized. This is to mitigate overflow on devices that don't have full
    // float.
    half d;
    @if (edgeType == GrClipEdgeType::kInverseFillBW ||
         edgeType == GrClipEdgeType::kInverseFillAA) {
        d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);
    } else {
        d = half((1.0 - length((circle.xy - sk_FragCoord.xy) *  circle.w)) * circle.z);
    }
    @if (edgeType == GrClipEdgeType::kFillAA ||
         edgeType == GrClipEdgeType::kInverseFillAA ||
         edgeType == GrClipEdgeType::kHairlineAA) {
        sk_OutColor = sk_InColor * saturate(d);
    } else {
        sk_OutColor = d > 0.5 ? sk_InColor : half4(0);
    }
}

@test(testData) {
    SkPoint center;
    center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
    center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
    SkScalar radius = testData->fRandom->nextRangeF(1.f, 1000.f);
    GrClipEdgeType et;
    do {
        et = (GrClipEdgeType) testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
    } while (GrClipEdgeType::kHairlineAA == et);
    return GrCircleEffect::Make(et, center, radius);
}
