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

#ifndef GrPipeline_DEFINED
#define GrPipeline_DEFINED

#include "GrColor.h"
#include "GrFragmentProcessor.h"
#include "GrNonAtomicRef.h"
#include "GrPendingProgramElement.h"
#include "GrProcessorSet.h"
#include "GrProgramDesc.h"
#include "GrRect.h"
#include "GrRenderTarget.h"
#include "GrScissorState.h"
#include "GrUserStencilSettings.h"
#include "GrWindowRectsState.h"
#include "SkMatrix.h"
#include "SkRefCnt.h"
#include "effects/GrCoverageSetOpXP.h"
#include "effects/GrDisableColorXP.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"

class GrAppliedClip;
class GrDeviceCoordTexture;
class GrOp;
class GrPipelineBuilder;
class GrRenderTargetContext;

/**
 * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
 * class, and contains all data needed to set the state for a gpu draw.
 */
class GrPipeline : public GrNonAtomicRef<GrPipeline> {
public:
    ///////////////////////////////////////////////////////////////////////////
    /// @name Creation

    enum Flags {
        /**
         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
         * the 3D API.
         */
        kHWAntialias_Flag = 0x1,
        /**
         * Modifies the vertex shader so that vertices will be positioned at pixel centers.
         */
        kSnapVerticesToPixelCenters_Flag = 0x2,
        /** Disables conversion to sRGB from linear when writing to a sRGB destination. */
        kDisableOutputConversionToSRGB_Flag = 0x4,
        /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */
        kAllowSRGBInputs_Flag = 0x8,
    };

    static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
        uint32_t flags = 0;
        if (paint.getAllowSRGBInputs()) {
            flags |= kAllowSRGBInputs_Flag;
        }
        if (paint.getDisableOutputConversionToSRGB()) {
            flags |= kDisableOutputConversionToSRGB_Flag;
        }
        return flags;
    }

    enum ScissorState : bool {
        kEnabled = true,
        kDisabled = false
    };

    struct InitArgs {
        uint32_t fFlags = 0;
        const GrProcessorSet* fProcessors = nullptr;  // Must be finalized
        const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
        const GrAppliedClip* fAppliedClip = nullptr;
        GrRenderTarget* fRenderTarget = nullptr;
        const GrCaps* fCaps = nullptr;
        GrResourceProvider* fResourceProvider = nullptr;
        GrXferProcessor::DstProxy fDstProxy;
    };

    /**
     *  Graphics state that can change dynamically without creating a new pipeline.
     **/
    struct DynamicState {
        // Overrides the scissor rectangle (if scissor is enabled in the pipeline).
        // TODO: eventually this should be the only way to specify a scissor rectangle, as is the
        // case with the simple constructor.
        SkIRect fScissorRect;
    };

    /**
     * A Default constructed pipeline is unusable until init() is called.
     **/
    GrPipeline() = default;

    /**
     * Creates a simple pipeline with default settings and no processors. The provided blend mode
     * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
     * specify a scissor rectangle through the DynamicState struct.
     **/
    GrPipeline(GrRenderTarget*, ScissorState, SkBlendMode);

    GrPipeline(const InitArgs& args) { this->init(args); }

    /** (Re)initializes a pipeline. After initialization the pipeline can be used. */
    void init(const InitArgs&);

    /** True if the pipeline has been initialized. */
    bool isInitialized() const { return SkToBool(fRenderTarget.get()); }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name Comparisons

    /**
     * Returns true if these pipelines are equivalent.  Coord transforms may be applied either on
     * the GPU or the CPU. When we apply them on the CPU then the matrices need not agree in order
     * to combine draws. Therefore we take a param that indicates whether coord transforms should be
     * compared."
     */
    static bool AreEqual(const GrPipeline& a, const GrPipeline& b);

    /**
     * Allows a GrOp subclass to determine whether two GrOp instances can combine. This is a
     * stricter test than isEqual because it also considers blend barriers when the two ops'
     * bounds overlap
     */
    static bool CanCombine(const GrPipeline& a, const SkRect& aBounds,
                           const GrPipeline& b, const SkRect& bBounds,
                           const GrCaps& caps)  {
        if (!AreEqual(a, b)) {
            return false;
        }
        if (a.xferBarrierType(caps)) {
            return !GrRectsTouchOrOverlap(aBounds, bBounds);
        }
        return true;
    }

    /// @}

    ///////////////////////////////////////////////////////////////////////////
    /// @name GrFragmentProcessors

    // Make the renderTarget's GrOpList (if it exists) be dependent on any
    // GrOpLists in this pipeline
    void addDependenciesTo(GrRenderTargetProxy*) const;

    int numColorFragmentProcessors() const { return fNumColorProcessors; }
    int numCoverageFragmentProcessors() const {
        return fFragmentProcessors.count() - fNumColorProcessors;
    }
    int numFragmentProcessors() const { return fFragmentProcessors.count(); }

    const GrXferProcessor& getXferProcessor() const {
        if (fXferProcessor) {
            return *fXferProcessor.get();
        } else {
            // A null xp member means the common src-over case. GrXferProcessor's ref'ing
            // mechanism is not thread safe so we do not hold a ref on this global.
            return GrPorterDuffXPFactory::SimpleSrcOverXP();
        }
    }

    /**
     * If the GrXferProcessor uses a texture to access the dst color, then this returns that
     * texture and the offset to the dst contents within that texture.
     */
    GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
        if (offset) {
            *offset = fDstTextureOffset;
        }
        return fDstTextureProxy.get();
    }

    GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
        if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
            return dstProxy->priv().peekTexture();
        }

        return nullptr;
    }

    const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
        SkASSERT(idx < this->numColorFragmentProcessors());
        return *fFragmentProcessors[idx].get();
    }

    const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
        SkASSERT(idx < this->numCoverageFragmentProcessors());
        return *fFragmentProcessors[fNumColorProcessors + idx].get();
    }

    const GrFragmentProcessor& getFragmentProcessor(int idx) const {
        return *fFragmentProcessors[idx].get();
    }

    /// @}

    /**
     * Retrieves the currently set render-target.
     *
     * @return    The currently set render target.
     */
    GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }

    const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }

    const GrScissorState& getScissorState() const { return fScissorState; }

    const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }

    bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
    bool snapVerticesToPixelCenters() const {
        return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
    }
    bool getDisableOutputConversionToSRGB() const {
        return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
    }
    bool getAllowSRGBInputs() const {
        return SkToBool(fFlags & kAllowSRGBInputs_Flag);
    }
    bool hasStencilClip() const {
        return SkToBool(fFlags & kHasStencilClip_Flag);
    }
    bool isStencilEnabled() const {
        return SkToBool(fFlags & kStencilEnabled_Flag);
    }
    bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }

    GrXferBarrierType xferBarrierType(const GrCaps& caps) const;

    static SkString DumpFlags(uint32_t flags) {
        if (flags) {
            SkString result;
            if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) {
                result.append("Snap vertices to pixel center.\n");
            }
            if (flags & GrPipeline::kHWAntialias_Flag) {
                result.append("HW Antialiasing enabled.\n");
            }
            if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) {
                result.append("Disable output conversion to sRGB.\n");
            }
            if (flags & GrPipeline::kAllowSRGBInputs_Flag) {
                result.append("Allow sRGB Inputs.\n");
            }
            return result;
        }
        return SkString("No pipeline flags\n");
    }

private:
    void markAsBad() { fFlags |= kIsBad_Flag; }

    /** This is a continuation of the public "Flags" enum. */
    enum PrivateFlags {
        kHasStencilClip_Flag = 0x10,
        kStencilEnabled_Flag = 0x20,
        kIsBad_Flag = 0x40,
    };

    using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>;
    using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
    using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
    using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;

    DstTextureProxy fDstTextureProxy;
    SkIPoint fDstTextureOffset;
    RenderTarget fRenderTarget;
    GrScissorState fScissorState;
    GrWindowRectsState fWindowRectsState;
    const GrUserStencilSettings* fUserStencilSettings;
    uint16_t fFlags;
    sk_sp<const GrXferProcessor> fXferProcessor;
    FragmentProcessorArray fFragmentProcessors;

    // This value is also the index in fFragmentProcessors where coverage processors begin.
    int fNumColorProcessors;

    typedef SkRefCnt INHERITED;
};

#endif
