OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrTargetCommands.h" | 8 #include "GrTargetCommands.h" |
9 | 9 |
10 #include "GrColor.h" | 10 #include "GrColor.h" |
11 #include "GrDefaultGeoProcFactory.h" | 11 #include "GrDefaultGeoProcFactory.h" |
12 #include "GrInOrderDrawBuffer.h" | 12 #include "GrInOrderDrawBuffer.h" |
13 #include "GrTemplates.h" | 13 #include "GrTemplates.h" |
14 #include "SkPoint.h" | 14 #include "SkPoint.h" |
15 | 15 |
16 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { | 16 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { |
17 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; | 17 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; |
18 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); | 18 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); |
19 if (isWinding) { | 19 if (isWinding) { |
20 // Double check that it is in fact winding. | 20 // Double check that it is in fact winding. |
21 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); | 21 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); |
22 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); | 22 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); |
23 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); | 23 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); |
24 SkASSERT(!pathStencilSettings.isTwoSided()); | 24 SkASSERT(!pathStencilSettings.isTwoSided()); |
25 } | 25 } |
26 return isWinding; | 26 return isWinding; |
27 } | 27 } |
28 | 28 |
29 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( | 29 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch*
batch) { |
30 GrInOrderDrawBuffer* iodb, | |
31 GrBatch* batch, | |
32 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | |
33 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) { | |
34 return NULL; | |
35 } | |
36 | |
37 // Check if there is a Batch Draw we can batch with | 30 // Check if there is a Batch Draw we can batch with |
38 if (Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) { | 31 if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type
()) { |
39 DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back()); | 32 DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back()); |
40 if (previous->fBatch->combineIfPossible(batch)) { | 33 if (previous->fState == state && previous->fBatch->combineIfPossible(bat
ch)) { |
41 return NULL; | 34 return NULL; |
42 } | 35 } |
43 } | 36 } |
44 | 37 |
45 return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget
)); | 38 return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatc
hTarget)); |
46 } | 39 } |
47 | 40 |
48 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( | 41 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( |
49 GrInOrderDrawBuffer* iod
b, | |
50 const GrPipelineBuilder&
pipelineBuilder, | 42 const GrPipelineBuilder&
pipelineBuilder, |
51 const GrPathProcessor* p
athProc, | 43 const GrPathProcessor* p
athProc, |
52 const GrPath* path, | 44 const GrPath* path, |
53 const GrScissorState& sc
issorState, | 45 const GrScissorState& sc
issorState, |
54 const GrStencilSettings&
stencilSettings) { | 46 const GrStencilSettings&
stencilSettings) { |
55 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, | 47 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, |
56 (path, pipelineBuilder.getRenderT
arget())); | 48 (path, pipelineBuilder.getRenderT
arget())); |
57 | 49 |
58 sp->fScissor = scissorState; | 50 sp->fScissor = scissorState; |
59 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); | 51 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); |
60 sp->fViewMatrix = pathProc->viewMatrix(); | 52 sp->fViewMatrix = pathProc->viewMatrix(); |
61 sp->fStencil = stencilSettings; | 53 sp->fStencil = stencilSettings; |
62 return sp; | 54 return sp; |
63 } | 55 } |
64 | 56 |
65 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( | 57 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( |
66 GrInOrderDrawBuffer* iodb, | 58 State* state, |
67 const GrPathProcessor* pathPro
c, | 59 const GrPathProcessor* pathPro
c, |
68 const GrPath* path, | 60 const GrPath* path, |
69 const GrStencilSettings& stenc
ilSettings, | 61 const GrStencilSettings& stenc
ilSettings) { |
70 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 62 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path))
; |
71 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover
ing? | |
72 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { | |
73 return NULL; | |
74 } | |
75 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | |
76 dp->fStencilSettings = stencilSettings; | 63 dp->fStencilSettings = stencilSettings; |
77 return dp; | 64 return dp; |
78 } | 65 } |
79 | 66 |
80 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( | 67 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( |
| 68 State* state, |
81 GrInOrderDrawBuffer* iodb, | 69 GrInOrderDrawBuffer* iodb, |
82 const GrPathProcessor* pathPro
c, | 70 const GrPathProcessor* pathPro
c, |
83 const GrPathRange* pathRange, | 71 const GrPathRange* pathRange, |
84 const void* indexValues, | 72 const void* indexValues, |
85 GrDrawTarget::PathIndexType in
dexType, | 73 GrDrawTarget::PathIndexType in
dexType, |
86 const float transformValues[], | 74 const float transformValues[], |
87 GrDrawTarget::PathTransformTyp
e transformType, | 75 GrDrawTarget::PathTransformTyp
e transformType, |
88 int count, | 76 int count, |
89 const GrStencilSettings& stenc
ilSettings, | 77 const GrStencilSettings& stenc
ilSettings, |
90 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 78 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { |
91 SkASSERT(pathRange); | 79 SkASSERT(pathRange); |
92 SkASSERT(indexValues); | 80 SkASSERT(indexValues); |
93 SkASSERT(transformValues); | 81 SkASSERT(transformValues); |
94 | 82 |
95 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { | |
96 return NULL; | |
97 } | |
98 | |
99 char* savedIndices; | 83 char* savedIndices; |
100 float* savedTransforms; | 84 float* savedTransforms; |
101 | 85 |
102 iodb->appendIndicesAndTransforms(indexValues, indexType, | 86 iodb->appendIndicesAndTransforms(indexValues, indexType, |
103 transformValues, transformType, | 87 transformValues, transformType, |
104 count, &savedIndices, &savedTransforms); | 88 count, &savedIndices, &savedTransforms); |
105 | 89 |
106 if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) { | 90 if (!fCmdBuffer.empty() && Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type
()) { |
107 // The previous command was also DrawPaths. Try to collapse this call in
to the one | 91 // The previous command was also DrawPaths. Try to collapse this call in
to the one |
108 // before. Note that stenciling all the paths at once, then covering, ma
y not be | 92 // before. Note that stenciling all the paths at once, then covering, ma
y not be |
109 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, | 93 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, |
110 // and the combined calls may also cancel each other's winding numbers i
n some | 94 // and the combined calls may also cancel each other's winding numbers i
n some |
111 // places. For now the winding numbers are only an issue if the fill is
even/odd, | 95 // places. For now the winding numbers are only an issue if the fill is
even/odd, |
112 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same | 96 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same |
113 // font tend to all wind in the same direction. | 97 // font tend to all wind in the same direction. |
114 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); | 98 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); |
115 if (pathRange == previous->pathRange() && | 99 if (pathRange == previous->pathRange() && |
116 indexType == previous->fIndexType && | 100 indexType == previous->fIndexType && |
117 transformType == previous->fTransformType && | 101 transformType == previous->fTransformType && |
118 stencilSettings == previous->fStencilSettings && | 102 stencilSettings == previous->fStencilSettings && |
119 path_fill_type_is_winding(stencilSettings) && | 103 path_fill_type_is_winding(stencilSettings) && |
120 !pipelineInfo.willBlendWithDst(pathProc)) { | 104 !pipelineInfo.willBlendWithDst(pathProc) && |
| 105 previous->fState == state) { |
121 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy
pe); | 106 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy
pe); |
122 const int xformSize = GrPathRendering::PathTransformSize(transfo
rmType); | 107 const int xformSize = GrPathRendering::PathTransformSize(transfo
rmType); |
123 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd
ices && | 108 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd
ices && |
124 (0 == xformSize || | 109 (0 == xformSize || |
125 &previous->fTransforms[previous->fCount*xformSize] == saved
Transforms)) { | 110 &previous->fTransforms[previous->fCount*xformSize] == saved
Transforms)) { |
126 // Fold this DrawPaths call into the one previous. | 111 // Fold this DrawPaths call into the one previous. |
127 previous->fCount += count; | 112 previous->fCount += count; |
128 return NULL; | 113 return NULL; |
129 } | 114 } |
130 } | 115 } |
131 } | 116 } |
132 | 117 |
133 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; | 118 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, path
Range)); |
134 dp->fIndices = savedIndices; | 119 dp->fIndices = savedIndices; |
135 dp->fIndexType = indexType; | 120 dp->fIndexType = indexType; |
136 dp->fTransforms = savedTransforms; | 121 dp->fTransforms = savedTransforms; |
137 dp->fTransformType = transformType; | 122 dp->fTransformType = transformType; |
138 dp->fCount = count; | 123 dp->fCount = count; |
139 dp->fStencilSettings = stencilSettings; | 124 dp->fStencilSettings = stencilSettings; |
140 return dp; | 125 return dp; |
141 } | 126 } |
142 | 127 |
143 GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb, | 128 GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect, |
144 const SkIRect* rect, | |
145 GrColor color, | 129 GrColor color, |
146 bool canIgnoreRect, | 130 bool canIgnoreRect, |
147 GrRenderTarget* renderTarge
t) { | 131 GrRenderTarget* renderTarge
t) { |
148 SkASSERT(renderTarget); | 132 SkASSERT(renderTarget); |
149 | 133 |
150 SkIRect r; | 134 SkIRect r; |
151 if (NULL == rect) { | 135 if (NULL == rect) { |
152 // We could do something smart and remove previous draws and clears to | 136 // We could do something smart and remove previous draws and clears to |
153 // the current render target. If we get that smart we have to make sure | 137 // the current render target. If we get that smart we have to make sure |
154 // those draws aren't read before this clear (render-to-texture). | 138 // those draws aren't read before this clear (render-to-texture). |
155 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 139 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
156 rect = &r; | 140 rect = &r; |
157 } | 141 } |
158 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 142 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
159 GrColorIsPMAssert(color); | 143 GrColorIsPMAssert(color); |
160 clr->fColor = color; | 144 clr->fColor = color; |
161 clr->fRect = *rect; | 145 clr->fRect = *rect; |
162 clr->fCanIgnoreRect = canIgnoreRect; | 146 clr->fCanIgnoreRect = canIgnoreRect; |
163 return clr; | 147 return clr; |
164 } | 148 } |
165 | 149 |
166 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf
fer* iodb, | 150 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& r
ect, |
167 const SkIRect& r
ect, | |
168 bool insideClip, | 151 bool insideClip, |
169 GrRenderTarget*
renderTarget) { | 152 GrRenderTarget*
renderTarget) { |
170 SkASSERT(renderTarget); | 153 SkASSERT(renderTarget); |
171 | 154 |
172 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); | 155 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); |
173 clr->fRect = rect; | 156 clr->fRect = rect; |
174 clr->fInsideClip = insideClip; | 157 clr->fInsideClip = insideClip; |
175 return clr; | 158 return clr; |
176 } | 159 } |
177 | 160 |
178 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb
, | 161 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTar
get) { |
179 GrRenderTarget* renderTar
get) { | |
180 SkASSERT(renderTarget); | 162 SkASSERT(renderTarget); |
181 | 163 |
182 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 164 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
183 clr->fColor = GrColor_ILLEGAL; | 165 clr->fColor = GrColor_ILLEGAL; |
184 return clr; | 166 return clr; |
185 } | 167 } |
186 | 168 |
187 void GrTargetCommands::reset() { | 169 void GrTargetCommands::reset() { |
188 fCmdBuffer.reset(); | 170 fCmdBuffer.reset(); |
189 fPrevState = NULL; | |
190 } | 171 } |
191 | 172 |
192 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { | 173 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { |
193 if (fCmdBuffer.empty()) { | 174 if (fCmdBuffer.empty()) { |
194 return; | 175 return; |
195 } | 176 } |
196 | 177 |
197 // Updated every time we find a set state cmd to reflect the current state i
n the playback | |
198 // stream. | |
199 SetState* currentState = NULL; | |
200 | |
201 GrGpu* gpu = iodb->getGpu(); | 178 GrGpu* gpu = iodb->getGpu(); |
202 | 179 |
203 // Loop over all batches and generate geometry | 180 // Loop over all batches and generate geometry |
204 CmdBuffer::Iter genIter(fCmdBuffer); | 181 CmdBuffer::Iter genIter(fCmdBuffer); |
205 while (genIter.next()) { | 182 while (genIter.next()) { |
206 if (Cmd::kDrawBatch_CmdType == genIter->type()) { | 183 if (Cmd::kDrawBatch_CmdType == genIter->type()) { |
207 DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get()); | 184 DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get()); |
208 fBatchTarget.resetNumberOfDraws(); | 185 fBatchTarget.resetNumberOfDraws(); |
209 db->execute(NULL, currentState); | 186 db->fBatch->generateGeometry(&fBatchTarget, db->fState->getPipeline(
)); |
210 db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); | 187 db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); |
211 } else if (Cmd::kSetState_CmdType == genIter->type()) { | |
212 SetState* ss = reinterpret_cast<SetState*>(genIter.get()); | |
213 | |
214 ss->execute(gpu, currentState); | |
215 currentState = ss; | |
216 } | 188 } |
217 } | 189 } |
218 | 190 |
219 iodb->getVertexAllocPool()->unmap(); | 191 iodb->getVertexAllocPool()->unmap(); |
220 iodb->getIndexAllocPool()->unmap(); | 192 iodb->getIndexAllocPool()->unmap(); |
221 fBatchTarget.preFlush(); | 193 fBatchTarget.preFlush(); |
222 | 194 |
223 CmdBuffer::Iter iter(fCmdBuffer); | 195 CmdBuffer::Iter iter(fCmdBuffer); |
224 | 196 |
225 while (iter.next()) { | 197 while (iter.next()) { |
226 GrGpuTraceMarker newMarker("", -1); | 198 GrGpuTraceMarker newMarker("", -1); |
227 SkString traceString; | 199 SkString traceString; |
228 if (iter->isTraced()) { | 200 if (iter->isTraced()) { |
229 traceString = iodb->getCmdString(iter->markerID()); | 201 traceString = iodb->getCmdString(iter->markerID()); |
230 newMarker.fMarker = traceString.c_str(); | 202 newMarker.fMarker = traceString.c_str(); |
231 gpu->addGpuTraceMarker(&newMarker); | 203 gpu->addGpuTraceMarker(&newMarker); |
232 } | 204 } |
233 | 205 |
234 if (Cmd::kDrawBatch_CmdType == iter->type()) { | 206 iter->execute(gpu); |
235 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get()); | |
236 fBatchTarget.flushNext(db->fBatch->numberOfDraws()); | |
237 | |
238 if (iter->isTraced()) { | |
239 gpu->removeGpuTraceMarker(&newMarker); | |
240 } | |
241 continue; | |
242 } | |
243 | |
244 if (Cmd::kSetState_CmdType == iter->type()) { | |
245 // TODO this is just until NVPR is in batch | |
246 SetState* ss = reinterpret_cast<SetState*>(iter.get()); | |
247 | |
248 if (ss->fPrimitiveProcessor) { | |
249 ss->execute(gpu, currentState); | |
250 } | |
251 currentState = ss; | |
252 | |
253 } else { | |
254 iter->execute(gpu, currentState); | |
255 } | |
256 | |
257 if (iter->isTraced()) { | 207 if (iter->isTraced()) { |
258 gpu->removeGpuTraceMarker(&newMarker); | 208 gpu->removeGpuTraceMarker(&newMarker); |
259 } | 209 } |
260 } | 210 } |
261 | 211 |
262 fBatchTarget.postFlush(); | 212 fBatchTarget.postFlush(); |
263 } | 213 } |
264 | 214 |
265 void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) { | 215 void GrTargetCommands::StencilPath::execute(GrGpu* gpu) { |
266 GrGpu::StencilPathState state; | 216 GrGpu::StencilPathState state; |
267 state.fRenderTarget = fRenderTarget.get(); | 217 state.fRenderTarget = fRenderTarget.get(); |
268 state.fScissor = &fScissor; | 218 state.fScissor = &fScissor; |
269 state.fStencil = &fStencil; | 219 state.fStencil = &fStencil; |
270 state.fUseHWAA = fUseHWAA; | 220 state.fUseHWAA = fUseHWAA; |
271 state.fViewMatrix = &fViewMatrix; | 221 state.fViewMatrix = &fViewMatrix; |
272 | 222 |
273 gpu->stencilPath(this->path(), state); | 223 gpu->stencilPath(this->path(), state); |
274 } | 224 } |
275 | 225 |
276 void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) { | 226 void GrTargetCommands::DrawPath::execute(GrGpu* gpu) { |
277 SkASSERT(state); | 227 if (!fState->fCompiled) { |
278 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state
->fDesc, | 228 gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fSt
ate->getPipeline(), |
279 &state->fBatchTracker); | 229 fState->fBatchTracker); |
| 230 fState->fCompiled = true; |
| 231 } |
| 232 DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(), |
| 233 &fState->fDesc, &fState->fBatchTracker); |
280 gpu->drawPath(args, this->path(), fStencilSettings); | 234 gpu->drawPath(args, this->path(), fStencilSettings); |
281 } | 235 } |
282 | 236 |
283 void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) { | 237 void GrTargetCommands::DrawPaths::execute(GrGpu* gpu) { |
284 SkASSERT(state); | 238 if (!fState->fCompiled) { |
285 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state
->fDesc, | 239 gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fSt
ate->getPipeline(), |
286 &state->fBatchTracker); | 240 fState->fBatchTracker); |
| 241 fState->fCompiled = true; |
| 242 } |
| 243 DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(), |
| 244 &fState->fDesc, &fState->fBatchTracker); |
287 gpu->drawPaths(args, this->pathRange(), | 245 gpu->drawPaths(args, this->pathRange(), |
288 fIndices, fIndexType, | 246 fIndices, fIndexType, |
289 fTransforms, fTransformType, | 247 fTransforms, fTransformType, |
290 fCount, fStencilSettings); | 248 fCount, fStencilSettings); |
291 } | 249 } |
292 | 250 |
293 void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) { | 251 void GrTargetCommands::DrawBatch::execute(GrGpu*) { |
294 SkASSERT(state); | 252 fBatchTarget->flushNext(fBatch->numberOfDraws()); |
295 fBatch->generateGeometry(fBatchTarget, state->getPipeline()); | |
296 } | 253 } |
297 | 254 |
298 void GrTargetCommands::SetState::execute(GrGpu* gpu, const SetState*) { | 255 void GrTargetCommands::Clear::execute(GrGpu* gpu) { |
299 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventu
ally we | |
300 // will only have GrBatch and we can delete this | |
301 if (fPrimitiveProcessor) { | |
302 gpu->buildProgramDesc(&fDesc, *fPrimitiveProcessor, *getPipeline(), fBat
chTracker); | |
303 } | |
304 } | |
305 | |
306 void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) { | |
307 if (GrColor_ILLEGAL == fColor) { | 256 if (GrColor_ILLEGAL == fColor) { |
308 gpu->discard(this->renderTarget()); | 257 gpu->discard(this->renderTarget()); |
309 } else { | 258 } else { |
310 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); | 259 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); |
311 } | 260 } |
312 } | 261 } |
313 | 262 |
314 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) { | 263 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu) { |
315 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); | 264 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); |
316 } | 265 } |
317 | 266 |
318 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) { | 267 void GrTargetCommands::CopySurface::execute(GrGpu* gpu) { |
319 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); | 268 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
320 } | 269 } |
321 | 270 |
322 void GrTargetCommands::XferBarrier::execute(GrGpu* gpu, const SetState* state) { | 271 void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) { |
323 gpu->xferBarrier(fBarrierType); | 272 gpu->xferBarrier(fBarrierType); |
324 } | 273 } |
325 | 274 |
326 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst, | 275 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst, |
327 GrSurface* src, | 276 GrSurface* src, |
328 const SkIRect& srcRec
t, | 277 const SkIRect& srcRec
t, |
329 const SkIPoint& dstPo
int) { | 278 const SkIPoint& dstPo
int) { |
330 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, sr
c)); | 279 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, sr
c)); |
331 cs->fSrcRect = srcRect; | 280 cs->fSrcRect = srcRect; |
332 cs->fDstPoint = dstPoint; | 281 cs->fDstPoint = dstPoint; |
333 return cs; | 282 return cs; |
334 } | 283 } |
335 | 284 |
336 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, | 285 void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline, |
337 const GrPrimitiveProcessor* pr
imProc, | 286 GrInOrderDrawBuffer* iodb) { |
338 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 287 const GrXferProcessor& xp = *pipeline.getXferProcessor(); |
339 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc)); | 288 GrRenderTarget* rt = pipeline.getRenderTarget(); |
340 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); | |
341 | |
342 if (ss->getPipeline()->mustSkip()) { | |
343 fCmdBuffer.pop_back(); | |
344 return false; | |
345 } | |
346 | |
347 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker, | |
348 ss->getPipeline()->getInitBatchTra
cker()); | |
349 | |
350 if (fPrevState && fPrevState->fPrimitiveProcessor.get() && | |
351 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, | |
352 *ss->fPrimitiveProcessor, | |
353 ss->fBatchTracker) && | |
354 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { | |
355 fCmdBuffer.pop_back(); | |
356 } else { | |
357 fPrevState = ss; | |
358 iodb->recordTraceMarkersIfNecessary(ss); | |
359 } | |
360 | |
361 this->recordXferBarrierIfNecessary(iodb, pipelineInfo); | |
362 return true; | |
363 } | |
364 | |
365 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, | |
366 GrBatch* batch, | |
367 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | |
368 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ()); | |
369 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); | |
370 | |
371 if (ss->getPipeline()->mustSkip()) { | |
372 fCmdBuffer.pop_back(); | |
373 return false; | |
374 } | |
375 | |
376 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker()); | |
377 | |
378 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() && | |
379 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { | |
380 fCmdBuffer.pop_back(); | |
381 } else { | |
382 fPrevState = ss; | |
383 iodb->recordTraceMarkersIfNecessary(ss); | |
384 } | |
385 | |
386 this->recordXferBarrierIfNecessary(iodb, pipelineInfo); | |
387 return true; | |
388 } | |
389 | |
390 void GrTargetCommands::recordXferBarrierIfNecessary(GrInOrderDrawBuffer* iodb, | |
391 const GrDrawTarget::Pipeline
Info& info) { | |
392 SkASSERT(fPrevState); | |
393 const GrXferProcessor& xp = *fPrevState->getXferProcessor(); | |
394 GrRenderTarget* rt = fPrevState->getRenderTarget(); | |
395 | 289 |
396 GrXferBarrierType barrierType; | 290 GrXferBarrierType barrierType; |
397 if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) { | 291 if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) { |
398 return; | 292 return; |
399 } | 293 } |
400 | 294 |
401 XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, XferBarrier, ()); | 295 XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, XferBarrier, ()); |
402 xb->fBarrierType = barrierType; | 296 xb->fBarrierType = barrierType; |
403 | 297 |
404 iodb->recordTraceMarkersIfNecessary(xb); | 298 iodb->recordTraceMarkersIfNecessary(xb); |
405 } | 299 } |
406 | 300 |
OLD | NEW |