• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrPath.h"
18 
19 #include "SkClipStack.h"
20 #include "SkStrokeRec.h"
21 #include "SkTemplates.h"
22 
23 class GrGpu;
24 class GrIndexBufferAllocPool;
25 class GrVertexBufferAllocPool;
26 
27 /**
28  * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
29  * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
30  * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
31  * references to the buffers. It is the callers responsibility to ensure that the data is still
32  * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
33  * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
34  * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
35  * store geometry.
36  */
37 class GrInOrderDrawBuffer : public GrDrawTarget {
38 public:
39 
40     /**
41      * Creates a GrInOrderDrawBuffer
42      *
43      * @param gpu        the gpu object where this will be played back
44      *                   (possible indirectly). GrResources used with the draw
45      *                   buffer are created by this gpu object.
46      * @param vertexPool pool where vertices for queued draws will be saved when
47      *                   the vertex source is either reserved or array.
48      * @param indexPool  pool where indices for queued draws will be saved when
49      *                   the index source is either reserved or array.
50      */
51     GrInOrderDrawBuffer(const GrGpu* gpu,
52                         GrVertexBufferAllocPool* vertexPool,
53                         GrIndexBufferAllocPool* indexPool);
54 
55     virtual ~GrInOrderDrawBuffer();
56 
57     /**
58      * Empties the draw buffer of any queued up draws. This must not be called while inside an
59      * unbalanced pushGeometrySource(). The current draw state and clip are preserved.
60      */
61     void reset();
62 
63     /**
64      * This plays the queued up draws to another target. It also resets this object (i.e. flushing
65      * is destructive). This buffer must not have an active reserved vertex or index source. Any
66      * reserved geometry on the target will be finalized because it's geometry source will be pushed
67      * before flushing and popped afterwards.
68      *
69      * @return false if the playback trivially drew nothing because nothing was recorded.
70      *
71      * @param target    the target to receive the playback
72      */
73     bool flushTo(GrDrawTarget* target);
74 
75     /**
76      * This function allows the draw buffer to automatically flush itself to another target. This
77      * means the buffer may internally call this->flushTo(target) when it is safe to do so.
78      *
79      * When the auto flush target is set to NULL (as it initially is) the draw buffer will never
80      * automatically flush itself.
81      */
82     void setAutoFlushTarget(GrDrawTarget* target);
83 
84     // overrides from GrDrawTarget
85     virtual bool geometryHints(size_t vertexSize,
86                                int* vertexCount,
87                                int* indexCount) const SK_OVERRIDE;
88     virtual void clear(const GrIRect* rect,
89                        GrColor color,
90                        GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
91     virtual void drawRect(const GrRect& rect,
92                           const SkMatrix* matrix,
93                           const GrRect* srcRects[],
94                           const SkMatrix* srcMatrices[]) SK_OVERRIDE;
95 
96 protected:
97     virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
98 
99 private:
100     enum Cmd {
101         kDraw_Cmd           = 1,
102         kStencilPath_Cmd    = 2,
103         kSetState_Cmd       = 3,
104         kSetClip_Cmd        = 4,
105         kClear_Cmd          = 5,
106     };
107 
108     class DrawRecord : public DrawInfo {
109     public:
DrawRecord(const DrawInfo & info)110         DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
111         GrVertexLayout          fVertexLayout;
112         const GrVertexBuffer*   fVertexBuffer;
113         const GrIndexBuffer*    fIndexBuffer;
114     };
115 
116     struct StencilPath {
117         StencilPath();
118 
119         SkAutoTUnref<const GrPath>  fPath;
120         SkStrokeRec                 fStroke;
121         SkPath::FillType            fFill;
122     };
123 
124     struct Clear {
ClearClear125         Clear() : fRenderTarget(NULL) {}
~ClearClear126         ~Clear() { GrSafeUnref(fRenderTarget); }
127 
128         GrIRect         fRect;
129         GrColor         fColor;
130         GrRenderTarget* fRenderTarget;
131     };
132 
133     // overrides from GrDrawTarget
134     virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
135     virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE;
136     virtual bool onReserveVertexSpace(size_t vertexSize,
137                                       int vertexCount,
138                                       void** vertices) SK_OVERRIDE;
139     virtual bool onReserveIndexSpace(int indexCount,
140                                      void** indices) SK_OVERRIDE;
141     virtual void releaseReservedVertexSpace() SK_OVERRIDE;
142     virtual void releaseReservedIndexSpace() SK_OVERRIDE;
143     virtual void onSetVertexSourceToArray(const void* vertexArray,
144                                           int vertexCount) SK_OVERRIDE;
145     virtual void onSetIndexSourceToArray(const void* indexArray,
146                                          int indexCount) SK_OVERRIDE;
147     virtual void releaseVertexArray() SK_OVERRIDE;
148     virtual void releaseIndexArray() SK_OVERRIDE;
149     virtual void geometrySourceWillPush() SK_OVERRIDE;
150     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
151     virtual void willReserveVertexAndIndexSpace(size_t vertexSize,
152                                                 int vertexCount,
153                                                 int indexCount) SK_OVERRIDE;
154     bool quickInsideClip(const SkRect& devBounds);
155 
156     // Attempts to concat instances from info onto the previous draw. info must represent an
157     // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
158     int concatInstancedDraw(const DrawInfo& info);
159 
160     // we lazily record state and clip changes in order to skip clips and states that have no
161     // effect.
162     bool needsNewState() const;
163     bool needsNewClip() const;
164 
165     // these functions record a command
166     void            recordState();
167     void            recordClip();
168     DrawRecord*     recordDraw(const DrawInfo&);
169     StencilPath*    recordStencilPath();
170     Clear*          recordClear();
171 
172     enum {
173         kCmdPreallocCnt          = 32,
174         kDrawPreallocCnt         = 8,
175         kStencilPathPreallocCnt  = 8,
176         kStatePreallocCnt        = 8,
177         kClipPreallocCnt         = 8,
178         kClearPreallocCnt        = 4,
179         kGeoPoolStatePreAllocCnt = 4,
180     };
181 
182     SkAutoTUnref<const GrGpu> fGpu;
183 
184     SkSTArray<kCmdPreallocCnt, uint8_t, true>                          fCmds;
185     GrSTAllocator<kDrawPreallocCnt, DrawRecord>                        fDraws;
186     GrSTAllocator<kStatePreallocCnt, StencilPath>                      fStencilPaths;
187     GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState>       fStates;
188     GrSTAllocator<kClearPreallocCnt, Clear>                            fClears;
189 
190     GrSTAllocator<kClipPreallocCnt, SkClipStack>        fClips;
191     GrSTAllocator<kClipPreallocCnt, SkIPoint>           fClipOrigins;
192 
193     GrDrawTarget*                   fAutoFlushTarget;
194 
195     bool                            fClipSet;
196 
197     enum ClipProxyState {
198         kUnknown_ClipProxyState,
199         kValid_ClipProxyState,
200         kInvalid_ClipProxyState
201     };
202     ClipProxyState                  fClipProxyState;
203     SkRect                          fClipProxy;
204 
205     GrVertexBufferAllocPool&        fVertexPool;
206 
207     GrIndexBufferAllocPool&         fIndexPool;
208 
209     struct GeometryPoolState {
210         const GrVertexBuffer*           fPoolVertexBuffer;
211         int                             fPoolStartVertex;
212         const GrIndexBuffer*            fPoolIndexBuffer;
213         int                             fPoolStartIndex;
214         // caller may conservatively over reserve vertices / indices.
215         // we release unused space back to allocator if possible
216         // can only do this if there isn't an intervening pushGeometrySource()
217         size_t                          fUsedPoolVertexBytes;
218         size_t                          fUsedPoolIndexBytes;
219     };
220     SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
221 
222     bool                            fFlushing;
223 
224     typedef GrDrawTarget INHERITED;
225 };
226 
227 #endif
228