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

#ifndef GrXferProcessor_DEFINED
#define GrXferProcessor_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/private/SkAssert.h"
#include "include/private/SkMacros.h"
#include "include/private/SkTo.h"
#include "src/gpu/Blend.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrNonAtomicRef.h"
#include "src/gpu/ganesh/GrProcessor.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"

#include <memory>

class GrGLSLProgramDataManager;
class GrGLSLXPFragmentBuilder;
enum GrSurfaceOrigin : int;
enum class GrClampType;
enum class SkBlendMode;
namespace skgpu { class KeyBuilder; }
struct GrShaderCaps;

/**
 * Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes
 * required after a pixel has been written, before it can be safely read again.
 */
enum GrXferBarrierType {
    kNone_GrXferBarrierType = 0, //<! No barrier is required
    kTexture_GrXferBarrierType,  //<! Required when a shader reads and renders to the same texture.
    kBlend_GrXferBarrierType,    //<! Required by certain blend extensions.
};
/** Should be able to treat kNone as false in boolean expressions */
static_assert(SkToBool(kNone_GrXferBarrierType) == false);

// Flag version of the above enum.
enum class GrXferBarrierFlags {
    kNone    = 0,
    kTexture = 1 << 0,
    kBlend   = 1 << 1,
};

SK_MAKE_BITFIELD_CLASS_OPS(GrXferBarrierFlags)

/**
 * GrXferProcessor is responsible for implementing the xfer mode that blends the src color and dst
 * color, and for applying any coverage. It does this by emitting fragment shader code and
 * controlling the fixed-function blend state. When dual-source blending is available, it may also
 * write a secondary fragment shader output color. GrXferProcessor has two modes of operation:
 *
 * Dst read: When allowed by the backend API, or when supplied a texture of the destination, the
 * GrXferProcessor may read the destination color. While operating in this mode, the subclass only
 * provides shader code that blends the src and dst colors, and the base class applies coverage.
 *
 * No dst read: When not performing a dst read, the subclass is given full control of the fixed-
 * function blend state and/or secondary output, and is responsible to apply coverage on its own.
 *
 * A GrXferProcessor is never installed directly into our draw state, but instead is created from a
 * GrXPFactory once we have finalized the state of our draw.
 */
class GrXferProcessor : public GrProcessor, public GrNonAtomicRef<GrXferProcessor> {
public:
    /**
     * Every GrXferProcessor must be capable of creating a subclass of ProgramImpl. The ProgramImpl
     * emits the shader code combines determines the fragment shader output(s) from the color and
     * coverage FP outputs, is attached to the generated backend API pipeline/program, and used to
     * extract uniform data from GrXferProcessor instances.
     */
    class ProgramImpl;

    /**
     * Adds a key on the skgpu::KeyBuilder calls onAddToKey(...) to get the specific subclass's key.
     */
    void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const;

    /** Returns a new instance of the appropriate *GL* implementation class
        for the given GrXferProcessor; caller is responsible for deleting
        the object. */
    virtual std::unique_ptr<ProgramImpl> makeProgramImpl() const = 0;

    /**
     * Returns the barrier type, if any, that this XP will require. Note that the possibility
     * that a kTexture type barrier is required is handled by the GrPipeline and need not be
     * considered by subclass overrides of this function.
     */
    virtual GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
        return kNone_GrXferBarrierType;
    }

    inline skgpu::BlendInfo getBlendInfo() const {
        skgpu::BlendInfo blendInfo;
        if (!this->willReadDstColor()) {
            this->onGetBlendInfo(&blendInfo);
        }
        return blendInfo;
    }

    bool willReadDstColor() const { return fWillReadDstColor; }

    /**
     * Returns whether or not this xferProcossor will set a secondary output to be used with dual
     * source blending.
     */
    bool hasSecondaryOutput() const;

    bool isLCD() const { return fIsLCD; }

    /** Returns true if this and other processor conservatively draw identically. It can only return
        true when the two processor are of the same subclass (i.e. they return the same object from
        from getFactory()).

        A return value of true from isEqual() should not be used to test whether the processor would
        generate the same shader code. To test for identical code generation use addToKey.
      */

    bool isEqual(const GrXferProcessor& that) const {
        if (this->classID() != that.classID()) {
            return false;
        }
        if (this->fWillReadDstColor != that.fWillReadDstColor) {
            return false;
        }
        if (fIsLCD != that.fIsLCD) {
            return false;
        }
        return this->onIsEqual(that);
    }

protected:
    GrXferProcessor(ClassID classID);
    GrXferProcessor(ClassID classID, bool willReadDstColor, GrProcessorAnalysisCoverage);

private:
    /**
     * Adds a key on the skgpu::KeyBuilder that reflects any variety in the code that may be emitted
     * by the xfer processor subclass.
     */
    virtual void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const = 0;

    /**
     * If we are not performing a dst read, returns whether the subclass will set a secondary
     * output. When using dst reads, the base class controls the secondary output and this method
     * will not be called.
     */
    virtual bool onHasSecondaryOutput() const { return false; }

    /**
     * If we are not performing a dst read, retrieves the fixed-function blend state required by the
     * subclass. When using dst reads, the base class controls the fixed-function blend state and
     * this method will not be called. The BlendInfo struct comes initialized to "no blending".
     */
    virtual void onGetBlendInfo(skgpu::BlendInfo*) const {}

    virtual bool onIsEqual(const GrXferProcessor&) const = 0;

    bool fWillReadDstColor;
    bool fIsLCD;

    using INHERITED = GrProcessor;
};

/**
 * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is
 * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the
 * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF along with all the
 * draw information to create a GrXferProcessor (XP) which can implement the desired blending for
 * the draw.
 *
 * Before the XP is created, the XPF is able to answer queries about what functionality the XPs it
 * creates will have. For example, can it create an XP that supports RGB coverage or will the XP
 * blend with the destination color.
 *
 * GrXPFactories are intended to be static immutable objects. We pass them around as raw pointers
 * and expect the pointers to always be valid and for the factories to be reusable and thread safe.
 * Equality is tested for using pointer comparison. GrXPFactory destructors must be no-ops.
 */

// In order to construct GrXPFactory subclass instances as constexpr the subclass, and therefore
// GrXPFactory, must be a literal type. One requirement is having a trivial destructor. This is ok
// since these objects have no need for destructors. However, GCC and clang throw a warning when a
// class has virtual functions and a non-virtual destructor. We suppress that warning here and
// for the subclasses.
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#endif
class GrXPFactory {
public:
    enum class AnalysisProperties : unsigned {
        kNone = 0x0,
        /**
         * The fragment shader will require the destination color.
         */
        kReadsDstInShader = 0x1,
        /**
         * The op may apply coverage as alpha and still blend correctly.
         */
        kCompatibleWithCoverageAsAlpha = 0x2,
        /**
         * The color input to the GrXferProcessor will be ignored.
         */
        kIgnoresInputColor = 0x4,
        /**
         * The destination color will be provided to the fragment processor using a texture. This is
         * additional information about the implementation of kReadsDstInShader.
         */
        kRequiresDstTexture = 0x10,
        /**
         * If set, each pixel can only be touched once during a draw (e.g., because we have a dst
         * texture or because we need an xfer barrier).
         */
        kRequiresNonOverlappingDraws = 0x20,
        /**
         * If set the draw will use fixed function non coherent advanced blends.
         */
        kUsesNonCoherentHWBlending = 0x40,
        /**
         * If set, the existing dst value has no effect on the final output.
         */
        kUnaffectedByDstValue = 0x80,
    };
    SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties);

    static sk_sp<const GrXferProcessor> MakeXferProcessor(const GrXPFactory*,
                                                          const GrProcessorAnalysisColor&,
                                                          GrProcessorAnalysisCoverage,
                                                          const GrCaps& caps,
                                                          GrClampType);

    static AnalysisProperties GetAnalysisProperties(const GrXPFactory*,
                                                    const GrProcessorAnalysisColor&,
                                                    const GrProcessorAnalysisCoverage&,
                                                    const GrCaps&,
                                                    GrClampType);

    static const GrXPFactory* FromBlendMode(SkBlendMode);

protected:
    constexpr GrXPFactory() {}

private:
    virtual sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
                                                           GrProcessorAnalysisCoverage,
                                                           const GrCaps&,
                                                           GrClampType) const = 0;

    /**
     * Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be
     * inferred by the base class based on kReadsDstInShader and the caps.
     */
    virtual AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
                                                  const GrProcessorAnalysisCoverage&,
                                                  const GrCaps&,
                                                  GrClampType) const = 0;
};
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

SK_MAKE_BITFIELD_CLASS_OPS(GrXPFactory::AnalysisProperties)

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

class GrXferProcessor::ProgramImpl {
public:
    virtual ~ProgramImpl() = default;

    using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;

    struct EmitArgs {
        EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
                 GrGLSLUniformHandler* uniformHandler,
                 const GrShaderCaps* caps,
                 const GrXferProcessor& xp,
                 const char* inputColor,
                 const char* inputCoverage,
                 const char* outputPrimary,
                 const char* outputSecondary,
                 const SamplerHandle dstTextureSamplerHandle,
                 GrSurfaceOrigin dstTextureOrigin,
                 const skgpu::Swizzle& writeSwizzle)
                : fXPFragBuilder(fragBuilder)
                , fUniformHandler(uniformHandler)
                , fShaderCaps(caps)
                , fXP(xp)
                , fInputColor(inputColor ? inputColor : "half4(1.0)")
                , fInputCoverage(inputCoverage)
                , fOutputPrimary(outputPrimary)
                , fOutputSecondary(outputSecondary)
                , fDstTextureSamplerHandle(dstTextureSamplerHandle)
                , fDstTextureOrigin(dstTextureOrigin)
                , fWriteSwizzle(writeSwizzle) {}
        GrGLSLXPFragmentBuilder* fXPFragBuilder;
        GrGLSLUniformHandler* fUniformHandler;
        const GrShaderCaps* fShaderCaps;
        const GrXferProcessor& fXP;
        const char* fInputColor;
        const char* fInputCoverage;
        const char* fOutputPrimary;
        const char* fOutputSecondary;
        const SamplerHandle fDstTextureSamplerHandle;
        GrSurfaceOrigin fDstTextureOrigin;
        skgpu::Swizzle fWriteSwizzle;
    };
    /**
     * This is similar to emitCode() in the base class, except it takes a full shader builder.
     * This allows the effect subclass to emit vertex code.
     */
    void emitCode(const EmitArgs&);

    /** A ProgramImpl instance can be reused with any GrXferProcessor that produces the same key.
        This function reads data from a GrXferProcessor and uploads any uniform variables required
        by the shaders created in emitCode(). The GrXferProcessor parameter is guaranteed to be of
        the same type that created this ProgramImpl and to have an identical processor key as the
        one that created this ProgramImpl. This function calls onSetData on the subclass of
        ProgramImpl.
     */
    void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp);

protected:
    ProgramImpl() = default;

    static void DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
                                          const char* srcCoverage,
                                          const char* dstColor,
                                          const char* outColor,
                                          const char* outColorSecondary,
                                          const GrXferProcessor& proc);

private:
    /**
     * Called by emitCode() when the XP will not be performing a dst read. This method is
     * responsible for both blending and coverage. A subclass only needs to implement this method if
     * it can construct a GrXferProcessor that will not read the dst color.
     */
    virtual void emitOutputsForBlendState(const EmitArgs&) {
        SK_ABORT("emitOutputsForBlendState not implemented.");
    }

    /**
     * Called by emitCode() when the XP will perform a dst read. This method only needs to supply
     * the blending logic. The base class applies coverage. A subclass only needs to implement this
     * method if it can construct a GrXferProcessor that reads the dst color.
     */
    virtual void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder*,
                                         GrGLSLUniformHandler*,
                                         const char* srcColor,
                                         const char* srcCoverage,
                                         const char* dstColor,
                                         const char* outColor,
                                         const char* outColorSecondary,
                                         const GrXferProcessor&) {
        SK_ABORT("emitBlendCodeForDstRead not implemented.");
    }

    virtual void emitWriteSwizzle(GrGLSLXPFragmentBuilder*,
                                  const skgpu::Swizzle&,
                                  const char* outColor,
                                  const char* outColorSecondary) const;

    virtual void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) {}
};

#endif
