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

#ifndef GrDrawTarget_DEFINED
#define GrDrawTarget_DEFINED

#include "GrBatchFlushState.h"
#include "GrClip.h"
#include "GrClipMaskManager.h"
#include "GrContext.h"
#include "GrPathProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "GrIndexBuffer.h"
#include "GrPathRendering.h"
#include "GrPipelineBuilder.h"
#include "GrPipeline.h"
#include "GrVertexBuffer.h"
#include "GrXferProcessor.h"

#include "batches/GrDrawBatch.h"

#include "SkClipStack.h"
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkStringUtils.h"
#include "SkStrokeRec.h"
#include "SkTArray.h"
#include "SkTLazy.h"
#include "SkTypes.h"
#include "SkXfermode.h"

class GrBatch;
class GrBatchFlushState;
class GrClip;
class GrCaps;
class GrPath;
class GrDrawPathBatchBase;
class GrPathRangeDraw;

class GrDrawTarget final : public SkRefCnt {
public:
    // The context may not be fully constructed and should not be used during GrDrawTarget
    // construction.
    GrDrawTarget(GrGpu* gpu, GrResourceProvider*);

    ~GrDrawTarget() override;

    void makeClosed() {
        // We only close drawTargets When MDB is enabled. When MDB is disabled there is only
        // ever one drawTarget and all calls will be funnelled into it.
#ifdef ENABLE_MDB
        this->setFlag(kClosed_Flag);
#endif
    }
    bool isClosed() const { return this->isSetFlag(kClosed_Flag); }

    /*
     * Notify this drawTarget that it relies on the contents of 'dependedOn'
     */
    void addDependency(GrSurface* dependedOn);

    /*
     * Does this drawTarget depend on 'dependedOn'?
     */
    bool dependsOn(GrDrawTarget* dependedOn) const {
        return fDependencies.find(dependedOn) >= 0;
    }

    /*
     * Dump out the drawTarget dependency DAG
     */
    SkDEBUGCODE(void dump() const;)

    /**
     * Empties the draw buffer of any queued up draws.
     */
    void reset();

    /**
     * This plays any queued up draws to its GrGpu target. It also resets this object (i.e. flushing
     * is destructive).
     */
    void flush();

    /**
     * Gets the capabilities of the draw target.
     */
    const GrCaps* caps() const { return fGpu->caps(); }

    void drawBatch(const GrPipelineBuilder&, GrDrawBatch*);

    /**
     * Draws path into the stencil buffer. The fill must be either even/odd or
     * winding (not inverse or hairline). It will respect the HW antialias flag
     * on the GrPipelineBuilder (if possible in the 3D API).  Note, we will never have an inverse
     * fill with stencil path
     */
    void stencilPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, const GrPath*,
                     GrPathRendering::FillType);

    /**
     * Draws a path. Fill must not be a hairline. It will respect the HW
     * antialias flag on the GrPipelineBuilder (if possible in the 3D API).
     *
     * TODO: Remove this function and construct the batch outside GrDrawTarget.
     */
    void drawPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, GrColor color,
                  const GrPath*, GrPathRendering::FillType);

    /**
     * Draws the aggregate path from combining multiple. Note that this will not
     * always be equivalent to back-to-back calls to drawPath(). It will respect
     * the HW antialias flag on the GrPipelineBuilder (if possible in the 3D API).
     *
     * TODO: Remove this function and construct the batch outside GrDrawTarget.
     *
     * @param draw            The transforms and indices for the draw.
     *                        This object must only be drawn once. The draw
     *                        may modify its contents.
     * @param fill            Fill type for drawing all the paths
     */
    void drawPathsFromRange(const GrPipelineBuilder&,
                            const SkMatrix& viewMatrix,
                            const SkMatrix& localMatrix,
                            GrColor color,
                            GrPathRange* range,
                            GrPathRangeDraw* draw,
                            GrPathRendering::FillType fill);

    /**
     * Helper function for drawing rects.
     *
     * @param rect        the rect to draw
     * @param localRect   optional rect that specifies local coords to map onto
     *                    rect. If nullptr then rect serves as the local coords.
     * @param localMatrix Optional local matrix. The local coordinates are specified by localRect,
     *                    or if it is nullptr by rect. This matrix applies to the coordinate implied by
     *                    that rectangle before it is input to GrCoordTransforms that read local
     *                    coordinates
     */
    void drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
                       GrColor color,
                       const SkMatrix& viewMatrix,
                       const SkRect& rect);

    void drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
                       GrColor color,
                       const SkMatrix& viewMatrix,
                       const SkRect& rect,
                       const SkMatrix& localMatrix);

    void drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
                       GrColor color,
                       const SkMatrix& viewMatrix,
                       const SkRect& rect,
                       const SkRect& localRect);

    void drawNonAARect(const GrPipelineBuilder& ds,
                       GrColor color,
                       const SkMatrix& viewM,
                       const SkIRect& irect) {
        SkRect rect = SkRect::Make(irect);
        this->drawNonAARect(ds, color, viewM, rect);
    }

    void drawAARect(const GrPipelineBuilder& pipelineBuilder,
                    GrColor color,
                    const SkMatrix& viewMatrix,
                    const SkRect& rect,
                    const SkRect& devRect);

    /**
     * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
     * thing if rect is nullptr, otherwise just the rect. If canIgnoreRect is set then the entire
     * render target can be optionally cleared.
     */
    void clear(const SkIRect* rect,
               GrColor color,
               bool canIgnoreRect,
               GrRenderTarget* renderTarget);

    /** Discards the contents render target. */
    void discard(GrRenderTarget*);

    /**
     * Copies a pixel rectangle from one surface to another. This call may finalize
     * reserved vertex/index data (as though a draw call was made). The src pixels
     * copied are specified by srcRect. They are copied to a rect of the same
     * size in dst with top left at dstPoint. If the src rect is clipped by the
     * src bounds then  pixel values in the dst rect corresponding to area clipped
     * by the src rect are not overwritten. This method is not guaranteed to succeed
     * depending on the type of surface, configs, etc, and the backend-specific
     * limitations.
     */
    void copySurface(GrSurface* dst,
                     GrSurface* src,
                     const SkIRect& srcRect,
                     const SkIPoint& dstPoint);

    bool programUnitTest(GrContext* owner, int maxStages);

    /** Provides access to internal functions to GrClipMaskManager without friending all of
        GrDrawTarget to CMM. */
    class CMMAccess {
    public:
        CMMAccess(GrDrawTarget* drawTarget) : fDrawTarget(drawTarget) {}
    private:
        void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) const {
            fDrawTarget->clearStencilClip(rect, insideClip, rt);
        }

        GrContext* context() const { return fDrawTarget->fContext; }
        GrResourceProvider* resourceProvider() const { return fDrawTarget->fResourceProvider; }
        GrDrawTarget* fDrawTarget;
        friend class GrClipMaskManager;
    };

    const CMMAccess cmmAccess() { return CMMAccess(this); }


private:
    friend class GrDrawingManager; // for resetFlag & TopoSortTraits

    enum Flags {
        kClosed_Flag    = 0x01,   //!< This drawTarget can't accept any more batches

        kWasOutput_Flag = 0x02,   //!< Flag for topological sorting
        kTempMark_Flag  = 0x04,   //!< Flag for topological sorting
    };

    void setFlag(uint32_t flag) {
        fFlags |= flag;
    }

    void resetFlag(uint32_t flag) {
        fFlags &= ~flag;
    }

    bool isSetFlag(uint32_t flag) const {
        return SkToBool(fFlags & flag);
    }

    struct TopoSortTraits {
        static void Output(GrDrawTarget* dt, int /* index */) {
            dt->setFlag(GrDrawTarget::kWasOutput_Flag);
        }
        static bool WasOutput(const GrDrawTarget* dt) {
            return dt->isSetFlag(GrDrawTarget::kWasOutput_Flag);
        }
        static void SetTempMark(GrDrawTarget* dt) {
            dt->setFlag(GrDrawTarget::kTempMark_Flag);
        }
        static void ResetTempMark(GrDrawTarget* dt) {
            dt->resetFlag(GrDrawTarget::kTempMark_Flag);
        }
        static bool IsTempMarked(const GrDrawTarget* dt) {
            return dt->isSetFlag(GrDrawTarget::kTempMark_Flag);
        }
        static int NumDependencies(const GrDrawTarget* dt) {
            return dt->fDependencies.count();
        }
        static GrDrawTarget* Dependency(GrDrawTarget* dt, int index) {
            return dt->fDependencies[index];
        }
    };

    void recordBatch(GrBatch*);
    bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
                                    const GrScissorState* scissor,
                                    GrDrawBatch* batch);

    // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
    // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
    // needs to be accessed by GLPrograms to setup a correct drawstate
    bool setupDstReadIfNecessary(const GrPipelineBuilder&,
        const GrProcOptInfo& colorPOI,
        const GrProcOptInfo& coveragePOI,
        GrXferProcessor::DstTexture*,
        const SkRect& batchBounds);

    void drawPathBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawPathBatchBase* batch,
                       GrPathRendering::FillType fill);
    // Check to see if this set of draw commands has been sent out
    void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
                                           const GrStencilAttachment*,
                                           GrStencilSettings*);
    bool setupClip(const GrPipelineBuilder&,
                           GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
                           GrPipelineBuilder::AutoRestoreStencil*,
                           GrScissorState*,
                           const SkRect* devBounds);

    void addDependency(GrDrawTarget* dependedOn);

    // Used only by CMM.
    void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);

    SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
    SkAutoTDelete<GrClipMaskManager>            fClipMaskManager;
    // The context is only in service of the clip mask manager, remove once CMM doesn't need this.
    GrContext*                                  fContext;
    GrGpu*                                      fGpu;
    GrResourceProvider*                         fResourceProvider;
    GrBatchFlushState                           fFlushState;
    bool                                        fFlushing;
    int                                         fFirstUnpreparedBatch;

    SkDEBUGCODE(int                             fDebugID;)
    uint32_t                                    fFlags;

    // 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
    SkTDArray<GrDrawTarget*>                    fDependencies;

    typedef SkRefCnt INHERITED;
};

#endif
