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

#ifndef skgpu_Blend_DEFINED
#define skgpu_Blend_DEFINED

#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/SkColorData.h"

enum class SkBlendMode;
class SkString;

namespace skgpu {

/**
 * Equations for alpha-blending.
 */
enum class BlendEquation : uint8_t {
    // Basic blend equations.
    kAdd,             //<! Cs*S + Cd*D
    kSubtract,        //<! Cs*S - Cd*D
    kReverseSubtract, //<! Cd*D - Cs*S

    // Advanced blend equations. These are described in the SVG and PDF specs.
    kScreen,
    kOverlay,
    kDarken,
    kLighten,
    kColorDodge,
    kColorBurn,
    kHardLight,
    kSoftLight,
    kDifference,
    kExclusion,
    kMultiply,
    kHSLHue,
    kHSLSaturation,
    kHSLColor,
    kHSLLuminosity,

    kIllegal,

    kFirstAdvanced = kScreen,
    kLast = kIllegal,
};

static const int kBlendEquationCnt = static_cast<int>(BlendEquation::kLast) + 1;

/**
 * Coefficients for alpha-blending.
 */
enum class BlendCoeff : uint8_t {
    kZero,    //<! 0
    kOne,     //<! 1
    kSC,      //<! src color
    kISC,     //<! one minus src color
    kDC,      //<! dst color
    kIDC,     //<! one minus dst color
    kSA,      //<! src alpha
    kISA,     //<! one minus src alpha
    kDA,      //<! dst alpha
    kIDA,     //<! one minus dst alpha
    kConstC,  //<! constant color
    kIConstC, //<! one minus constant color
    kS2C,
    kIS2C,
    kS2A,
    kIS2A,

    kIllegal,

    kLast = kIllegal,
};

struct BlendInfo {
    SkDEBUGCODE(SkString dump() const;)

    bool operator==(const BlendInfo& other) const {
        return fEquation == other.fEquation &&
               fSrcBlend == other.fSrcBlend &&
               fDstBlend == other.fDstBlend &&
               fBlendConstant == other.fBlendConstant &&
               fWritesColor == other.fWritesColor;
    }

    skgpu::BlendEquation fEquation = skgpu::BlendEquation::kAdd;
    skgpu::BlendCoeff    fSrcBlend = skgpu::BlendCoeff::kOne;
    skgpu::BlendCoeff    fDstBlend = skgpu::BlendCoeff::kZero;
    SkPMColor4f          fBlendConstant = SK_PMColor4fTRANSPARENT;
    bool                 fWritesColor = true;
};

static const int kBlendCoeffCnt = static_cast<int>(BlendCoeff::kLast) + 1;

static constexpr bool BlendCoeffRefsSrc(const BlendCoeff coeff) {
    return BlendCoeff::kSC == coeff || BlendCoeff::kISC == coeff || BlendCoeff::kSA == coeff ||
           BlendCoeff::kISA == coeff;
}

static constexpr bool BlendCoeffRefsDst(const BlendCoeff coeff) {
    return BlendCoeff::kDC == coeff || BlendCoeff::kIDC == coeff || BlendCoeff::kDA == coeff ||
           BlendCoeff::kIDA == coeff;
}

static constexpr bool BlendCoeffRefsSrc2(const BlendCoeff coeff) {
    return BlendCoeff::kS2C == coeff || BlendCoeff::kIS2C == coeff ||
           BlendCoeff::kS2A == coeff || BlendCoeff::kIS2A == coeff;
}

static constexpr bool BlendCoeffsUseSrcColor(BlendCoeff srcCoeff, BlendCoeff dstCoeff) {
    return BlendCoeff::kZero != srcCoeff || BlendCoeffRefsSrc(dstCoeff);
}

static constexpr bool BlendCoeffsUseDstColor(BlendCoeff srcCoeff,
                                             BlendCoeff dstCoeff,
                                             bool srcColorIsOpaque) {
    return BlendCoeffRefsDst(srcCoeff) ||
           (dstCoeff != BlendCoeff::kZero && !(dstCoeff == BlendCoeff::kISA && srcColorIsOpaque));
}

static constexpr bool BlendEquationIsAdvanced(BlendEquation equation) {
    return equation >= BlendEquation::kFirstAdvanced &&
           equation != BlendEquation::kIllegal;
}

static constexpr bool BlendModifiesDst(BlendEquation equation,
                                       BlendCoeff srcCoeff,
                                       BlendCoeff dstCoeff) {
    return (BlendEquation::kAdd != equation && BlendEquation::kReverseSubtract != equation) ||
            BlendCoeff::kZero != srcCoeff || BlendCoeff::kOne != dstCoeff;
}

static constexpr bool BlendCoeffRefsConstant(const BlendCoeff coeff) {
    return coeff == BlendCoeff::kConstC || coeff == BlendCoeff::kIConstC;
}

static constexpr bool BlendShouldDisable(BlendEquation equation,
                                         BlendCoeff srcCoeff,
                                         BlendCoeff dstCoeff) {
    return (BlendEquation::kAdd == equation || BlendEquation::kSubtract == equation) &&
            BlendCoeff::kOne == srcCoeff && BlendCoeff::kZero == dstCoeff;
}

/**
 * Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp)
 *
 * For "add" and "reverse subtract" the blend equation with f=coverage is:
 *
 *   D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D
 *      = f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
 *
 * (Let srcCoeff be negative for reverse subtract.) We can tweak alpha for coverage when the
 * following relationship holds:
 *
 *   (f*S) * srcCoeff' + D * dstCoeff' == f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
 *
 * (Where srcCoeff' and dstCoeff' have any reference to S pre-multiplied by f.)
 *
 * It's easy to see this works for the src term as long as srcCoeff' == srcCoeff (meaning srcCoeff
 * does not reference S). For the dst term, this will work as long as the following is true:
 *|
 *   dstCoeff' == f * dstCoeff + (1 - f)
 *   dstCoeff' == 1 - f * (1 - dstCoeff)
 *
 * By inspection we can see this will work as long as dstCoeff has a 1, and any other term in
 * dstCoeff references S.
 *
 * Moreover, if the blend doesn't modify the dst at all then it is ok to arbitrarily modify the src
 * color so folding in coverage is allowed.
 */
static constexpr bool BlendAllowsCoverageAsAlpha(BlendEquation equation,
                                                 BlendCoeff srcCoeff,
                                                 BlendCoeff dstCoeff) {
    return BlendEquationIsAdvanced(equation) ||
           !BlendModifiesDst(equation, srcCoeff, dstCoeff) ||
           ((BlendEquation::kAdd == equation || BlendEquation::kReverseSubtract == equation) &&
            !BlendCoeffRefsSrc(srcCoeff) &&
            (BlendCoeff::kOne == dstCoeff || BlendCoeff::kISC == dstCoeff ||
             BlendCoeff::kISA == dstCoeff));
}

/**
 * Returns the name of the SkSL built-in blend function for a SkBlendMode.
 */
const char* BlendFuncName(SkBlendMode mode);

/**
 * If a blend can be represented by `blend_porter_duff`, returns the associated blend constants as
 * an array of four floats. If not, returns an empty span.
 */
SkSpan<const float> GetPorterDuffBlendConstants(SkBlendMode mode);

/**
 * Returns a pair of "blend function + uniform data" for a particular SkBlendMode.
 * This allows us to use fewer unique functions when generating shaders, e.g. every Porter-Duff
 * blend can use the same function.
 */
struct ReducedBlendModeInfo {
    const char*         fFunction;
    SkSpan<const float> fUniformData;
};
ReducedBlendModeInfo GetReducedBlendModeInfo(SkBlendMode mode);

} // namespace skgpu

#endif // skgpu_Blend_DEFINED
