OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrInOrderDrawBuffer.h" | 8 #include "GrInOrderDrawBuffer.h" |
9 | 9 |
10 #include "GrBufferAllocPool.h" | 10 #include "GrBufferAllocPool.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 kTraceCmdBit = 0x80, | 97 kTraceCmdBit = 0x80, |
98 kCmdMask = 0x7f, | 98 kCmdMask = 0x7f, |
99 }; | 99 }; |
100 | 100 |
101 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } | 101 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } |
102 | 102 |
103 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } | 103 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } |
104 | 104 |
105 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr
aceCmdBit); } | 105 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr
aceCmdBit); } |
106 | 106 |
107 void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, | 107 void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds, |
| 108 const SkRect& rect, |
108 const SkRect* localRect, | 109 const SkRect* localRect, |
109 const SkMatrix* localMatrix) { | 110 const SkMatrix* localMatrix) { |
110 GrDrawState* drawState = this->drawState(); | 111 GrDrawState::AutoRestoreEffects are(ds); |
111 GrDrawState::AutoRestoreEffects are(drawState); | |
112 | 112 |
113 GrColor color = drawState->getColor(); | 113 GrColor color = ds->getColor(); |
| 114 set_vertex_attributes(ds, SkToBool(localRect), color); |
114 | 115 |
115 set_vertex_attributes(drawState, SkToBool(localRect), color); | 116 AutoReleaseGeometry geo(this, 4, ds->getVertexStride(), 0); |
116 | |
117 AutoReleaseGeometry geo(this, 4, 0); | |
118 if (!geo.succeeded()) { | 117 if (!geo.succeeded()) { |
119 SkDebugf("Failed to get space for vertices!\n"); | 118 SkDebugf("Failed to get space for vertices!\n"); |
120 return; | 119 return; |
121 } | 120 } |
122 | 121 |
123 // Go to device coords to allow batching across matrix changes | 122 // Go to device coords to allow batching across matrix changes |
124 SkMatrix matrix = drawState->getViewMatrix(); | 123 SkMatrix matrix = ds->getViewMatrix(); |
125 | 124 |
126 // When the caller has provided an explicit source rect for a stage then we
don't want to | 125 // When the caller has provided an explicit source rect for a stage then we
don't want to |
127 // modify that stage's matrix. Otherwise if the effect is generating its sou
rce rect from | 126 // modify that stage's matrix. Otherwise if the effect is generating its sou
rce rect from |
128 // the vertex positions then we have to account for the view matrix change. | 127 // the vertex positions then we have to account for the view matrix change. |
129 GrDrawState::AutoViewMatrixRestore avmr; | 128 GrDrawState::AutoViewMatrixRestore avmr; |
130 if (!avmr.setIdentity(drawState)) { | 129 if (!avmr.setIdentity(ds)) { |
131 return; | 130 return; |
132 } | 131 } |
133 | 132 |
134 size_t vstride = drawState->getVertexStride(); | 133 size_t vstride = ds->getVertexStride(); |
135 | 134 |
136 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom
, vstride); | 135 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom
, vstride); |
137 matrix.mapPointsWithStride(geo.positions(), vstride, 4); | 136 matrix.mapPointsWithStride(geo.positions(), vstride, 4); |
138 | 137 |
139 SkRect devBounds; | 138 SkRect devBounds; |
140 // since we already computed the dev verts, set the bounds hint. This will h
elp us avoid | 139 // since we already computed the dev verts, set the bounds hint. This will h
elp us avoid |
141 // unnecessary clipping in our onDraw(). | 140 // unnecessary clipping in our onDraw(). |
142 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); | 141 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); |
143 | 142 |
144 if (localRect) { | 143 if (localRect) { |
145 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); | 144 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); |
146 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
kLocalOffset); | 145 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
kLocalOffset); |
147 coords->setRectFan(localRect->fLeft, localRect->fTop, | 146 coords->setRectFan(localRect->fLeft, localRect->fTop, |
148 localRect->fRight, localRect->fBottom, | 147 localRect->fRight, localRect->fBottom, |
149 vstride); | 148 vstride); |
150 if (localMatrix) { | 149 if (localMatrix) { |
151 localMatrix->mapPointsWithStride(coords, vstride, 4); | 150 localMatrix->mapPointsWithStride(coords, vstride, 4); |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 static const int kColorOffset = sizeof(SkPoint); | 154 static const int kColorOffset = sizeof(SkPoint); |
156 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k
ColorOffset); | 155 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k
ColorOffset); |
157 for (int i = 0; i < 4; ++i) { | 156 for (int i = 0; i < 4; ++i) { |
158 *vertColor = color; | 157 *vertColor = color; |
159 vertColor = (GrColor*) ((intptr_t) vertColor + vstride); | 158 vertColor = (GrColor*) ((intptr_t) vertColor + vstride); |
160 } | 159 } |
161 | 160 |
162 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); | 161 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); |
163 this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds); | 162 this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBoun
ds); |
164 | |
165 // to ensure that stashing the drawState ptr is valid | |
166 SkASSERT(this->drawState() == drawState); | |
167 } | 163 } |
168 | 164 |
169 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info, | 165 int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, |
| 166 const DrawInfo& info, |
170 const GrClipMaskManager::ScissorSta
te& scissorState) { | 167 const GrClipMaskManager::ScissorSta
te& scissorState) { |
171 SkASSERT(!fCmdBuffer.empty()); | 168 SkASSERT(!fCmdBuffer.empty()); |
172 SkASSERT(info.isInstanced()); | 169 SkASSERT(info.isInstanced()); |
173 | 170 |
174 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 171 const GeometrySrcState& geomSrc = this->getGeomSrc(); |
175 const GrDrawState& drawState = this->getDrawState(); | |
176 | 172 |
177 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | 173 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index |
178 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | 174 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated |
179 // between draws. | 175 // between draws. |
180 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | 176 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || |
181 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | 177 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { |
182 return 0; | 178 return 0; |
183 } | 179 } |
184 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 180 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
185 // the same IB | 181 // the same IB |
(...skipping 21 matching lines...) Expand all Loading... |
207 } | 203 } |
208 | 204 |
209 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); | 205 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); |
210 | 206 |
211 // how many instances can be concat'ed onto draw given the size of the index
buffer | 207 // how many instances can be concat'ed onto draw given the size of the index
buffer |
212 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); | 208 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); |
213 instancesToConcat -= draw->fInfo.instanceCount(); | 209 instancesToConcat -= draw->fInfo.instanceCount(); |
214 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 210 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
215 | 211 |
216 // update the amount of reserved vertex data actually referenced in draws | 212 // update the amount of reserved vertex data actually referenced in draws |
217 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * | 213 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * ds.get
VertexStride(); |
218 drawState.getVertexStride(); | |
219 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); | 214 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); |
220 | 215 |
221 draw->fInfo.adjustInstanceCount(instancesToConcat); | 216 draw->fInfo.adjustInstanceCount(instancesToConcat); |
222 | 217 |
223 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 218 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
224 if (this->getActiveTraceMarkers().count() > 0) { | 219 if (this->getActiveTraceMarkers().count() > 0) { |
225 if (cmd_has_trace_marker(draw->fType)) { | 220 if (cmd_has_trace_marker(draw->fType)) { |
226 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); | 221 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); |
227 } else { | 222 } else { |
228 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); | 223 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); |
229 draw->fType = add_trace_bit(draw->fType); | 224 draw->fType = add_trace_bit(draw->fType); |
230 } | 225 } |
231 } | 226 } |
232 | 227 |
233 return instancesToConcat; | 228 return instancesToConcat; |
234 } | 229 } |
235 | 230 |
236 void GrInOrderDrawBuffer::onDraw(const DrawInfo& info, | 231 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, |
| 232 const DrawInfo& info, |
237 const GrClipMaskManager::ScissorState& scissorS
tate) { | 233 const GrClipMaskManager::ScissorState& scissorS
tate) { |
238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 234 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
239 const GrDrawState& drawState = this->getDrawState(); | |
240 | 235 |
241 this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType())
, | 236 this->recordStateIfNecessary(ds, |
| 237 GrGpu::PrimTypeToDrawType(info.primitiveType())
, |
242 info.getDstCopy()); | 238 info.getDstCopy()); |
243 | 239 |
244 const GrVertexBuffer* vb; | 240 const GrVertexBuffer* vb; |
245 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 241 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
246 vb = this->getGeomSrc().fVertexBuffer; | 242 vb = this->getGeomSrc().fVertexBuffer; |
247 } else { | 243 } else { |
248 vb = poolState.fPoolVertexBuffer; | 244 vb = poolState.fPoolVertexBuffer; |
249 } | 245 } |
250 | 246 |
251 const GrIndexBuffer* ib = NULL; | 247 const GrIndexBuffer* ib = NULL; |
252 if (info.isIndexed()) { | 248 if (info.isIndexed()) { |
253 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 249 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { |
254 ib = this->getGeomSrc().fIndexBuffer; | 250 ib = this->getGeomSrc().fIndexBuffer; |
255 } else { | 251 } else { |
256 ib = poolState.fPoolIndexBuffer; | 252 ib = poolState.fPoolIndexBuffer; |
257 } | 253 } |
258 } | 254 } |
259 | 255 |
260 Draw* draw; | 256 Draw* draw; |
261 if (info.isInstanced()) { | 257 if (info.isInstanced()) { |
262 int instancesConcated = this->concatInstancedDraw(info, scissorState); | 258 int instancesConcated = this->concatInstancedDraw(ds, info, scissorState
); |
263 if (info.instanceCount() > instancesConcated) { | 259 if (info.instanceCount() > instancesConcated) { |
264 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e, vb, ib)); | 260 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e, vb, ib)); |
265 draw->fInfo.adjustInstanceCount(-instancesConcated); | 261 draw->fInfo.adjustInstanceCount(-instancesConcated); |
266 } else { | 262 } else { |
267 return; | 263 return; |
268 } | 264 } |
269 } else { | 265 } else { |
270 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v
b, ib)); | 266 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v
b, ib)); |
271 } | 267 } |
272 this->recordTraceMarkersIfNecessary(); | 268 this->recordTraceMarkersIfNecessary(); |
273 | 269 |
274 // Adjust the starting vertex and index when we are using reserved or array
sources to | 270 // Adjust the starting vertex and index when we are using reserved or array
sources to |
275 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. | 271 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. |
276 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { | 272 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { |
277 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); | 273 size_t bytes = (info.vertexCount() + info.startVertex()) * ds.getVertexS
tride(); |
278 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); | 274 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); |
279 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); | 275 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); |
280 } | 276 } |
281 | 277 |
282 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { | 278 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { |
283 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); | 279 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); |
284 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 280 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
285 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); | 281 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); |
286 } | 282 } |
287 } | 283 } |
288 | 284 |
289 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, | 285 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, |
| 286 const GrPath* path, |
290 const GrClipMaskManager::ScissorState& s
cissorState, | 287 const GrClipMaskManager::ScissorState& s
cissorState, |
291 const GrStencilSettings& stencilSettings
) { | 288 const GrStencilSettings& stencilSettings
) { |
292 // Only compare the subset of GrDrawState relevant to path stenciling? | 289 // Only compare the subset of GrDrawState relevant to path stenciling? |
293 this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL); | 290 this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL); |
294 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); | 291 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
295 sp->fScissorState = scissorState; | 292 sp->fScissorState = scissorState; |
296 sp->fStencilSettings = stencilSettings; | 293 sp->fStencilSettings = stencilSettings; |
297 this->recordTraceMarkersIfNecessary(); | 294 this->recordTraceMarkersIfNecessary(); |
298 } | 295 } |
299 | 296 |
300 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, | 297 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, |
| 298 const GrPath* path, |
301 const GrClipMaskManager::ScissorState& scis
sorState, | 299 const GrClipMaskManager::ScissorState& scis
sorState, |
302 const GrStencilSettings& stencilSettings, | 300 const GrStencilSettings& stencilSettings, |
303 const GrDeviceCoordTexture* dstCopy) { | 301 const GrDeviceCoordTexture* dstCopy) { |
304 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 302 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
305 this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy); | 303 this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy); |
306 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 304 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
307 if (dstCopy) { | 305 if (dstCopy) { |
308 dp->fDstCopy = *dstCopy; | 306 dp->fDstCopy = *dstCopy; |
309 } | 307 } |
310 dp->fScissorState = scissorState; | 308 dp->fScissorState = scissorState; |
311 dp->fStencilSettings = stencilSettings; | 309 dp->fStencilSettings = stencilSettings; |
312 this->recordTraceMarkersIfNecessary(); | 310 this->recordTraceMarkersIfNecessary(); |
313 } | 311 } |
314 | 312 |
315 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, | 313 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, |
| 314 const GrPathRange* pathRange, |
316 const uint32_t indices[], | 315 const uint32_t indices[], |
317 int count, | 316 int count, |
318 const float transforms[], | 317 const float transforms[], |
319 PathTransformType transformsType, | 318 PathTransformType transformsType, |
320 const GrClipMaskManager::ScissorState& sci
ssorState, | 319 const GrClipMaskManager::ScissorState& sci
ssorState, |
321 const GrStencilSettings& stencilSettings, | 320 const GrStencilSettings& stencilSettings, |
322 const GrDeviceCoordTexture* dstCopy) { | 321 const GrDeviceCoordTexture* dstCopy) { |
323 SkASSERT(pathRange); | 322 SkASSERT(pathRange); |
324 SkASSERT(indices); | 323 SkASSERT(indices); |
325 SkASSERT(transforms); | 324 SkASSERT(transforms); |
326 | 325 |
327 this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy); | 326 this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy); |
328 | 327 |
329 int sizeOfIndices = sizeof(uint32_t) * count; | 328 int sizeOfIndices = sizeof(uint32_t) * count; |
330 int sizeOfTransforms = sizeof(float) * count * | 329 int sizeOfTransforms = sizeof(float) * count * |
331 GrPathRendering::PathTransformSize(transformsType); | 330 GrPathRendering::PathTransformSize(transformsType); |
332 | 331 |
333 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), | 332 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), |
334 sizeOfIndices + sizeOfTra
nsforms); | 333 sizeOfIndices + sizeOfTra
nsforms); |
335 memcpy(dp->indices(), indices, sizeOfIndices); | 334 memcpy(dp->indices(), indices, sizeOfIndices); |
336 dp->fCount = count; | 335 dp->fCount = count; |
337 memcpy(dp->transforms(), transforms, sizeOfTransforms); | 336 memcpy(dp->transforms(), transforms, sizeOfTransforms); |
338 dp->fTransformsType = transformsType; | 337 dp->fTransformsType = transformsType; |
339 dp->fScissorState = scissorState; | 338 dp->fScissorState = scissorState; |
340 dp->fStencilSettings = stencilSettings; | 339 dp->fStencilSettings = stencilSettings; |
341 if (dstCopy) { | 340 if (dstCopy) { |
342 dp->fDstCopy = *dstCopy; | 341 dp->fDstCopy = *dstCopy; |
343 } | 342 } |
344 | 343 |
345 this->recordTraceMarkersIfNecessary(); | 344 this->recordTraceMarkersIfNecessary(); |
346 } | 345 } |
347 | 346 |
348 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, | 347 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, |
349 bool canIgnoreRect, GrRenderTarget* renderTarg
et) { | 348 bool canIgnoreRect, GrRenderTarget* renderTarg
et) { |
| 349 SkASSERT(renderTarget); |
350 SkIRect r; | 350 SkIRect r; |
351 if (NULL == renderTarget) { | |
352 renderTarget = this->drawState()->getRenderTarget(); | |
353 SkASSERT(renderTarget); | |
354 } | |
355 if (NULL == rect) { | 351 if (NULL == rect) { |
356 // We could do something smart and remove previous draws and clears to | 352 // We could do something smart and remove previous draws and clears to |
357 // the current render target. If we get that smart we have to make sure | 353 // the current render target. If we get that smart we have to make sure |
358 // those draws aren't read before this clear (render-to-texture). | 354 // those draws aren't read before this clear (render-to-texture). |
359 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 355 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
360 rect = &r; | 356 rect = &r; |
361 } | 357 } |
362 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 358 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
363 GrColorIsPMAssert(color); | 359 GrColorIsPMAssert(color); |
364 clr->fColor = color; | 360 clr->fColor = color; |
365 clr->fRect = *rect; | 361 clr->fRect = *rect; |
366 clr->fCanIgnoreRect = canIgnoreRect; | 362 clr->fCanIgnoreRect = canIgnoreRect; |
367 this->recordTraceMarkersIfNecessary(); | 363 this->recordTraceMarkersIfNecessary(); |
368 } | 364 } |
369 | 365 |
370 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, | 366 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, |
371 bool insideClip, | 367 bool insideClip, |
372 GrRenderTarget* renderTarget) { | 368 GrRenderTarget* renderTarget) { |
373 if (NULL == renderTarget) { | 369 SkASSERT(renderTarget); |
374 renderTarget = this->drawState()->getRenderTarget(); | |
375 SkASSERT(renderTarget); | |
376 } | |
377 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); | 370 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); |
378 clr->fRect = rect; | 371 clr->fRect = rect; |
379 clr->fInsideClip = insideClip; | 372 clr->fInsideClip = insideClip; |
380 this->recordTraceMarkersIfNecessary(); | 373 this->recordTraceMarkersIfNecessary(); |
381 } | 374 } |
382 | 375 |
383 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | 376 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { |
384 SkASSERT(renderTarget); | 377 SkASSERT(renderTarget); |
385 if (!this->caps()->discardRenderTargetSupport()) { | 378 if (!this->caps()->discardRenderTargetSupport()) { |
386 return; | 379 return; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 GrGpuTraceMarker newMarker("", -1); | 428 GrGpuTraceMarker newMarker("", -1); |
436 SkString traceString; | 429 SkString traceString; |
437 if (cmd_has_trace_marker(iter->fType)) { | 430 if (cmd_has_trace_marker(iter->fType)) { |
438 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 431 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
439 newMarker.fMarker = traceString.c_str(); | 432 newMarker.fMarker = traceString.c_str(); |
440 fDstGpu->addGpuTraceMarker(&newMarker); | 433 fDstGpu->addGpuTraceMarker(&newMarker); |
441 ++currCmdMarker; | 434 ++currCmdMarker; |
442 } | 435 } |
443 | 436 |
444 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { | 437 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
445 const SetState* ss = reinterpret_cast<const SetState*>(iter.get()); | 438 SetState* ss = reinterpret_cast<SetState*>(iter.get()); |
446 currentOptState.reset(GrOptDrawState::Create(ss->fState, | 439 currentOptState.reset(GrOptDrawState::Create(fDstGpu, |
447 fDstGpu, | 440 ss->fState, |
448 &ss->fDstCopy, | 441 &ss->fDstCopy, |
449 ss->fDrawType)); | 442 ss->fDrawType)); |
450 } else { | 443 } else { |
451 iter->execute(fDstGpu, currentOptState.get()); | 444 iter->execute(fDstGpu, currentOptState.get()); |
452 } | 445 } |
453 | 446 |
454 if (cmd_has_trace_marker(iter->fType)) { | 447 if (cmd_has_trace_marker(iter->fType)) { |
455 fDstGpu->removeGpuTraceMarker(&newMarker); | 448 fDstGpu->removeGpuTraceMarker(&newMarker); |
456 } | 449 } |
457 } | 450 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 this->recordTraceMarkersIfNecessary(); | 521 this->recordTraceMarkersIfNecessary(); |
529 return true; | 522 return true; |
530 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { | 523 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { |
531 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint); | 524 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint); |
532 return true; | 525 return true; |
533 } else { | 526 } else { |
534 return false; | 527 return false; |
535 } | 528 } |
536 } | 529 } |
537 | 530 |
538 bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst, | 531 bool GrInOrderDrawBuffer::canCopySurface(const GrSurface* dst, |
539 GrSurface* src, | 532 const GrSurface* src, |
540 const SkIRect& srcRect, | 533 const SkIRect& srcRect, |
541 const SkIPoint& dstPoint) { | 534 const SkIPoint& dstPoint) { |
542 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) || | 535 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) || |
543 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint); | 536 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint); |
544 } | 537 } |
545 | 538 |
546 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface
Desc* desc) { | 539 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface
Desc* desc) { |
547 fDstGpu->initCopySurfaceDstDesc(src, desc); | 540 fDstGpu->initCopySurfaceDstDesc(src, desc); |
548 } | 541 } |
549 | 542 |
550 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, | 543 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, |
| 544 size_t vertexStride, |
551 int indexCount) { | 545 int indexCount) { |
552 // We use geometryHints() to know whether to flush the draw buffer. We | 546 // We use geometryHints() to know whether to flush the draw buffer. We |
553 // can't flush if we are inside an unbalanced pushGeometrySource. | 547 // can't flush if we are inside an unbalanced pushGeometrySource. |
554 // Moreover, flushing blows away vertex and index data that was | 548 // Moreover, flushing blows away vertex and index data that was |
555 // previously reserved. So if the vertex or index data is pulled from | 549 // previously reserved. So if the vertex or index data is pulled from |
556 // reserved space and won't be released by this request then we can't | 550 // reserved space and won't be released by this request then we can't |
557 // flush. | 551 // flush. |
558 bool insideGeoPush = fGeoPoolStateStack.count() > 1; | 552 bool insideGeoPush = fGeoPoolStateStack.count() > 1; |
559 | 553 |
560 bool unreleasedVertexSpace = | 554 bool unreleasedVertexSpace = |
561 !vertexCount && | 555 !vertexCount && |
562 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; | 556 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; |
563 | 557 |
564 bool unreleasedIndexSpace = | 558 bool unreleasedIndexSpace = |
565 !indexCount && | 559 !indexCount && |
566 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; | 560 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; |
567 | 561 |
568 int vcount = vertexCount; | 562 int vcount = vertexCount; |
569 int icount = indexCount; | 563 int icount = indexCount; |
570 | 564 |
571 if (!insideGeoPush && | 565 if (!insideGeoPush && |
572 !unreleasedVertexSpace && | 566 !unreleasedVertexSpace && |
573 !unreleasedIndexSpace && | 567 !unreleasedIndexSpace && |
574 this->geometryHints(&vcount, &icount)) { | 568 this->geometryHints(vertexStride, &vcount, &icount)) { |
575 this->flush(); | 569 this->flush(); |
576 } | 570 } |
577 } | 571 } |
578 | 572 |
579 bool GrInOrderDrawBuffer::geometryHints(int* vertexCount, | 573 bool GrInOrderDrawBuffer::geometryHints(size_t vertexStride, |
| 574 int* vertexCount, |
580 int* indexCount) const { | 575 int* indexCount) const { |
581 // we will recommend a flush if the data could fit in a single | 576 // we will recommend a flush if the data could fit in a single |
582 // preallocated buffer but none are left and it can't fit | 577 // preallocated buffer but none are left and it can't fit |
583 // in the current buffer (which may not be prealloced). | 578 // in the current buffer (which may not be prealloced). |
584 bool flush = false; | 579 bool flush = false; |
585 if (indexCount) { | 580 if (indexCount) { |
586 int32_t currIndices = fIndexPool.currentBufferIndices(); | 581 int32_t currIndices = fIndexPool.currentBufferIndices(); |
587 if (*indexCount > currIndices && | 582 if (*indexCount > currIndices && |
588 (!fIndexPool.preallocatedBuffersRemaining() && | 583 (!fIndexPool.preallocatedBuffersRemaining() && |
589 *indexCount <= fIndexPool.preallocatedBufferIndices())) { | 584 *indexCount <= fIndexPool.preallocatedBufferIndices())) { |
590 | 585 |
591 flush = true; | 586 flush = true; |
592 } | 587 } |
593 *indexCount = currIndices; | 588 *indexCount = currIndices; |
594 } | 589 } |
595 if (vertexCount) { | 590 if (vertexCount) { |
596 size_t vertexStride = this->getDrawState().getVertexStride(); | |
597 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride); | 591 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride); |
598 if (*vertexCount > currVertices && | 592 if (*vertexCount > currVertices && |
599 (!fVertexPool.preallocatedBuffersRemaining() && | 593 (!fVertexPool.preallocatedBuffersRemaining() && |
600 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride
))) { | 594 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride
))) { |
601 | 595 |
602 flush = true; | 596 flush = true; |
603 } | 597 } |
604 *vertexCount = currVertices; | 598 *vertexCount = currVertices; |
605 } | 599 } |
606 return flush; | 600 return flush; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // is now unreleasable because data may have been appended later in the | 683 // is now unreleasable because data may have been appended later in the |
690 // pool. | 684 // pool. |
691 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { | 685 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { |
692 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 686 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
693 } | 687 } |
694 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { | 688 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { |
695 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; | 689 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; |
696 } | 690 } |
697 } | 691 } |
698 | 692 |
699 void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType, | 693 void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds, |
| 694 GrGpu::DrawType drawType, |
700 const GrDeviceCoordTexture* dst
Copy) { | 695 const GrDeviceCoordTexture* dst
Copy) { |
701 if (!fLastState) { | 696 if (!fLastState) { |
702 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get
DrawState())); | 697 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); |
703 fLastState = &ss->fState; | 698 fLastState = &ss->fState; |
704 if (dstCopy) { | 699 if (dstCopy) { |
705 ss->fDstCopy = *dstCopy; | 700 ss->fDstCopy = *dstCopy; |
706 } | 701 } |
707 ss->fDrawType = drawType; | 702 ss->fDrawType = drawType; |
708 this->convertDrawStateToPendingExec(fLastState); | 703 this->convertDrawStateToPendingExec(fLastState); |
709 this->recordTraceMarkersIfNecessary(); | 704 this->recordTraceMarkersIfNecessary(); |
710 return; | 705 return; |
711 } | 706 } |
712 const GrDrawState& curr = this->getDrawState(); | 707 switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) { |
713 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { | |
714 case GrDrawState::kIncompatible_CombinedState: { | 708 case GrDrawState::kIncompatible_CombinedState: { |
715 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr)
); | 709 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); |
716 fLastState = &ss->fState; | 710 fLastState = &ss->fState; |
717 if (dstCopy) { | 711 if (dstCopy) { |
718 ss->fDstCopy = *dstCopy; | 712 ss->fDstCopy = *dstCopy; |
719 } | 713 } |
720 ss->fDrawType = drawType; | 714 ss->fDrawType = drawType; |
721 this->convertDrawStateToPendingExec(fLastState); | 715 this->convertDrawStateToPendingExec(fLastState); |
722 this->recordTraceMarkersIfNecessary(); | 716 this->recordTraceMarkersIfNecessary(); |
723 break; | 717 break; |
724 } | 718 } |
725 case GrDrawState::kA_CombinedState: | 719 case GrDrawState::kA_CombinedState: |
726 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | 720 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
727 break; | 721 break; |
728 case GrDrawState::kB_CombinedState: | 722 case GrDrawState::kB_CombinedState: |
729 // prev has already been converted to pending execution. That is a o
ne-way ticket. | 723 // prev has already been converted to pending execution. That is a o
ne-way ticket. |
730 // So here we just destruct the previous state and reinit with a new
copy of curr. | 724 // So here we just destruct the previous state and reinit with a new
copy of curr. |
731 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots | 725 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots |
732 // of draw states. | 726 // of draw states. |
733 fLastState->~GrDrawState(); | 727 fLastState->~GrDrawState(); |
734 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); | 728 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds)); |
735 this->convertDrawStateToPendingExec(fLastState); | 729 this->convertDrawStateToPendingExec(fLastState); |
736 break; | 730 break; |
737 } | 731 } |
738 } | 732 } |
739 | 733 |
740 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 734 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
741 SkASSERT(!fCmdBuffer.empty()); | 735 SkASSERT(!fCmdBuffer.empty()); |
742 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 736 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
743 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 737 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
744 if (activeTraceMarkers.count() > 0) { | 738 if (activeTraceMarkers.count() > 0) { |
745 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 739 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
746 fGpuCmdMarkers.push_back(activeTraceMarkers); | 740 fGpuCmdMarkers.push_back(activeTraceMarkers); |
747 } | 741 } |
748 } | 742 } |
OLD | NEW |