• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrInOrderDrawBuffer_DEFINED
9 #define GrInOrderDrawBuffer_DEFINED
10 
11 #include "GrDrawTarget.h"
12 #include "GrAllocPool.h"
13 #include "GrAllocator.h"
14 #include "GrPath.h"
15 
16 #include "SkClipStack.h"
17 #include "SkTemplates.h"
18 #include "SkTypes.h"
19 
20 class GrGpu;
21 class GrIndexBufferAllocPool;
22 class GrVertexBufferAllocPool;
23 
24 /**
25  * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
26  * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
27  * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
28  * references to the 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 caller's
30  * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
31  * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
32  * store geometry.
33  */
34 class GrInOrderDrawBuffer : public GrDrawTarget {
35 public:
36 
37     /**
38      * Creates a GrInOrderDrawBuffer
39      *
40      * @param gpu        the gpu object that this draw buffer flushes to.
41      * @param vertexPool pool where vertices for queued draws will be saved when
42      *                   the vertex source is either reserved or array.
43      * @param indexPool  pool where indices for queued draws will be saved when
44      *                   the index source is either reserved or array.
45      */
46     GrInOrderDrawBuffer(GrGpu* gpu,
47                         GrVertexBufferAllocPool* vertexPool,
48                         GrIndexBufferAllocPool* indexPool);
49 
50     virtual ~GrInOrderDrawBuffer();
51 
52     /**
53      * Empties the draw buffer of any queued up draws. This must not be called while inside an
54      * unbalanced pushGeometrySource(). The current draw state and clip are preserved.
55      */
56     void reset();
57 
58     /**
59      * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing
60      * is destructive). This buffer must not have an active reserved vertex or index source. Any
61      * reserved geometry on the target will be finalized because it's geometry source will be pushed
62      * before flushing and popped afterwards.
63      */
64     void flush();
65 
66     // tracking for draws
getCurrentDrawToken()67     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
68 
69     // overrides from GrDrawTarget
70     virtual bool geometryHints(int* vertexCount,
71                                int* indexCount) const SK_OVERRIDE;
72     virtual void clear(const SkIRect* rect,
73                        GrColor color,
74                        bool canIgnoreRect,
75                        GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
76 
77     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
78 
79 protected:
80     virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
81 
82 private:
83     enum Cmd {
84         kDraw_Cmd           = 1,
85         kStencilPath_Cmd    = 2,
86         kSetState_Cmd       = 3,
87         kSetClip_Cmd        = 4,
88         kClear_Cmd          = 5,
89         kCopySurface_Cmd    = 6,
90         kDrawPath_Cmd       = 7,
91     };
92 
93     class DrawRecord : public DrawInfo {
94     public:
DrawRecord(const DrawInfo & info)95         DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
96         const GrVertexBuffer*   fVertexBuffer;
97         const GrIndexBuffer*    fIndexBuffer;
98     };
99 
100     struct StencilPath : public ::SkNoncopyable {
101         StencilPath();
102 
103         SkAutoTUnref<const GrPath>  fPath;
104         SkPath::FillType            fFill;
105     };
106 
107     struct DrawPath : public ::SkNoncopyable {
108         DrawPath();
109 
110         SkAutoTUnref<const GrPath>  fPath;
111         SkPath::FillType            fFill;
112         GrDeviceCoordTexture        fDstCopy;
113     };
114 
115     struct Clear : public ::SkNoncopyable {
ClearClear116         Clear() : fRenderTarget(NULL) {}
~ClearClear117         ~Clear() { SkSafeUnref(fRenderTarget); }
118 
119         SkIRect         fRect;
120         GrColor         fColor;
121         bool            fCanIgnoreRect;
122         GrRenderTarget* fRenderTarget;
123     };
124 
125     struct CopySurface : public ::SkNoncopyable {
126         SkAutoTUnref<GrSurface> fDst;
127         SkAutoTUnref<GrSurface> fSrc;
128         SkIRect                 fSrcRect;
129         SkIPoint                fDstPoint;
130     };
131 
132     // overrides from GrDrawTarget
133     virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
134     virtual void onDrawRect(const SkRect& rect,
135                             const SkMatrix* matrix,
136                             const SkRect* localRect,
137                             const SkMatrix* localMatrix) SK_OVERRIDE;
138 
139     virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
140     virtual void onDrawPath(const GrPath*, SkPath::FillType,
141                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
142 
143     virtual bool onReserveVertexSpace(size_t vertexSize,
144                                       int vertexCount,
145                                       void** vertices) SK_OVERRIDE;
146     virtual bool onReserveIndexSpace(int indexCount,
147                                      void** indices) SK_OVERRIDE;
148     virtual void releaseReservedVertexSpace() SK_OVERRIDE;
149     virtual void releaseReservedIndexSpace() SK_OVERRIDE;
150     virtual void onSetVertexSourceToArray(const void* vertexArray,
151                                           int vertexCount) SK_OVERRIDE;
152     virtual void onSetIndexSourceToArray(const void* indexArray,
153                                          int indexCount) SK_OVERRIDE;
154     virtual void releaseVertexArray() SK_OVERRIDE;
155     virtual void releaseIndexArray() SK_OVERRIDE;
156     virtual void geometrySourceWillPush() SK_OVERRIDE;
157     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
158     virtual void willReserveVertexAndIndexSpace(int vertexCount,
159                                                 int indexCount) SK_OVERRIDE;
160     virtual bool onCopySurface(GrSurface* dst,
161                                GrSurface* src,
162                                const SkIRect& srcRect,
163                                const SkIPoint& dstPoint)  SK_OVERRIDE;
164     virtual bool onCanCopySurface(GrSurface* dst,
165                                   GrSurface* src,
166                                   const SkIRect& srcRect,
167                                   const SkIPoint& dstPoint) SK_OVERRIDE;
168 
169     bool quickInsideClip(const SkRect& devBounds);
170 
171     // Attempts to concat instances from info onto the previous draw. info must represent an
172     // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
173     int concatInstancedDraw(const DrawInfo& info);
174 
175     // we lazily record state and clip changes in order to skip clips and states that have no
176     // effect.
177     bool needsNewState() const;
178     bool needsNewClip() const;
179 
180     // these functions record a command
181     void            recordState();
182     void            recordClip();
183     DrawRecord*     recordDraw(const DrawInfo&);
184     StencilPath*    recordStencilPath();
185     DrawPath*       recordDrawPath();
186     Clear*          recordClear();
187     CopySurface*    recordCopySurface();
188 
189     // TODO: Use a single allocator for commands and records
190     enum {
191         kCmdPreallocCnt          = 32,
192         kDrawPreallocCnt         = 8,
193         kStencilPathPreallocCnt  = 8,
194         kDrawPathPreallocCnt     = 8,
195         kStatePreallocCnt        = 8,
196         kClipPreallocCnt         = 8,
197         kClearPreallocCnt        = 4,
198         kGeoPoolStatePreAllocCnt = 4,
199         kCopySurfacePreallocCnt  = 4,
200     };
201 
202     SkSTArray<kCmdPreallocCnt, uint8_t, true>                          fCmds;
203     GrSTAllocator<kDrawPreallocCnt, DrawRecord>                        fDraws;
204     GrSTAllocator<kStatePreallocCnt, StencilPath>                      fStencilPaths;
205     GrSTAllocator<kStatePreallocCnt, DrawPath>                         fDrawPaths;
206     GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState>       fStates;
207     GrSTAllocator<kClearPreallocCnt, Clear>                            fClears;
208     GrSTAllocator<kCopySurfacePreallocCnt, CopySurface>                fCopySurfaces;
209     GrSTAllocator<kClipPreallocCnt, SkClipStack>                       fClips;
210     GrSTAllocator<kClipPreallocCnt, SkIPoint>                          fClipOrigins;
211 
212     GrDrawTarget*                   fDstGpu;
213 
214     bool                            fClipSet;
215 
216     enum ClipProxyState {
217         kUnknown_ClipProxyState,
218         kValid_ClipProxyState,
219         kInvalid_ClipProxyState
220     };
221     ClipProxyState                  fClipProxyState;
222     SkRect                          fClipProxy;
223 
224     GrVertexBufferAllocPool&        fVertexPool;
225 
226     GrIndexBufferAllocPool&         fIndexPool;
227 
228     struct GeometryPoolState {
229         const GrVertexBuffer*           fPoolVertexBuffer;
230         int                             fPoolStartVertex;
231         const GrIndexBuffer*            fPoolIndexBuffer;
232         int                             fPoolStartIndex;
233         // caller may conservatively over reserve vertices / indices.
234         // we release unused space back to allocator if possible
235         // can only do this if there isn't an intervening pushGeometrySource()
236         size_t                          fUsedPoolVertexBytes;
237         size_t                          fUsedPoolIndexBytes;
238     };
239     SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
240 
isIssued(uint32_t drawID)241     virtual bool       isIssued(uint32_t drawID) { return drawID != fDrawID; }
242 
243     bool                            fFlushing;
244     uint32_t                        fDrawID;
245 
246     typedef GrDrawTarget INHERITED;
247 };
248 
249 #endif
250