OLD | NEW |
| (Empty) |
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 "GrCommandBuilder.h" | |
13 #include "SkChunkAlloc.h" | |
14 | |
15 /** | |
16 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws
for eventual | |
17 * playback into a GrGpu. In theory one draw buffer could playback into another.
When index or | |
18 * vertex buffers are used as geometry sources it is the callers the draw buffer
only holds | |
19 * references to the buffers. It is the callers responsibility to ensure that th
e data is still | |
20 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the
caller's | |
21 * responsibility to ensure that all referenced textures, buffers, and render-ta
rgets are associated | |
22 * in the GrGpu object that the buffer is played back into. The buffer requires
VB and IB pools to | |
23 * store geometry. | |
24 */ | |
25 class GrInOrderDrawBuffer : public GrClipTarget { | |
26 public: | |
27 | |
28 /** | |
29 * Creates a GrInOrderDrawBuffer | |
30 * | |
31 * @param context the context object that owns this draw buffer. | |
32 */ | |
33 GrInOrderDrawBuffer(GrContext* context); | |
34 | |
35 ~GrInOrderDrawBuffer() override; | |
36 | |
37 void clearStencilClip(const SkIRect& rect, | |
38 bool insideClip, | |
39 GrRenderTarget* renderTarget) override; | |
40 | |
41 void discard(GrRenderTarget*) override; | |
42 | |
43 protected: | |
44 void appendIndicesAndTransforms(const void* indexValues, PathIndexType index
Type, | |
45 const float* transformValues, PathTransformT
ype transformType, | |
46 int count, char** indicesLocation, float** x
formsLocation) { | |
47 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType); | |
48 *indicesLocation = (char*) fPathIndexBuffer.alloc(count * indexBytes, | |
49 SkChunkAlloc::kThrow_A
llocFailType); | |
50 SkASSERT(SkIsAlign4((uintptr_t)*indicesLocation)); | |
51 memcpy(*indicesLocation, reinterpret_cast<const char*>(indexValues), cou
nt * indexBytes); | |
52 | |
53 const int xformBytes = GrPathRendering::PathTransformSize(transformType)
* sizeof(float); | |
54 *xformsLocation = NULL; | |
55 | |
56 if (0 != xformBytes) { | |
57 *xformsLocation = (float*) fPathTransformBuffer.alloc(count * xformB
ytes, | |
58 SkChunkAlloc::kTh
row_AllocFailType); | |
59 SkASSERT(SkIsAlign4((uintptr_t)*xformsLocation)); | |
60 memcpy(*xformsLocation, transformValues, count * xformBytes); | |
61 } | |
62 } | |
63 | |
64 private: | |
65 friend class GrInOrderCommandBuilder; | |
66 friend class GrTargetCommands; | |
67 | |
68 typedef GrTargetCommands::State State; | |
69 | |
70 State* allocState(const GrPrimitiveProcessor* primProc = NULL) { | |
71 void* allocation = fPipelineBuffer.alloc(sizeof(State), SkChunkAlloc::kT
hrow_AllocFailType); | |
72 return SkNEW_PLACEMENT_ARGS(allocation, State, (primProc)); | |
73 } | |
74 | |
75 void unallocState(State* state) { | |
76 state->unref(); | |
77 fPipelineBuffer.unalloc(state); | |
78 } | |
79 | |
80 void onReset() override; | |
81 void onFlush() override; | |
82 | |
83 // overrides from GrDrawTarget | |
84 void onDrawBatch(GrBatch*, const PipelineInfo&) override; | |
85 void onStencilPath(const GrPipelineBuilder&, | |
86 const GrPathProcessor*, | |
87 const GrPath*, | |
88 const GrScissorState&, | |
89 const GrStencilSettings&) override; | |
90 void onDrawPath(const GrPathProcessor*, | |
91 const GrPath*, | |
92 const GrStencilSettings&, | |
93 const PipelineInfo&) override; | |
94 void onDrawPaths(const GrPathProcessor*, | |
95 const GrPathRange*, | |
96 const void* indices, | |
97 PathIndexType, | |
98 const float transformValues[], | |
99 PathTransformType, | |
100 int count, | |
101 const GrStencilSettings&, | |
102 const PipelineInfo&) override; | |
103 void onClear(const SkIRect* rect, | |
104 GrColor color, | |
105 bool canIgnoreRect, | |
106 GrRenderTarget* renderTarget) override; | |
107 void onCopySurface(GrSurface* dst, | |
108 GrSurface* src, | |
109 const SkIRect& srcRect, | |
110 const SkIPoint& dstPoint) override; | |
111 | |
112 // Records any trace markers for a command | |
113 void recordTraceMarkersIfNecessary(GrTargetCommands::Cmd*); | |
114 SkString getCmdString(int index) const { | |
115 SkASSERT(index < fGpuCmdMarkers.count()); | |
116 return fGpuCmdMarkers[index].toString(); | |
117 } | |
118 bool isIssued(uint32_t drawID) override { return drawID != fDrawID; } | |
119 | |
120 State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(const GrPrimitivePro
cessor*, | |
121 const GrDrawTarget::
PipelineInfo&); | |
122 State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrBatch*, | |
123 const GrDrawTarget::
PipelineInfo&); | |
124 | |
125 // TODO: Use a single allocator for commands and records | |
126 enum { | |
127 kPathIdxBufferMinReserve = 2 * 64, // 64 uint16_t's | |
128 kPathXformBufferMinReserve = 2 * 64, // 64 two-float transforms | |
129 kPipelineBufferMinReserve = 32 * sizeof(State), | |
130 }; | |
131 | |
132 // every 100 flushes we should reset our fPipelineBuffer to prevent us from
holding at a | |
133 // highwater mark | |
134 static const int kPipelineBufferHighWaterMark = 100; | |
135 | |
136 SkAutoTDelete<GrCommandBuilder> fCommands; | |
137 SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers; | |
138 SkChunkAlloc fPathIndexBuffer; | |
139 SkChunkAlloc fPathTransformBuffer; | |
140 SkChunkAlloc fPipelineBuffer; | |
141 uint32_t fDrawID; | |
142 SkAutoTUnref<State> fPrevState; | |
143 | |
144 typedef GrClipTarget INHERITED; | |
145 }; | |
146 | |
147 #endif | |
OLD | NEW |