// Graphite-specific fragment shader code

half4 sk_error() {
    return half4(1.0, 0.0, 1.0, 1.0);
}

half4 sk_solid_shader(float4 colorParam) {
    return half4(colorParam);
}

// The localMatrix is passed to the child by the glue code. This snippet just needs to bubble the
// child's output back up. 'localMatrix' is passed in to be consistent w/ the default glue code.
half4 sk_local_matrix_shader(float4x4 localMatrix, half4 childResult) {
    return childResult;
}

float $tile(int tm, float f, float min, float max, float normalizer) {
    const int kClamp         = 0;
    const int kRepeat        = 1;
    const int kMirrorRepeat  = 2;
    const int kClampToBorder = 3;

    if (tm == kClamp) {
        return clamp(f, min, max) / normalizer;
    } else if (tm == kRepeat) {
        float length = max - min;
        return (mod(f - min, length) + min) / normalizer;
    } else if (tm == kMirrorRepeat) {
        float length = max - min;
        float length2 = 2 * length;
        float tmp = mod(f - min, length2);
        return (mix(tmp, length2 - tmp, step(length, tmp)) + min) / normalizer;
    } else { // kClampToBorder
        // For now, just clamp.
        return clamp(f, min, max) / normalizer;
    }
}

float2 sk_compute_coords(float4x4 dev2Local,
                         float4 subset,
                         int tmX,
                         int tmY,
                         int imgWidth,
                         int imgHeight) {
    float4 localCoords = dev2Local * sk_FragCoord;
    float2 coords = float2($tile(tmX, localCoords.x, subset.x, subset.z, float(imgWidth)),
                           $tile(tmY, localCoords.y, subset.y, subset.w, float(imgHeight)));
    return coords;
}

half4 sk_clamp_grad_4(float4 colorsParam[4], float offsetsParam[4], float t) {
    float4 result = colorsParam[0];
    result = mix(result, colorsParam[1],
                 clamp((t-offsetsParam[0])/(offsetsParam[1]-offsetsParam[0]),
                       0, 1));
    result = mix(result, colorsParam[2],
                 clamp((t-offsetsParam[1])/(offsetsParam[2]-offsetsParam[1]),
                       0, 1));
    result = mix(result, colorsParam[3],
                 clamp((t-offsetsParam[2])/(offsetsParam[3]-offsetsParam[2]),
                       0, 1));
    return half4(result);
}

half4 sk_linear_grad_4_shader(float4x4 dev2Local,
                              float4 colorsParam[4],
                              float offsetsParam[4],
                              float2 point0Param,
                              float2 point1Param,
                              float radius0Param,
                              float radius1Param,
                              float2 padding) {
    float2 pos = (dev2Local * sk_FragCoord).xy;
    float2 delta = point1Param - point0Param;
    float2 pt = pos - point0Param;
    float t = dot(pt, delta) / dot(delta, delta);
    return sk_clamp_grad_4(colorsParam, offsetsParam, t);
}

half4 sk_radial_grad_4_shader(float4x4 dev2Local,
                              float4 colorsParam[4],
                              float offsetsParam[4],
                              float2 centerParam,
                              float radiusParam,
                              float padding) {
    float2 pos = (dev2Local * sk_FragCoord).xy;
    float2 pt = pos - centerParam;
    float t = length(pt) / radiusParam;
    return sk_clamp_grad_4(colorsParam, offsetsParam, t);
}

half4 sk_sweep_grad_4_shader(float4x4 dev2Local,
                             float4 colorsParam[4],
                             float offsetsParam[4],
                             float2 centerParam,
                             float biasParam,
                             float scaleParam) {
    float2 pos = (dev2Local * sk_FragCoord).xy;
    float2 pt = pos - centerParam;

    // Some devices incorrectly implement atan2(y,x) as atan(y/x). In actuality it is
    // atan2(y,x) = 2 * atan(y / (sqrt(x^2 + y^2) + x)). To work around this we pass in
    // (sqrt(x^2 + y^2) + x) as the second parameter to atan2 in these cases. We let the device
    // handle the undefined behavior if the second parameter is 0, instead of doing the divide
    // ourselves and calling atan with the quotient.
    float angle = sk_Caps.atan2ImplementedAsAtanYOverX ? 2 * atan(-pt.y, length(pt) - pt.x)
                                                       : atan(-pt.y, -pt.x);

    // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
    float t = (angle * 0.1591549430918 + 0.5 + biasParam) * scaleParam;
    return sk_clamp_grad_4(colorsParam, offsetsParam, t);
}

half4 sk_blend(int blendMode, half4 src, half4 dst) {
    const int kClear      = 0;
    const int kSrc        = 1;
    const int kDst        = 2;
    const int kSrcOver    = 3;
    const int kDstOver    = 4;
    const int kSrcIn      = 5;
    const int kDstIn      = 6;
    const int kSrcOut     = 7;
    const int kDstOut     = 8;
    const int kSrcATop    = 9;
    const int kDstATop    = 10;
    const int kXor        = 11;
    const int kPlus       = 12;
    const int kModulate   = 13;
    const int kScreen     = 14;
    const int kOverlay    = 15;
    const int kDarken     = 16;
    const int kLighten    = 17;
    const int kColorDodge = 18;
    const int kColorBurn  = 19;
    const int kHardLight  = 20;
    const int kSoftLight  = 21;
    const int kDifference = 22;
    const int kExclusion  = 23;
    const int kMultiply   = 24;
    const int kHue        = 25;
    const int kSaturation = 26;
    const int kColor      = 27;
    const int kLuminosity = 28;

    switch (blendMode) {
        case kClear:      { return blend_clear(src, dst); }
        case kSrc:        { return blend_src(src, dst); }
        case kDst:        { return blend_dst(src, dst); }
        case kSrcOver:    { return blend_porter_duff(src, dst, half4(1, 0,  0, -1)); }
        case kDstOver:    { return blend_porter_duff(src, dst, half4(0, 1, -1,  0)); }
        case kSrcIn:      { return blend_porter_duff(src, dst, half4(0, 0,  1,  0)); }
        case kDstIn:      { return blend_porter_duff(src, dst, half4(0, 0,  0,  1)); }
        case kSrcOut:     { return blend_porter_duff(src, dst, half4(0, 0, -1,  0)); }
        case kDstOut:     { return blend_porter_duff(src, dst, half4(0, 0,  0, -1)); }
        case kSrcATop:    { return blend_porter_duff(src, dst, half4(0, 0,  1, -1)); }
        case kDstATop:    { return blend_porter_duff(src, dst, half4(0, 0, -1,  1)); }
        case kXor:        { return blend_porter_duff(src, dst, half4(0, 0, -1, -1)); }
        case kPlus:       { return blend_porter_duff(src, dst, half4(1, 1,  0,  0)); }
        case kModulate:   { return blend_modulate(src, dst); }
        case kScreen:     { return blend_screen(src, dst); }
        case kOverlay:    { return blend_overlay(src, dst, /*flip=*/0); }
        case kDarken:     { return blend_darken(src, dst, /*mode=*/1); }
        case kLighten:    { return blend_darken(src, dst, /*mode=*/-1); }
        case kColorDodge: { return blend_color_dodge(src, dst); }
        case kColorBurn:  { return blend_color_burn(src, dst); }
        case kHardLight:  { return blend_overlay(src, dst, /*flip=*/1); }
        case kSoftLight:  { return blend_soft_light(src, dst); }
        case kDifference: { return blend_difference(src, dst); }
        case kExclusion:  { return blend_exclusion(src, dst); }
        case kMultiply:   { return blend_multiply(src, dst); }
        case kHue:        { return blend_hslc(src, dst, /*flipSat=*/half2(0, 1)); }
        case kSaturation: { return blend_hslc(src, dst, /*flipSat=*/half2(1)); }
        case kColor:      { return blend_hslc(src, dst, /*flipSat=*/half2(0)); }
        case kLuminosity: { return blend_hslc(src, dst, /*flipSat=*/half2(1, 0)); }
        default: return half4(0);  // Avoids 'blend can exit without returning a value' error
    }
}

half4 sk_blend_shader(int blendMode, int pad0, int pad1, int pad2, half4 child0, half4 child1) {
    return sk_blend(blendMode, child1, child0);
}
