/*
 * 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 "GrClip.h"
#include "GrClipMaskManager.h"
#include "GrContext.h"
#include "GrPathProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "GrIndexBuffer.h"
#include "GrPathRendering.h"
#include "GrPipelineBuilder.h"
#include "GrTraceMarker.h"
#include "GrVertexBuffer.h"

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

class GrClip;
class GrCaps;
class GrPath;
class GrPathRange;
class GrPipeline;

class GrDrawTarget : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(GrDrawTarget)

    typedef GrPathRange::PathIndexType PathIndexType;
    typedef GrPathRendering::PathTransformType PathTransformType;

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

    // The context may not be fully constructed and should not be used during GrDrawTarget
    // construction.
    GrDrawTarget(GrContext* context);

    virtual ~GrDrawTarget() {}

    /**
     * Empties the draw buffer of any queued up draws.
     */
    void reset() { this->onReset(); }

    /**
     * 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 fCaps.get(); }

    void drawBatch(GrPipelineBuilder*, GrBatch*);

    /**
     * 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(GrPipelineBuilder*, const GrPathProcessor*, 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).
     */
    void drawPath(GrPipelineBuilder*, const GrPathProcessor*, 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).
     *
     * @param pathRange       Source paths to draw from
     * @param indices         Array of path indices to draw
     * @param indexType       Data type of the array elements in indexBuffer
     * @param transformValues Array of transforms for the individual paths
     * @param transformType   Type of transforms in transformBuffer
     * @param count           Number of paths to draw
     * @param fill            Fill type for drawing all the paths
     */
    void drawPaths(GrPipelineBuilder*,
                   const GrPathProcessor*,
                   const GrPathRange* pathRange,
                   const void* indices,
                   PathIndexType indexType,
                   const float transformValues[],
                   PathTransformType transformType,
                   int count,
                   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 NULL then rect serves as the local coords.
     * @param localMatrix Optional local matrix. The local coordinates are specified by localRect,
     *                    or if it is NULL by rect. This matrix applies to the coordinate implied by
     *                    that rectangle before it is input to GrCoordTransforms that read local
     *                    coordinates
     */
    void drawRect(GrPipelineBuilder* pipelineBuilder,
                  GrColor color,
                  const SkMatrix& viewMatrix,
                  const SkRect& rect,
                  const SkRect* localRect,
                  const SkMatrix* localMatrix);

    /**
     * Helper for drawRect when the caller doesn't need separate local rects or matrices.
     */
    void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
                        const SkRect& rect) {
        this->drawRect(ds, color, viewM, rect, NULL, NULL);
    }
    void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
                        const SkIRect& irect) {
        SkRect rect = SkRect::Make(irect);
        this->drawRect(ds, color, viewM, rect, NULL, NULL);
    }


    /**
     * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
     * thing if rect is NULL, 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.
     **/
    virtual void discard(GrRenderTarget*) = 0;

    /**
     * Called at start and end of gpu trace marking
     * GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
     * and end of a code block respectively
     */
    void addGpuTraceMarker(const GrGpuTraceMarker* marker);
    void removeGpuTraceMarker(const GrGpuTraceMarker* marker);

    /**
     * Takes the current active set of markers and stores them for later use. Any current marker
     * in the active set is removed from the active set and the targets remove function is called.
     * These functions do not work as a stack so you cannot call save a second time before calling
     * restore. Also, it is assumed that when restore is called the current active set of markers
     * is empty. When the stored markers are added back into the active set, the targets add marker
     * is called.
     */
    void saveActiveTraceMarkers();
    void restoreActiveTraceMarkers();

    /**
     * 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 can fail and return false
     * depending on the type of surface, configs, etc, and the backend-specific
     * limitations. If rect is clipped out entirely by the src or dst bounds then
     * true is returned since there is no actual copy necessary to succeed.
     */
    bool copySurface(GrSurface* dst,
                     GrSurface* src,
                     const SkIRect& srcRect,
                     const SkIPoint& dstPoint);
    /**
     * Function that determines whether a copySurface call would succeed without actually
     * performing the copy.
     */
    bool canCopySurface(const GrSurface* dst,
                        const GrSurface* src,
                        const SkIRect& srcRect,
                        const SkIPoint& dstPoint);

    /**
     * Release any resources that are cached but not currently in use. This
     * is intended to give an application some recourse when resources are low.
     */
    virtual void purgeResources() {};

    bool programUnitTest(int maxStages);

protected:
    friend class GrCommandBuilder; // for PipelineInfo
    friend class GrInOrderCommandBuilder; // for PipelineInfo
    friend class GrReorderCommandBuilder; // for PipelineInfo
    friend class GrTargetCommands; // for PipelineInfo

    GrContext* getContext() { return fContext; }
    const GrContext* getContext() const { return fContext; }

    GrGpu* getGpu() {
        SkASSERT(fContext && fContext->getGpu());
        return fContext->getGpu();
    }
    const GrGpu* getGpu() const {
        SkASSERT(fContext && fContext->getGpu());
        return fContext->getGpu();
    }

    const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }

    // 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,
                                 GrDeviceCoordTexture* dstCopy,
                                 const SkRect* drawBounds);

    struct PipelineInfo {
        PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
                     const GrPrimitiveProcessor* primProc,
                     const SkRect* devBounds, GrDrawTarget* target);

        PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
                     const GrBatch* batch, const SkRect* devBounds,
                     GrDrawTarget* target);

        bool willBlendWithDst(const GrPrimitiveProcessor* primProc) const {
            return fPipelineBuilder->willBlendWithDst(primProc);
        }
    private:
        friend class GrDrawTarget;

        bool mustSkipDraw() const { return (NULL == fPipelineBuilder); }

        GrPipelineBuilder*      fPipelineBuilder;
        GrScissorState*         fScissor;
        GrProcOptInfo           fColorPOI; 
        GrProcOptInfo           fCoveragePOI; 
        GrDeviceCoordTexture    fDstCopy;
    };

    void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline);

private:
    virtual void onReset() = 0;

    virtual void onFlush() = 0;

    virtual void onDrawBatch(GrBatch*, const PipelineInfo&) = 0;
    virtual void onStencilPath(const GrPipelineBuilder&,
                               const GrPathProcessor*,
                               const GrPath*,
                               const GrScissorState&,
                               const GrStencilSettings&) = 0;
    virtual void onDrawPath(const GrPathProcessor*,
                            const GrPath*,
                            const GrStencilSettings&,
                            const PipelineInfo&) = 0;
    virtual void onDrawPaths(const GrPathProcessor*,
                             const GrPathRange*,
                             const void* indices,
                             PathIndexType,
                             const float transformValues[],
                             PathTransformType,
                             int count,
                             const GrStencilSettings&,
                             const PipelineInfo&) = 0;

    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
                         GrRenderTarget* renderTarget) = 0;

    /** The subclass's copy surface implementation. It should assume that any clipping has already
        been performed on the rect and point and that the GrGpu supports the copy. */
    virtual void onCopySurface(GrSurface* dst,
                               GrSurface* src,
                               const SkIRect& srcRect,
                               const SkIPoint& dstPoint) = 0;

    // Check to see if this set of draw commands has been sent out
    virtual bool       isIssued(uint32_t drawID) { return true; }
    void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
                                           const GrStencilAttachment*,
                                           GrStencilSettings*);
    virtual GrClipMaskManager* clipMaskManager() = 0;
    virtual bool setupClip(GrPipelineBuilder*,
                           GrPipelineBuilder::AutoRestoreFragmentProcessors*,
                           GrPipelineBuilder::AutoRestoreStencil*,
                           GrScissorState*,
                           const SkRect* devBounds) = 0;

    // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
    GrContext*                                                      fContext;
    SkAutoTUnref<const GrCaps>                            fCaps;
    // To keep track that we always have at least as many debug marker adds as removes
    int                                                             fGpuTraceMarkerCount;
    GrTraceMarkerSet                                                fActiveTraceMarkers;
    GrTraceMarkerSet                                                fStoredTraceMarkers;
    bool                                                            fFlushing;

    typedef SkRefCnt INHERITED;
};

/*
 * This class is JUST for clip mask manager.  Everyone else should just use draw target above.
 */
class GrClipTarget : public GrDrawTarget {
public:
    GrClipTarget(GrContext* context)
        : INHERITED(context) {
        fClipMaskManager.setClipTarget(this);
    }

    /* Clip mask manager needs access to the context.
     * TODO we only need a very small subset of context in the CMM.
     */
    GrContext* getContext() { return INHERITED::getContext(); }
    const GrContext* getContext() const { return INHERITED::getContext(); }

    /**
     * Clip Mask Manager(and no one else) needs to clear private stencil bits.
     * ClipTarget subclass sets clip bit in the stencil buffer. The subclass
     * is free to clear the remaining bits to zero if masked clears are more
     * expensive than clearing all bits.
     */
    virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* = NULL) = 0;

    /**
     * Release any resources that are cached but not currently in use. This
     * is intended to give an application some recourse when resources are low.
     */
    void purgeResources() override {
        // The clip mask manager can rebuild all its clip masks so just
        // get rid of them all.
        fClipMaskManager.purgeResources();
    };

protected:
    GrClipMaskManager           fClipMaskManager;

private:
    GrClipMaskManager* clipMaskManager() override { return &fClipMaskManager; }

    virtual bool setupClip(GrPipelineBuilder*,
                           GrPipelineBuilder::AutoRestoreFragmentProcessors*,
                           GrPipelineBuilder::AutoRestoreStencil*,
                           GrScissorState* scissorState,
                           const SkRect* devBounds) override;

    typedef GrDrawTarget INHERITED;
};

#endif
