/*
    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:
    /**
     *  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);
    /**
     * Wraps an externally-created rendertarget in a GrRenderTarget.
     * @param platformRenderTarget  handle to the the render target in the
     *                              underlying 3D API. Interpretation depends on
     *                              GrGpu subclass in use.
     * @param stencilBits           number of stencil bits the target has
     * @param isMultisampled        specify whether the RT is multisampled
     * @param width                 width of the render target
     * @param height                height of the render target
     */
     GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
                                                int stencilBits,
                                                bool isMultisampled,
                                                int width, int height);

    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; }

    /**
     * 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.
     */
    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

    // 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* onCreatePlatformRenderTarget(
                                                intptr_t platformRenderTarget,
                                                int stencilBits,
                                                bool isMultisampled,
                                                int width, int height) = 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(GrPathIter* 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
