Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrInOrderDrawBuffer.h
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 "GrIndexBuffer.h"
15 #include "GrRenderTarget.h"
16 #include "GrPath.h"
17 #include "GrPathRange.h"
18 #include "GrSurface.h"
19 #include "GrTRecorder.h"
20 #include "GrVertexBuffer.h"
21
22 #include "SkClipStack.h"
23 #include "SkTemplates.h"
24 #include "SkTypes.h"
25
26 class GrGpu;
27 class GrIndexBufferAllocPool;
28 class GrVertexBufferAllocPool;
29
30 /**
31  * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
32  * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
33  * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
34  * references to the buffers. It is the callers responsibility to ensure that the data is still
35  * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
36  * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
37  * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
38  * store geometry.
39  */
40 class GrInOrderDrawBuffer : public GrClipTarget {
41 public:
42
43     /**
44      * Creates a GrInOrderDrawBuffer
45      *
46      * @param gpu        the gpu object that this draw buffer flushes to.
47      * @param vertexPool pool where vertices for queued draws will be saved when
48      *                   the vertex source is either reserved or array.
49      * @param indexPool  pool where indices for queued draws will be saved when
50      *                   the index source is either reserved or array.
51      */
52     GrInOrderDrawBuffer(GrGpu* gpu,
53                         GrVertexBufferAllocPool* vertexPool,
54                         GrIndexBufferAllocPool* indexPool);
55
56     virtual ~GrInOrderDrawBuffer();
57
58     /**
59      * Empties the draw buffer of any queued up draws. This must not be called while inside an
60      * unbalanced pushGeometrySource(). The current draw state and clip are preserved.
61      */
62     void reset();
63
64     /**
65      * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing
66      * is destructive). This buffer must not have an active reserved vertex or index source. Any
67      * reserved geometry on the target will be finalized because it's geometry source will be pushed
68      * before flushing and popped afterwards.
69      */
70     void flush();
71
72     // tracking for draws
73     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
74
75     // overrides from GrDrawTarget
76     virtual bool geometryHints(int* vertexCount,
77                                int* indexCount) const SK_OVERRIDE;
78
79     virtual bool copySurface(GrSurface* dst,
80                              GrSurface* src,
81                              const SkIRect& srcRect,
82                              const SkIPoint& dstPoint)  SK_OVERRIDE;
83
84     virtual bool canCopySurface(GrSurface* dst,
85                                 GrSurface* src,
86                                 const SkIRect& srcRect,
87                                 const SkIPoint& dstPoint) SK_OVERRIDE;
88
89     virtual void clearStencilClip(const SkIRect& rect,
90                                   bool insideClip,
91                                   GrRenderTarget* renderTarget) SK_OVERRIDE;
92
93     virtual void discard(GrRenderTarget*) SK_OVERRIDE;
94
95     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) SK_OVERRIDE;
96
97 protected:
98     virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
99
100 private:
101     enum {
102         kDraw_Cmd           = 1,
103         kStencilPath_Cmd    = 2,
104         kSetState_Cmd       = 3,
105         kSetClip_Cmd        = 4,
106         kClear_Cmd          = 5,
107         kCopySurface_Cmd    = 6,
108         kDrawPath_Cmd       = 7,
109         kDrawPaths_Cmd      = 8,
110     };
111
112     struct Cmd : ::SkNoncopyable {
113         Cmd(uint8_t type) : fType(type) {}
114         virtual ~Cmd() {}
115
116         virtual void execute(GrClipTarget*) = 0;
117
118         uint8_t fType;
119     };
120
121     struct Draw : public Cmd {
122         Draw(const DrawInfo& info, const GrVertexBuffer* vb, const GrIndexBuffer* ib)
123             : Cmd(kDraw_Cmd)
124             , fInfo(info)
125             , fVertexBuffer(vb)
126             , fIndexBuffer(ib) {}
127
128         const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
129         const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
130
131         virtual void execute(GrClipTarget*);
132
133         DrawInfo fInfo;
134
135     private:
136         GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType>    fVertexBuffer;
137         GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType>     fIndexBuffer;
138     };
139
140     struct StencilPath : public Cmd {
141         StencilPath(const GrPath* path) : Cmd(kStencilPath_Cmd), fPath(path) {}
142
143         const GrPath* path() const { return fPath.get(); }
144
145         virtual void execute(GrClipTarget*);
146
147         GrPathRendering::FillType fFill;
148
149     private:
150         GrPendingIOResource<const GrPath, kRead_GrIOType>   fPath;
151     };
152
153     struct DrawPath : public Cmd {
154         DrawPath(const GrPath* path) : Cmd(kDrawPath_Cmd), fPath(path) {}
155
156         const GrPath* path() const { return fPath.get(); }
157
158         virtual void execute(GrClipTarget*);
159
160         GrPathRendering::FillType fFill;
161         GrDeviceCoordTexture      fDstCopy;
162
163     private:
164         GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
165     };
166
167     struct DrawPaths : public Cmd {
168         DrawPaths(const GrPathRange* pathRange) : Cmd(kDrawPaths_Cmd), fPathRange(pathRange) {}
169
170         const GrPathRange* pathRange() const { return fPathRange.get();  }
171         uint32_t* indices() { return reinterpret_cast<uint32_t*>(CmdBuffer::GetDataForItem(this)); }
172         float* transforms() { return reinterpret_cast<float*>(&this->indices()[fCount]); }
173
174         virtual void execute(GrClipTarget*);
175
176         size_t                    fCount;
177         PathTransformType         fTransformsType;
178         GrPathRendering::FillType fFill;
179         GrDeviceCoordTexture      fDstCopy;
180
181     private:
182         GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
183     };
184
185     // This is also used to record a discard by setting the color to GrColor_ILLEGAL
186     struct Clear : public Cmd {
187         Clear(GrRenderTarget* rt) : Cmd(kClear_Cmd), fRenderTarget(rt) {}
188
189         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
190
191         virtual void execute(GrClipTarget*);
192
193         SkIRect fRect;
194         GrColor fColor;
195         bool    fCanIgnoreRect;
196
197     private:
198         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
199     };
200
201     // This command is ONLY used by the clip mask manager to clear the stencil clip bits
202     struct ClearStencilClip : public Cmd {
203         ClearStencilClip(GrRenderTarget* rt) : Cmd(kClear_Cmd), fRenderTarget(rt) {}
204
205         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
206
207         virtual void execute(GrClipTarget*);
208
209         SkIRect fRect;
210         bool    fInsideClip;
211
212     private:
213         GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
214     };
215
216     struct CopySurface : public Cmd {
217         CopySurface(GrSurface* dst, GrSurface* src) : Cmd(kCopySurface_Cmd), fDst(dst), fSrc(src) {}
218
219         GrSurface* dst() const { return fDst.get(); }
220         GrSurface* src() const { return fSrc.get(); }
221
222         virtual void execute(GrClipTarget*);
223
224         SkIPoint    fDstPoint;
225         SkIRect     fSrcRect;
226
227     private:
228         GrPendingIOResource<GrSurface, kWrite_GrIOType> fDst;
229         GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc;
230     };
231
232     struct SetState : public Cmd {
233         SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {}
234
235         virtual void execute(GrClipTarget*);
236
237         GrDrawState fState;
238     };
239
240     struct SetClip : public Cmd {
241         SetClip(const GrClipData* clipData)
242             : Cmd(kSetClip_Cmd),
243               fStackStorage(*clipData->fClipStack) {
244             fClipData.fClipStack = &fStackStorage;
245             fClipData.fOrigin = clipData->fOrigin;
246         }
247
248         virtual void execute(GrClipTarget*);
249
250         GrClipData fClipData;
251
252     private:
253         SkClipStack fStackStorage;
254     };
255
256     typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
257     typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
258
259     // overrides from GrDrawTarget
260     virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
261     virtual void onDrawRect(const SkRect& rect,
262                             const SkRect* localRect,
263                             const SkMatrix* localMatrix) SK_OVERRIDE;
264
265     virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) SK_OVERRIDE;
266     virtual void onDrawPath(const GrPath*, GrPathRendering::FillType,
267                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
268     virtual void onDrawPaths(const GrPathRange*,
269                              const uint32_t indices[], int count,
270                              const float transforms[], PathTransformType,
271                              GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
272     virtual void onClear(const SkIRect* rect,
273                          GrColor color,
274                          bool canIgnoreRect,
275                          GrRenderTarget* renderTarget) SK_OVERRIDE;
276
277     virtual bool onReserveVertexSpace(size_t vertexSize,
278                                       int vertexCount,
279                                       void** vertices) SK_OVERRIDE;
280     virtual bool onReserveIndexSpace(int indexCount,
281                                      void** indices) SK_OVERRIDE;
282     virtual void releaseReservedVertexSpace() SK_OVERRIDE;
283     virtual void releaseReservedIndexSpace() SK_OVERRIDE;
284     virtual void geometrySourceWillPush() SK_OVERRIDE;
285     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
286     virtual void willReserveVertexAndIndexSpace(int vertexCount,
287                                                 int indexCount) SK_OVERRIDE;
288
289     bool quickInsideClip(const SkRect& devBounds);
290
291     virtual void didAddGpuTraceMarker() SK_OVERRIDE {}
292     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE {}
293
294     // Attempts to concat instances from info onto the previous draw. info must represent an
295     // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
296     int concatInstancedDraw(const DrawInfo& info);
297
298     // Determines whether the current draw operation requieres a new drawstate and if so records it.
299     void recordStateIfNecessary();
300     // We lazily record clip changes in order to skip clips that have no effect.
301     void recordClipIfNecessary();
302     // Records any trace markers for a command after adding it to the buffer.
303     void recordTraceMarkersIfNecessary();
304
305     virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
306
307     // TODO: Use a single allocator for commands and records
308     enum {
309         kCmdBufferInitialSizeInBytes = 64 * 1024,
310         kGeoPoolStatePreAllocCnt     = 4,
311     };
312
313     CmdBuffer                         fCmdBuffer;
314     GrDrawState*                      fLastState;
315     GrClipData*                       fLastClip;
316
317     SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
318     GrClipTarget*                     fDstGpu;
319     bool                              fClipSet;
320
321     enum ClipProxyState {
322         kUnknown_ClipProxyState,
323         kValid_ClipProxyState,
324         kInvalid_ClipProxyState
325     };
326
327     ClipProxyState                                      fClipProxyState;
328     SkRect                                              fClipProxy;
329     GrVertexBufferAllocPool&                            fVertexPool;
330     GrIndexBufferAllocPool&                             fIndexPool;
331
332     struct GeometryPoolState {
333         const GrVertexBuffer*   fPoolVertexBuffer;
334         int                     fPoolStartVertex;
335         const GrIndexBuffer*    fPoolIndexBuffer;
336         int                     fPoolStartIndex;
337         // caller may conservatively over reserve vertices / indices.
338         // we release unused space back to allocator if possible
339         // can only do this if there isn't an intervening pushGeometrySource()
340         size_t                  fUsedPoolVertexBytes;
341         size_t                  fUsedPoolIndexBytes;
342     };
343
344     typedef SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> GeoPoolStateStack;
345
346     GeoPoolStateStack                                   fGeoPoolStateStack;
347     bool                                                fFlushing;
348     uint32_t                                            fDrawID;
349
350     typedef GrClipTarget INHERITED;
351 };
352
353 #endif