/*
 * Copyright 2022 Rive
 */

// From the KHR_blend_equation_advanced spec:
//
//    The advanced blend equations are those listed in tables X.1 and X.2.  When
//    using one of these equations, blending is performed according to the
//    following equations:
//
//      R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad)
//      G = f(Gs',Gd')*p0(As,Ad) + Y*Gs'*p1(As,Ad) + Z*Gd'*p2(As,Ad)
//      B = f(Bs',Bd')*p0(As,Ad) + Y*Bs'*p1(As,Ad) + Z*Bd'*p2(As,Ad)
//      A =          X*p0(As,Ad) +     Y*p1(As,Ad) +     Z*p2(As,Ad)
//
//    where the function f and terms X, Y, and Z are specified in the table.
//    The R, G, and B components of the source color used for blending are
//    considered to have been premultiplied by the A component prior to
//    blending.  The base source color (Rs',Gs',Bs') is obtained by dividing
//    through by the A component:
//
//      (Rs', Gs', Bs') =
//        (0, 0, 0),              if As == 0
//        (Rs/As, Gs/As, Bs/As),  otherwise
//
//    The destination color components are always considered to have been
//    premultiplied by the destination A component and the base destination
//    color (Rd', Gd', Bd') is obtained by dividing through by the A component:
//
//      (Rd', Gd', Bd') =
//        (0, 0, 0),               if Ad == 0
//        (Rd/Ad, Gd/Ad, Bd/Ad),   otherwise
//
//    When blending using advanced blend equations, we expect that the R, G, and
//    B components of premultiplied source and destination color inputs be
//    stored as the product of non-premultiplied R, G, and B components and the
//    A component of the color.  If any R, G, or B component of a premultiplied
//    input color is non-zero and the A component is zero, the color is
//    considered ill-formed, and the corresponding component of the blend result
//    will be undefined.
//
//    The weighting functions p0, p1, and p2 are defined as follows:
//
//      p0(As,Ad) = As*Ad
//      p1(As,Ad) = As*(1 - Ad)
//      p2(As,Ad) = Ad*(1 - As)
//
//    In these functions, the A components of the source and destination colors
//    are taken to indicate the portion of the pixel covered by the fragment
//    (source) and the fragments previously accumulated in the pixel
//    (destination).  The functions p0, p1, and p2 approximate the relative
//    portion of the pixel covered by the intersection of the source and
//    destination, covered only by the source, and covered only by the
//    destination, respectively.  The equations defined here assume that there
//    is no correlation between the source and destination coverage.
//

#ifdef @FRAGMENT

#ifdef @ENABLE_KHR_BLEND
layout(
#ifdef @ENABLE_HSL_BLEND_MODES
    blend_support_all_equations
#else
    blend_support_multiply,
    blend_support_screen,
    blend_support_overlay,
    blend_support_darken,
    blend_support_lighten,
    blend_support_colordodge,
    blend_support_colorburn,
    blend_support_hardlight,
    blend_support_softlight,
    blend_support_difference,
    blend_support_exclusion
#endif
    ) out;
#endif // ENABLE_KHR_BLEND

#ifdef @ENABLE_ADVANCED_BLEND
#ifdef @ENABLE_HSL_BLEND_MODES
// When using one of the HSL blend equations in table X.2 as the blend equation,
// the blend coefficients are effectively obtained by converting both the
// non-premultiplied source and destination colors to the HSL (hue, saturation,
// luminosity) color space, generating a new HSL color by selecting H, S, and L
// components from the source or destination according to the blend equation,
// and then converting the result back to RGB. The HSL blend equations are only
// well defined when the values of the input color components are in the range
// [0..1].
half minv3(half3 c) { return min(min(c.r, c.g), c.b); }
half maxv3(half3 c) { return max(max(c.r, c.g), c.b); }
half lumv3(half3 c) { return dot(c, make_half3(.30, .59, .11)); }
half satv3(half3 c) { return maxv3(c) - minv3(c); }

// If any color components are outside [0,1], adjust the color to get the
// components in range.
half3 clip_color(half3 color)
{
    half lum = lumv3(color);
    half mincol = minv3(color);
    half maxcol = maxv3(color);
    if (mincol < .0)
        color = lum + ((color - lum) * lum) / (lum - mincol);
    if (maxcol > 1.)
        color = lum + ((color - lum) * (1. - lum)) / (maxcol - lum);
    return color;
}

// Take the base RGB color <cbase> and override its luminosity with that of the
// RGB color <clum>.
half3 set_lum(half3 cbase, half3 clum)
{
    half lbase = lumv3(cbase);
    half llum = lumv3(clum);
    half ldiff = llum - lbase;
    half3 color = cbase + make_half3(ldiff);
    return clip_color(color);
}

// Take the base RGB color <cbase> and override its saturation with that of the
// RGB color <csat>. The override the luminosity of the result with that of the
// RGB color <clum>.
half3 set_lum_sat(half3 cbase, half3 csat, half3 clum)
{
    half minbase = minv3(cbase);
    half sbase = satv3(cbase);
    half ssat = satv3(csat);
    half3 color;
    if (sbase > .0)
    {
        // Equivalent (modulo rounding errors) to setting the smallest (R,G,B)
        // component to 0, the largest to <ssat>, and interpolating the "middle"
        // component based on its original value relative to the
        // smallest/largest.
        color = (cbase - minbase) * ssat / sbase;
    }
    else
    {
        color = make_half3(.0);
    }
    return set_lum(color, clum);
}
#endif // ENABLE_HSL_BLEND_MODES

// The advanced blend coefficients are generated from un-multiplied RGB values,
// and control the look of each blend mode.
half3 advanced_blend_coeffs(half3 src, half4 dstPremul, ushort mode)
{
    half3 dst = unmultiply_rgb(dstPremul);
    half3 coeffs;
    switch (mode)
    {
#if defined(@RENDER_MODE_MSAA) && defined(@SPEC_CONST_NONE)
        // Normally MSAA filters out the "BLEND_SRC_OVER" draws via
        // specialization constants or #ifdefs. But when specialization
        // constants are disabled for WebGPU, we need to handle it here in the
        // switch.
        case BLEND_SRC_OVER:
            coeffs = src;
            break;
#endif
        case BLEND_MODE_MULTIPLY:
            coeffs = src.rgb * dst.rgb;
            break;
        case BLEND_MODE_SCREEN:
            coeffs = src.rgb + dst.rgb - src.rgb * dst.rgb;
            break;
        case BLEND_MODE_OVERLAY:
        {
            // This logic is equivalent to the following, but should be more
            // efficient, and works around a Vulkan Adreno 6-series Android 9/10
            // driver bug:
            //  f(Cs,Cd) = 2*Cs*Cd, if Cd <= 0.5
            //             1-2*(1-Cs)*(1-Cd), otherwise
            half3 sd = src * dst;
            coeffs = 2.0 * mix(sd,
                               src + dst - sd - 0.5,
                               greaterThan(dst, make_half3(0.5)));
            break;
        }
        case BLEND_MODE_DARKEN:
            coeffs = min(src.rgb, dst.rgb);
            break;
        case BLEND_MODE_LIGHTEN:
            coeffs = max(src.rgb, dst.rgb);
            break;
        case BLEND_MODE_COLORDODGE:
        {
            dstPremul.rgb = clamp(dstPremul.rgb, make_half3(.0), dstPremul.aaa);
            half3 denom =
                clamp(1. - src, make_half3(.0), make_half3(1.)) * dstPremul.a;
            coeffs = mix(min(make_half3(1.), dstPremul.rgb / denom),
                         sign(dstPremul.rgb),
                         equal(denom, make_half3(.0)));
            break;
        }
        case BLEND_MODE_COLORBURN:
        {
            src = clamp(src, make_half3(.0), make_half3(1.));
            dstPremul.rgb = clamp(dstPremul.rgb, make_half3(.0), dstPremul.aaa);
            if (dstPremul.a == .0)
                dstPremul.a = 1.;
            half3 numer = dstPremul.a - dstPremul.rgb;
            coeffs = 1. - mix(min(make_half3(1.), numer / (src * dstPremul.a)),
                              sign(numer),
                              equal(src, make_half3(.0)));
            break;
        }
        case BLEND_MODE_HARDLIGHT:
        {
            // This logic is equivalent to the following, but should be more
            // efficient, and works around a Vulkan Adreno 6-series Android 9/10
            // driver bug:
            //   f(Cs,Cd) = 2*Cs*Cd, if Cs <= 0.5
            //              1-2*(1-Cs)*(1-Cd), otherwise
            half3 sd = src * dst;
            coeffs = 2.0 * mix(sd,
                               src + dst - sd - 0.5,
                               greaterThan(src, make_half3(0.5)));
            break;
        }
        case BLEND_MODE_SOFTLIGHT:
        {
            // This logic is equivalent to the following, but should be more
            // efficient, and works around a Vulkan Adreno 6-series Android 9/10
            // driver bug:
            //   f(Cs,Cd) =
            //     Cd-(1-2*Cs)*Cd*(1-Cd),
            //       if Cs <= 0.5
            //     Cd+(2*Cs-1)*Cd*((16*Cd-12)*Cd+3),
            //       if Cs > 0.5 and Cd <= 0.25
            //     Cd+(2*Cs-1)*(sqrt(Cd)-Cd),
            //       if Cs > 0.5 and Cd > 0.25
            for (int i = 0; i < 3; ++i)
            {
                if (src[i] <= 0.5)
                    coeffs[i] = (1.0 - dst[i]);
                else if (dst[i] <= 0.25)
                    coeffs[i] = ((16.0 * dst[i] - 12.0) * dst[i] + 3.0);
                else
                    coeffs[i] = (inversesqrt(dst[i]) - 1.0);
            }

            coeffs = dst + dst * (2.0 * src - 1.0) * coeffs;
            break;
        }
        case BLEND_MODE_DIFFERENCE:
            coeffs = abs(dst.rgb - src.rgb);
            break;
        case BLEND_MODE_EXCLUSION:
            coeffs = src.rgb + dst.rgb - 2. * src.rgb * dst.rgb;
            break;
#ifdef @ENABLE_HSL_BLEND_MODES
        // The HSL blend equations are only well defined when the values of the
        // input color components are in the range [0..1].
        case BLEND_MODE_HUE:
            if (@ENABLE_HSL_BLEND_MODES)
            {
                src.rgb = clamp(src.rgb, make_half3(.0), make_half3(1.));
                coeffs = set_lum_sat(src.rgb, dst.rgb, dst.rgb);
            }
            break;
        case BLEND_MODE_SATURATION:
            if (@ENABLE_HSL_BLEND_MODES)
            {
                src.rgb = clamp(src.rgb, make_half3(.0), make_half3(1.));
                coeffs = set_lum_sat(dst.rgb, src.rgb, dst.rgb);
            }
            break;
        case BLEND_MODE_COLOR:
            if (@ENABLE_HSL_BLEND_MODES)
            {
                src.rgb = clamp(src.rgb, make_half3(.0), make_half3(1.));
                coeffs = set_lum(src.rgb, dst.rgb);
            }
            break;
        case BLEND_MODE_LUMINOSITY:
            if (@ENABLE_HSL_BLEND_MODES)
            {
                src.rgb = clamp(src.rgb, make_half3(.0), make_half3(1.));
                coeffs = set_lum(dst.rgb, src.rgb);
            }
            break;
#endif
    }
    return coeffs;
}

// Performs the given advanced blend operation with a solid RGB src color (no
// srcAlpha).
//
// NOTE: This method is sufficient for all blending because alpha in the src
// can be accounted for afterward using a standard src-over blend operation.
//
// e.g., dst = blend_src_over(
//           premultiply(advanced_color_blend(src.rgb, dstPremul)),
//           dstPremul)
INLINE half3 advanced_color_blend(half3 src, half4 dstPremul, ushort mode)
{
    // The weighting functions p0, p1, and p2 are defined as follows:
    //
    //     p0(As,Ad) = As*Ad
    //     p1(As,Ad) = As*(1 - Ad)
    //     p2(As,Ad) = Ad*(1 - As)
    //
    // Since srcAlpha (As) == 1, this simplifies to:
    //
    //     p0(As,Ad) = Ad
    //     p1(As,Ad) = (1 - Ad)
    //     p2(As,Ad) = 0
    //
    // Blending is performed according to the following equations:
    //
    //     R = coeffs(Rs',Rd')*p0 + Y*Rs'*p1 + Z*Rd'*p2
    //     G = coeffs(Gs',Gd')*p0 + Y*Gs'*p1 + Z*Gd'*p2
    //     B = coeffs(Bs',Bd')*p0 + Y*Bs'*p1 + Z*Bd'*p2
    //     A =               X*p0 +     Y*p1 +     Z*p2
    //
    // NOTE: (X,Y,Z) always == 1, so it is ignored in this implementation.
    //       Also, since (X,Y,Z) == 1, alpha simplifies to standard src-over
    //       rules: A = Ad * (1 - As) + As
    half3 coeffs = advanced_blend_coeffs(src, dstPremul, mode);

    // Because p0 is (Ad), p1 is (1 - Ad), and p2 is 0, this is equivalent to
    // that matrix multiply:
    return mix(src, coeffs, make_half3(dstPremul.a));
}
#endif // ENABLE_ADVANCED_BLEND

#endif // FRAGMENT
