/*
    Copyright 2011 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

#ifndef GrGpu_DEFINED
#define GrGpu_DEFINED

#include "GrDrawTarget.h"
#include "GrPathRenderer.h"
#include "GrRect.h"
#include "GrRefCnt.h"
#include "GrTexture.h"

class GrContext;
class GrIndexBufferAllocPool;
class GrResource;
class GrVertexBufferAllocPool;

/**
 * Gpu usage statistics.
 */
struct GrGpuStats {
    uint32_t fVertexCnt;  //<! Number of vertices drawn
    uint32_t fIndexCnt;   //<! Number of indices drawn
    uint32_t fDrawCnt;    //<! Number of draws

    uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)

    /*
        *  Number of times the texture is set in 3D API
        */
    uint32_t fTextureChngCnt;
    /*
        *  Number of times the render target is set in 3D API
        */
    uint32_t fRenderTargetChngCnt;
    /*
        *  Number of textures created (includes textures that are rendertargets).
        */
    uint32_t fTextureCreateCnt;
    /*
        *  Number of rendertargets created.
        */
    uint32_t fRenderTargetCreateCnt;
};

class GrGpu : public GrDrawTarget {

public:
    /**
     * Additional blend coeffecients for dual source blending, not exposed
     * through GrPaint/GrContext.
     */
    enum ExtendedBlendCoeffs {
        // source 2 refers to second output color when
        // using dual source blending.
        kS2C_BlendCoeff = kPublicBlendCoeffCount,
        kIS2C_BlendCoeff,
        kS2A_BlendCoeff,
        kIS2A_BlendCoeff,

        kTotalBlendCoeffCount
    };

    /**
     *  Create an instance of GrGpu that matches the specified Engine backend.
     *  If the requested engine is not supported (at compile-time or run-time)
     *  this returns NULL.
     */
    static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);

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

    GrGpu();
    virtual ~GrGpu();

    // The GrContext sets itself as the owner of this Gpu object
    void setContext(GrContext* context) {
        GrAssert(NULL == fContext); 
        fContext = context;
    }
    GrContext* getContext() { return fContext; }
    const GrContext* getContext() const { return fContext; }

    /**
     * The GrGpu object normally assumes that no outsider is setting state
     * within the underlying 3D API's context/device/whatever. This call informs
     * the GrGpu that the state was modified and it shouldn't make assumptions
     * about the state.
     */
    void markContextDirty() { fContextIsDirty = true; }

    void unimpl(const char[]);

    /**
     * Creates a texture object. If desc width or height is not a power of
     * two but underlying API requires a power of two texture then srcData
     * will be embedded in a power of two texture. The extra width and height
     * is filled as though srcData were rendered clamped into the texture.
     *
     * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
     * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
     * on the render target until its releaseRenderTarget() is called or it is
     * destroyed.
     *
     * @param desc        describes the texture to be created.
     * @param srcData     texel data to load texture. Begins with full-size
     *                    palette data for paletted textures. Contains width*
     *                    height texels. If NULL texture data is uninitialized.
     *
     * @return    The texture object if successful, otherwise NULL.
     */
    GrTexture* createTexture(const GrTextureDesc& desc,
                             const void* srcData, size_t rowBytes);

    GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);

    /**
     * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
     * viewport state from the underlying 3D API and wraps it in a
     * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
     * underlying object in its destructor and it is up to caller to guarantee
     * that it remains valid while the GrRenderTarget is used.
     *
     * @return the newly created GrRenderTarget
     */
    GrRenderTarget* createRenderTargetFrom3DApiState();

    /**
     * Creates a vertex buffer.
     *
     * @param size    size in bytes of the vertex buffer
     * @param dynamic hints whether the data will be frequently changed
     *                by either GrVertexBuffer::lock or
     *                GrVertexBuffer::updateData.
     *
     * @return    The vertex buffer if successful, otherwise NULL.
     */
    GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);

    /**
     * Creates an index buffer.
     *
     * @param size    size in bytes of the index buffer
     * @param dynamic hints whether the data will be frequently changed
     *                by either GrIndexBuffer::lock or
     *                GrIndexBuffer::updateData.
     *
     * @return The index buffer if successful, otherwise NULL.
     */
    GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);

    /**
     * Are 8 bit paletted textures supported.
     *
     * @return    true if 8bit palette textures are supported, false otherwise
     */
    bool supports8BitPalette() const { return f8bitPaletteSupport; }

    /**
     * returns true if two sided stenciling is supported. If false then only
     * the front face values of the GrStencilSettings
     * @return    true if only a single stencil pass is needed.
     */
    bool supportsTwoSidedStencil() const
                                        { return fTwoSidedStencilSupport; }

    /**
     * returns true if stencil wrap is supported. If false then
     * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as
     * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively.
     * @return    true if stencil wrap ops are supported.
     */
    bool supportsStencilWrapOps() const
                                        { return fStencilWrapOpsSupport; }

    /**
     * Checks whether locking vertex and index buffers is supported.
     *
     * @return true if locking is supported.
     */
    bool supportsBufferLocking() const { return fBufferLockSupport; }

    /**
     * Does the 3D API support anti-aliased lines. If so then line primitive
     * types will use this functionality when the AA state flag is set.
     */
    bool supportsAALines() const { return fAALineSupport; }

    /**
     * Does the subclass support GrSamplerState::k4x4Downsample_Filter
     */
    bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; }

    /**
     * Does this instance support dual-source blending? Required for proper
     * blending with partial coverage with certain blend modes (dst coeff is
     * not 1, ISA, or ISC)
     */
    bool supportsDualSourceBlending() const { 
        return fDualSourceBlendingSupport; 
    }

    /**
     * Gets the minimum width of a render target. If a texture/rt is created
     * with a width less than this size the GrGpu object will clamp it to this
     * value.
     */
    int minRenderTargetWidth() const { return fMinRenderTargetWidth; }

    /**
     * Gets the minimum width of a render target. If a texture/rt is created
     * with a height less than this size the GrGpu object will clamp it to this
     * value.
     */
    int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
    
    /**
     * Reports whether full scene anti-aliasing is supported.
     */
    bool supportsFullsceneAA() const { return fFSAASupport; }

    /**
     * Returns true if NPOT textures can be created
     *
     * @return    true if NPOT textures can be created
     */
    bool npotTextureSupport() const { return fNPOTTextureSupport; }

    /**
     * Returns true if NPOT textures can be repeat/mirror tiled.
     *
     * @return    true if NPOT textures can be tiled
     */
    bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }

    /**
     * Returns true if a NPOT texture can be a rendertarget
     *
     * @return    the true if NPOT texture/rendertarget can be created.
     */
    bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }

    int maxTextureDimension() const { return fMaxTextureDimension; }

    // GrDrawTarget overrides
    virtual void drawIndexed(GrPrimitiveType type,
                             int startVertex,
                             int startIndex,
                             int vertexCount,
                             int indexCount);

    virtual void drawNonIndexed(GrPrimitiveType type,
                                int startVertex,
                                int vertexCount);
    virtual void clear(const GrIRect* rect, GrColor color);

    /**
     * Installs a path renderer that will be used to draw paths that are
     * part of the clip.
     */
    void setClipPathRenderer(GrPathRenderer* pathRenderer) {
        GrSafeAssign(fClientPathRenderer, pathRenderer);
    }

    /**
     * Returns an index buffer that can be used to render quads.
     * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
     * The max number of quads can be queried using GrIndexBuffer::maxQuads().
     * Draw with kTriangles_PrimitiveType
     * @ return the quad index buffer
     */
    const GrIndexBuffer* getQuadIndexBuffer() const;

    /**
     * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
     * (1,1), (0,1)].
     * @ return unit square vertex buffer
     */
    const GrVertexBuffer* getUnitSquareVertexBuffer() const;

    /**
     * Ensures that the current render target is actually set in the
     * underlying 3D API. Used when client wants to use 3D API to directly
     * render to the RT.
     */
    void forceRenderTargetFlush();

    /**
     * Reads a rectangle of pixels from a render target.
     * @param renderTarget  the render target to read from. NULL means the
     *                      current render target.
     * @param left          left edge of the rectangle to read (inclusive)
     * @param top           top edge of the rectangle to read (inclusive)
     * @param width         width of rectangle to read in pixels.
     * @param height        height of rectangle to read in pixels.
     * @param config        the pixel config of the destination buffer
     * @param buffer        memory to read the rectangle into.
     *
     * @return true if the read succeeded, false if not. The read can fail
     *              because of a unsupported pixel config or because no render
     *              target is currently set.
     */
    bool readPixels(GrRenderTarget* renderTarget,
                    int left, int top, int width, int height,
                    GrPixelConfig config, void* buffer);

    const GrGpuStats& getStats() const;
    void resetStats();
    void printStats() const;

    /**
     * Called to tell Gpu object that all GrResources have been lost and should
     * be abandoned.
     */
    virtual void abandonResources();

    /**
     * Called to tell Gpu object to release all GrResources.
     */
    void releaseResources();

    /**
     * Add resource to list of resources. Should only be called by GrResource.
     * @param resource  the resource to add.
     */
    void insertResource(GrResource* resource);

    /**
     * Remove resource from list of resources. Should only be called by
     * GrResource.
     * @param resource  the resource to remove.
     */
    void removeResource(GrResource* resource);

protected:
    enum PrivateStateBits {
        kFirstBit = (kLastPublicStateBit << 1),

        kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
                                                 // stencil bits used for
                                                 // clipping.
    };

    /**
     * Extensions to GrDrawTarget::StateBits to implement stencil clipping
     */
    struct ClipState {
        bool            fClipInStencil;
        bool            fClipIsDirty;
    } fClipState;

    // GrDrawTarget override
    virtual void clipWillBeSet(const GrClip& newClip);

    // prepares clip flushes gpu state before a draw
    bool setupClipAndFlushState(GrPrimitiveType type);

    // Functions used to map clip-respecting stencil tests into normal
    // stencil funcs supported by GPUs.
    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
                                            GrStencilFunc func);
    static void ConvertStencilFuncAndMask(GrStencilFunc func,
                                          bool clipInStencil,
                                          unsigned int clipBit,
                                          unsigned int userBits,
                                          unsigned int* ref,
                                          unsigned int* mask);

    // stencil settings to clip drawing when stencil clipping is in effect
    // and the client isn't using the stencil test.
    static const GrStencilSettings gClipStencilSettings;

    // defaults to false, subclass can set true to support palleted textures
    bool f8bitPaletteSupport;

    // set by subclass
    bool fNPOTTextureSupport;
    bool fNPOTTextureTileSupport;
    bool fNPOTRenderTargetSupport;
    bool fTwoSidedStencilSupport;
    bool fStencilWrapOpsSupport;
    bool fAALineSupport;
    bool fFSAASupport;
    bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter
    bool fDualSourceBlendingSupport;

    // set by subclass to true if index and vertex buffers can be locked, false
    // otherwise.
    bool fBufferLockSupport;

    // set by subclass
    int fMinRenderTargetWidth;
    int fMinRenderTargetHeight;
    int fMaxTextureDimension;

    GrGpuStats fStats;

    const GrVertexBuffer*           fCurrPoolVertexBuffer;
    int                             fCurrPoolStartVertex;

    const GrIndexBuffer*            fCurrPoolIndexBuffer;
    int                             fCurrPoolStartIndex;

    // GrDrawTarget overrides
    virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
                                   void**         vertices,
                                   void**         indices);
    virtual void onReleaseGeometry();

    virtual void onSetVertexSourceToArray(const void* vertexArray,
                                          int vertexCount);

    virtual void onSetIndexSourceToArray(const void* indexArray,
                                         int indexCount);
    // Helpers for setting up geometry state
    void finalizeReservedVertices();
    void finalizeReservedIndices();

    // overridden by API-specific derived class to handle re-emitting 3D API
    // preample and dirtying state cache.
    virtual void resetContext() = 0;

    // overridden by API-specific derived class to create objects.
    virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
                                       const void* srcData,
                                       size_t rowBytes) = 0;
    virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
    virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState() = 0;
    virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
                                                 bool dynamic) = 0;
    virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
                                               bool dynamic) = 0;

    // overridden by API-specific derivated class to perform the clear and 
    // clearRect. NULL rect means clear whole target.
    virtual void onClear(const GrIRect* rect, GrColor color) = 0;

    // overridden by API-specific derived class to perform the draw call.
    virtual void onDrawIndexed(GrPrimitiveType type,
                               uint32_t startVertex,
                               uint32_t startIndex,
                               uint32_t vertexCount,
                               uint32_t indexCount) = 0;

    virtual void onDrawNonIndexed(GrPrimitiveType type,
                                  uint32_t vertexCount,
                                  uint32_t numVertices) = 0;

    // overridden by API-specific derived class to perform flush
    virtual void onForceRenderTargetFlush() = 0;

    // overridden by API-specific derived class to perform the read pixels.
    virtual bool onReadPixels(GrRenderTarget* target,
                              int left, int top, int width, int height,
                              GrPixelConfig, void* buffer) = 0;

    // called to program the vertex data, indexCount will be 0 if drawing non-
    // indexed geometry. The subclass may adjust the startVertex and/or
    // startIndex since it may have already accounted for these in the setup.
    virtual void setupGeometry(int* startVertex,
                               int* startIndex,
                               int vertexCount,
                               int indexCount) = 0;


    // The GrGpu typically records the clients requested state and then flushes
    // deltas from previous state at draw time. This function does the
    // API-specific flush of the state
    // returns false if current state is unsupported.
    virtual bool flushGraphicsState(GrPrimitiveType type) = 0;

    // Sets the scissor rect, or disables if rect is NULL.
    virtual void flushScissor(const GrIRect* rect) = 0;

    // GrGpu subclass removes the clip from the stencil buffer
    virtual void clearStencilClip(const GrIRect& rect) = 0;

private:
    GrContext*                  fContext; // not reffed (context refs gpu)

    GrVertexBufferAllocPool*    fVertexPool;

    GrIndexBufferAllocPool*     fIndexPool;

    mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
                                                  // created on-demand

    mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
                                                         // created on-demand

    GrDefaultPathRenderer*      fDefaultPathRenderer;
    GrPathRenderer*             fClientPathRenderer;

    bool                        fContextIsDirty;

    // when in an internal draw these indicate whether the pools are in use
    // by one of the outer draws. If false then it is safe to reset the
    // pool.
    bool                        fVertexPoolInUse;
    bool                        fIndexPoolInUse;

    GrResource*                 fResourceHead;

    // readies the pools to provide vertex/index data.
    void prepareVertexPool();
    void prepareIndexPool();

    // determines the path renderer used to draw a clip path element.
    GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);

    void handleDirtyContext() {
        if (fContextIsDirty) {
            this->resetContext();
            fContextIsDirty = false;
        }
    }

    // used to save and restore state when the GrGpu needs
    // to make its geometry pools available internally
    class AutoInternalDrawGeomRestore {
    public:
        AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
            fGpu = gpu;

            fVertexPoolWasInUse = gpu->fVertexPoolInUse;
            fIndexPoolWasInUse  = gpu->fIndexPoolInUse;

            gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
                                   (kBuffer_GeometrySrcType !=
                                    gpu->fGeometrySrc.fVertexSrc);
            gpu->fIndexPoolInUse  = fIndexPoolWasInUse ||
                                   (kBuffer_GeometrySrcType !=
                                    gpu->fGeometrySrc.fIndexSrc);;

            fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
            fSavedPoolStartVertex  = gpu->fCurrPoolStartVertex;
            fSavedPoolIndexBuffer  = gpu->fCurrPoolIndexBuffer;
            fSavedPoolStartIndex   = gpu->fCurrPoolStartIndex;

            fSavedReservedGeometry = gpu->fReservedGeometry;
            gpu->fReservedGeometry.fLocked = false;
        }
        ~AutoInternalDrawGeomRestore() {
            fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
            fGpu->fCurrPoolStartVertex  = fSavedPoolStartVertex;
            fGpu->fCurrPoolIndexBuffer  = fSavedPoolIndexBuffer;
            fGpu->fCurrPoolStartIndex   = fSavedPoolStartIndex;
            fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
            fGpu->fIndexPoolInUse  = fIndexPoolWasInUse;
            fGpu->fReservedGeometry = fSavedReservedGeometry;
        }
    private:
        AutoGeometrySrcRestore  fAgsr;
        GrGpu*                  fGpu;
        const GrVertexBuffer*   fSavedPoolVertexBuffer;
        int                     fSavedPoolStartVertex;
        const GrIndexBuffer*    fSavedPoolIndexBuffer;
        int                     fSavedPoolStartIndex;
        bool                    fVertexPoolWasInUse;
        bool                    fIndexPoolWasInUse;
        ReservedGeometry        fSavedReservedGeometry;
    };

    typedef GrDrawTarget INHERITED;
};

#endif
