1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11#ifndef GrInOrderDrawBuffer_DEFINED
12#define GrInOrderDrawBuffer_DEFINED
13
14#include "GrDrawTarget.h"
15#include "GrAllocPool.h"
16#include "GrAllocator.h"
17#include "GrClip.h"
18
19class GrGpu;
20class GrIndexBufferAllocPool;
21class GrVertexBufferAllocPool;
22
23/**
24 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
25 * draws for eventual playback into a GrGpu. In theory one draw buffer could
26 * playback into another. When index or vertex buffers are used as geometry
27 * sources it is the callers the draw buffer only holds references to the
28 * buffers. It is the callers responsibility to ensure that the data is still
29 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the
30 * caller's responsibility to ensure that all referenced textures, buffers,
31 * and rendertargets are associated in the GrGpu object that the buffer is
32 * played back into. The buffer requires VB and IB pools to store geometry.
33 */
34
35class GrInOrderDrawBuffer : public GrDrawTarget {
36public:
37
38    /**
39     * Creates a GrInOrderDrawBuffer
40     *
41     * @param gpu        the gpu object where this will be played back
42     *                   (possible indirectly). GrResources used with the draw
43     *                   buffer are created by this gpu object.
44     * @param vertexPool pool where vertices for queued draws will be saved when
45     *                   the vertex source is either reserved or array.
46     * @param indexPool  pool where indices for queued draws will be saved when
47     *                   the index source is either reserved or array.
48     */
49    GrInOrderDrawBuffer(const GrGpu* gpu,
50                        GrVertexBufferAllocPool* vertexPool,
51                        GrIndexBufferAllocPool* indexPool);
52
53    virtual ~GrInOrderDrawBuffer();
54
55    /**
56     * Copies the draw state and clip from target to this draw buffer.
57     *
58     * @param target    the target whose clip and state should be copied.
59     */
60    void initializeDrawStateAndClip(const GrDrawTarget& target);
61
62    /**
63     * Provides the buffer with an index buffer that can be used for quad rendering.
64     * The buffer may be able to batch consecutive drawRects if this is provided.
65     * @param indexBuffer   index buffer with quad indices.
66     */
67    void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
68
69    /**
70     * Empties the draw buffer of any queued up draws.
71     */
72    void reset();
73
74    /**
75     * plays the queued up draws to another target. Does not empty this buffer so
76     * that it can be played back multiple times.
77     * @param target    the target to receive the playback
78     */
79    void playback(GrDrawTarget* target);
80
81    // overrides from GrDrawTarget
82    virtual void drawRect(const GrRect& rect,
83                          const GrMatrix* matrix = NULL,
84                          StageMask stageEnableMask = 0,
85                          const GrRect* srcRects[] = NULL,
86                          const GrMatrix* srcMatrices[] = NULL);
87
88    virtual bool geometryHints(GrVertexLayout vertexLayout,
89                               int* vertexCount,
90                               int* indexCount) const;
91
92    virtual void clear(const GrIRect* rect, GrColor color);
93
94private:
95
96    struct Draw {
97        GrPrimitiveType         fPrimitiveType;
98        int                     fStartVertex;
99        int                     fStartIndex;
100        int                     fVertexCount;
101        int                     fIndexCount;
102        bool                    fStateChanged;
103        bool                    fClipChanged;
104        GrVertexLayout          fVertexLayout;
105        const GrVertexBuffer*   fVertexBuffer;
106        const GrIndexBuffer*    fIndexBuffer;
107    };
108
109    struct Clear {
110        int fBeforeDrawIdx;
111        GrIRect fRect;
112        GrColor fColor;
113    };
114
115    // overrides from GrDrawTarget
116    virtual void onDrawIndexed(GrPrimitiveType primitiveType,
117                               int startVertex,
118                               int startIndex,
119                               int vertexCount,
120                               int indexCount);
121    virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
122                                  int startVertex,
123                                  int vertexCount);
124    virtual bool onReserveVertexSpace(GrVertexLayout layout,
125                                      int vertexCount,
126                                      void** vertices);
127    virtual bool onReserveIndexSpace(int indexCount, void** indices);
128    virtual void releaseReservedVertexSpace();
129    virtual void releaseReservedIndexSpace();
130    virtual void onSetVertexSourceToArray(const void* vertexArray,
131                                          int vertexCount);
132    virtual void onSetIndexSourceToArray(const void* indexArray,
133                                         int indexCount);
134    virtual void releaseVertexArray();
135    virtual void releaseIndexArray();
136    virtual void geometrySourceWillPush();
137    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
138    virtual void clipWillBeSet(const GrClip& newClip);
139
140    bool needsNewState() const;
141    bool needsNewClip() const;
142
143    void pushState();
144    void pushClip();
145
146    enum {
147        kDrawPreallocCnt         = 8,
148        kStatePreallocCnt        = 8,
149        kClipPreallocCnt         = 8,
150        kClearPreallocCnt        = 4,
151        kGeoPoolStatePreAllocCnt = 4,
152    };
153
154    GrSTAllocator<kDrawPreallocCnt, Draw>               fDraws;
155    GrSTAllocator<kStatePreallocCnt, SavedDrawState>    fStates;
156    GrSTAllocator<kClearPreallocCnt, Clear>             fClears;
157    GrSTAllocator<kClipPreallocCnt, GrClip>             fClips;
158
159    bool                            fClipSet;
160
161    GrVertexLayout                  fLastRectVertexLayout;
162    const GrIndexBuffer*            fQuadIndexBuffer;
163    int                             fMaxQuads;
164    int                             fCurrQuad;
165
166    GrVertexBufferAllocPool&        fVertexPool;
167
168    GrIndexBufferAllocPool&         fIndexPool;
169
170    struct GeometryPoolState {
171        const GrVertexBuffer*           fPoolVertexBuffer;
172        int                             fPoolStartVertex;
173        const GrIndexBuffer*            fPoolIndexBuffer;
174        int                             fPoolStartIndex;
175        // caller may conservatively over reserve vertices / indices.
176        // we release unused space back to allocator if possible
177        // can only do this if there isn't an intervening pushGeometrySource()
178        size_t                          fUsedPoolVertexBytes;
179        size_t                          fUsedPoolIndexBytes;
180    };
181    SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
182
183    typedef GrDrawTarget INHERITED;
184};
185
186#endif
187