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" |
11 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
12 #include "GrTextStrike.h" | 12 #include "GrTextStrike.h" |
13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
14 #include "GrTemplates.h" | 14 #include "GrTemplates.h" |
15 #include "GrTexture.h" | 15 #include "GrTexture.h" |
16 | 16 |
17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, | 17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
18 GrVertexBufferAllocPool* vertexPool, | 18 GrVertexBufferAllocPool* vertexPool, |
19 GrIndexBufferAllocPool* indexPool) | 19 GrIndexBufferAllocPool* indexPool) |
20 : GrDrawTarget(gpu->getContext()) | 20 : GrDrawTarget(gpu->getContext()) |
21 , fCmdBuffer(kCmdBufferInitialSizeInBytes) | |
22 , fLastState(NULL) | |
23 , fLastClip(NULL) | |
24 , fDstGpu(gpu) | 21 , fDstGpu(gpu) |
25 , fClipSet(true) | 22 , fClipSet(true) |
26 , fClipProxyState(kUnknown_ClipProxyState) | 23 , fClipProxyState(kUnknown_ClipProxyState) |
27 , fVertexPool(*vertexPool) | 24 , fVertexPool(*vertexPool) |
28 , fIndexPool(*indexPool) | 25 , fIndexPool(*indexPool) |
29 , fFlushing(false) | 26 , fFlushing(false) |
30 , fDrawID(0) { | 27 , fDrawID(0) { |
31 | 28 |
32 fDstGpu->ref(); | 29 fDstGpu->ref(); |
33 fCaps.reset(SkRef(fDstGpu->caps())); | 30 fCaps.reset(SkRef(fDstGpu->caps())); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 return fClipProxy.contains(devBounds); | 209 return fClipProxy.contains(devBounds); |
213 } | 210 } |
214 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), | 211 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), |
215 SkIntToScalar(this->getClip()->fOrigin.fY)}; | 212 SkIntToScalar(this->getClip()->fOrigin.fY)}; |
216 SkRect clipSpaceBounds = devBounds; | 213 SkRect clipSpaceBounds = devBounds; |
217 clipSpaceBounds.offset(originOffset); | 214 clipSpaceBounds.offset(originOffset); |
218 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); | 215 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); |
219 } | 216 } |
220 | 217 |
221 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { | 218 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { |
222 SkASSERT(!fCmdBuffer.empty()); | |
223 SkASSERT(info.isInstanced()); | 219 SkASSERT(info.isInstanced()); |
224 | 220 |
225 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 221 const GeometrySrcState& geomSrc = this->getGeomSrc(); |
226 const GrDrawState& drawState = this->getDrawState(); | 222 const GrDrawState& drawState = this->getDrawState(); |
227 | 223 |
228 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | 224 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index |
229 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | 225 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated |
230 // between draws. | 226 // between draws. |
231 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | 227 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || |
232 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | 228 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { |
233 return 0; | 229 return 0; |
234 } | 230 } |
235 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 231 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
236 // the same IB | 232 // the same IB |
237 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) { | 233 if (kDraw_Cmd != strip_trace_bit(fCmds.back())) { |
238 return 0; | 234 return 0; |
239 } | 235 } |
240 | 236 |
241 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); | 237 Draw* draw = &fDraws.back(); |
242 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
243 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; | 239 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; |
244 | 240 |
245 if (!draw->fInfo.isInstanced() || | 241 if (!draw->isInstanced() || |
246 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || | 242 draw->verticesPerInstance() != info.verticesPerInstance() || |
247 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || | 243 draw->indicesPerInstance() != info.indicesPerInstance() || |
248 draw->vertexBuffer() != vertexBuffer || | 244 draw->vertexBuffer() != vertexBuffer || |
249 draw->indexBuffer() != geomSrc.fIndexBuffer) { | 245 draw->indexBuffer() != geomSrc.fIndexBuffer) { |
250 return 0; | 246 return 0; |
251 } | 247 } |
252 // info does not yet account for the offset from the start of the pool's VB
while the previous | 248 // info does not yet account for the offset from the start of the pool's VB
while the previous |
253 // draw record does. | 249 // draw record does. |
254 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); | 250 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); |
255 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVe
rtex) { | 251 if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) { |
256 return 0; | 252 return 0; |
257 } | 253 } |
258 | 254 |
259 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); | 255 SkASSERT(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCou
nt()); |
260 | 256 |
261 // how many instances can be concat'ed onto draw given the size of the index
buffer | 257 // how many instances can be concat'ed onto draw given the size of the index
buffer |
262 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); | 258 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); |
263 instancesToConcat -= draw->fInfo.instanceCount(); | 259 instancesToConcat -= draw->instanceCount(); |
264 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 260 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
265 | 261 |
266 // update the amount of reserved vertex data actually referenced in draws | 262 // update the amount of reserved vertex data actually referenced in draws |
267 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * | 263 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * |
268 drawState.getVertexStride(); | 264 drawState.getVertexStride(); |
269 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); | 265 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); |
270 | 266 |
271 draw->fInfo.adjustInstanceCount(instancesToConcat); | 267 draw->adjustInstanceCount(instancesToConcat); |
272 | 268 |
273 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 269 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
274 if (this->getActiveTraceMarkers().count() > 0) { | 270 if (this->getActiveTraceMarkers().count() > 0) { |
275 if (cmd_has_trace_marker(draw->fType)) { | 271 if (cmd_has_trace_marker(fCmds.back())) { |
276 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); | 272 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); |
277 } else { | 273 } else { |
278 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); | 274 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); |
279 draw->fType = add_trace_bit(draw->fType); | 275 fCmds.back() = add_trace_bit(fCmds.back()); |
280 } | 276 } |
281 } | 277 } |
282 | 278 |
283 return instancesToConcat; | 279 return instancesToConcat; |
284 } | 280 } |
285 | 281 |
286 class AutoClipReenable { | 282 class AutoClipReenable { |
287 public: | 283 public: |
288 AutoClipReenable() : fDrawState(NULL) {} | 284 AutoClipReenable() : fDrawState(NULL) {} |
289 ~AutoClipReenable() { | 285 ~AutoClipReenable() { |
(...skipping 16 matching lines...) Expand all Loading... |
306 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 302 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
307 const GrDrawState& drawState = this->getDrawState(); | 303 const GrDrawState& drawState = this->getDrawState(); |
308 AutoClipReenable acr; | 304 AutoClipReenable acr; |
309 | 305 |
310 if (drawState.isClipState() && | 306 if (drawState.isClipState() && |
311 info.getDevBounds() && | 307 info.getDevBounds() && |
312 this->quickInsideClip(*info.getDevBounds())) { | 308 this->quickInsideClip(*info.getDevBounds())) { |
313 acr.set(this->drawState()); | 309 acr.set(this->drawState()); |
314 } | 310 } |
315 | 311 |
316 this->recordClipIfNecessary(); | 312 if (this->needsNewClip()) { |
| 313 this->recordClip(); |
| 314 } |
317 this->recordStateIfNecessary(); | 315 this->recordStateIfNecessary(); |
318 | 316 |
319 const GrVertexBuffer* vb; | 317 const GrVertexBuffer* vb; |
320 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 318 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
321 vb = this->getGeomSrc().fVertexBuffer; | 319 vb = this->getGeomSrc().fVertexBuffer; |
322 } else { | 320 } else { |
323 vb = poolState.fPoolVertexBuffer; | 321 vb = poolState.fPoolVertexBuffer; |
324 } | 322 } |
325 | 323 |
326 const GrIndexBuffer* ib = NULL; | 324 const GrIndexBuffer* ib = NULL; |
327 if (info.isIndexed()) { | 325 if (info.isIndexed()) { |
328 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 326 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { |
329 ib = this->getGeomSrc().fIndexBuffer; | 327 ib = this->getGeomSrc().fIndexBuffer; |
330 } else { | 328 } else { |
331 ib = poolState.fPoolIndexBuffer; | 329 ib = poolState.fPoolIndexBuffer; |
332 } | 330 } |
333 } | 331 } |
334 | 332 |
335 Draw* draw; | 333 Draw* draw; |
336 if (info.isInstanced()) { | 334 if (info.isInstanced()) { |
337 int instancesConcated = this->concatInstancedDraw(info); | 335 int instancesConcated = this->concatInstancedDraw(info); |
338 if (info.instanceCount() > instancesConcated) { | 336 if (info.instanceCount() > instancesConcated) { |
339 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib)); | 337 draw = this->recordDraw(info, vb, ib); |
340 draw->fInfo.adjustInstanceCount(-instancesConcated); | 338 draw->adjustInstanceCount(-instancesConcated); |
341 } else { | 339 } else { |
342 return; | 340 return; |
343 } | 341 } |
344 } else { | 342 } else { |
345 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib)); | 343 draw = this->recordDraw(info, vb, ib); |
346 } | 344 } |
347 this->recordTraceMarkersIfNecessary(); | |
348 | 345 |
349 // Adjust the starting vertex and index when we are using reserved or array
sources to | 346 // Adjust the starting vertex and index when we are using reserved or array
sources to |
350 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. | 347 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. |
351 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { | 348 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { |
352 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); | 349 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); |
353 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); | 350 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); |
354 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); | 351 draw->adjustStartVertex(poolState.fPoolStartVertex); |
355 } | 352 } |
356 | 353 |
357 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { | 354 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { |
358 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); | 355 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); |
359 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 356 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
360 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); | 357 draw->adjustStartIndex(poolState.fPoolStartIndex); |
361 } | 358 } |
362 } | 359 } |
363 | 360 |
364 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { | 361 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { |
365 this->recordClipIfNecessary(); | 362 if (this->needsNewClip()) { |
| 363 this->recordClip(); |
| 364 } |
366 // Only compare the subset of GrDrawState relevant to path stenciling? | 365 // Only compare the subset of GrDrawState relevant to path stenciling? |
367 this->recordStateIfNecessary(); | 366 this->recordStateIfNecessary(); |
368 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); | 367 StencilPath* sp = this->recordStencilPath(path); |
369 sp->fFill = fill; | 368 sp->fFill = fill; |
370 this->recordTraceMarkersIfNecessary(); | |
371 } | 369 } |
372 | 370 |
373 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, | 371 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, |
374 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { | 372 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { |
375 this->recordClipIfNecessary(); | 373 if (this->needsNewClip()) { |
| 374 this->recordClip(); |
| 375 } |
376 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 376 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
377 this->recordStateIfNecessary(); | 377 this->recordStateIfNecessary(); |
378 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 378 DrawPath* cp = this->recordDrawPath(path); |
379 dp->fFill = fill; | 379 cp->fFill = fill; |
380 if (dstCopy) { | 380 if (dstCopy) { |
381 dp->fDstCopy = *dstCopy; | 381 cp->fDstCopy = *dstCopy; |
382 } | 382 } |
383 this->recordTraceMarkersIfNecessary(); | |
384 } | 383 } |
385 | 384 |
386 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, | 385 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, |
387 const uint32_t indices[], int count, | 386 const uint32_t indices[], int count, |
388 const float transforms[], PathTransformTyp
e transformsType, | 387 const float transforms[], PathTransformTyp
e transformsType, |
389 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { | 388 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { |
390 SkASSERT(pathRange); | 389 SkASSERT(pathRange); |
391 SkASSERT(indices); | 390 SkASSERT(indices); |
392 SkASSERT(transforms); | 391 SkASSERT(transforms); |
393 | 392 |
394 this->recordClipIfNecessary(); | 393 if (this->needsNewClip()) { |
| 394 this->recordClip(); |
| 395 } |
395 this->recordStateIfNecessary(); | 396 this->recordStateIfNecessary(); |
| 397 DrawPaths* dp = this->recordDrawPaths(pathRange); |
| 398 dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this withou
t a malloc |
| 399 memcpy(dp->fIndices, indices, sizeof(uint32_t) * count); |
| 400 dp->fCount = count; |
396 | 401 |
397 int sizeOfIndices = sizeof(uint32_t) * count; | 402 const int transformsLength = GrPathRendering::PathTransformSize(transformsTy
pe) * count; |
398 int sizeOfTransforms = sizeof(float) * count * | 403 dp->fTransforms = SkNEW_ARRAY(float, transformsLength); |
399 GrPathRendering::PathTransformSize(transformsType); | 404 memcpy(dp->fTransforms, transforms, sizeof(float) * transformsLength); |
| 405 dp->fTransformsType = transformsType; |
400 | 406 |
401 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), | |
402 sizeOfIndices + sizeOfTra
nsforms); | |
403 memcpy(dp->indices(), indices, sizeOfIndices); | |
404 dp->fCount = count; | |
405 memcpy(dp->transforms(), transforms, sizeOfTransforms); | |
406 dp->fTransformsType = transformsType; | |
407 dp->fFill = fill; | 407 dp->fFill = fill; |
| 408 |
408 if (dstCopy) { | 409 if (dstCopy) { |
409 dp->fDstCopy = *dstCopy; | 410 dp->fDstCopy = *dstCopy; |
410 } | 411 } |
411 | |
412 this->recordTraceMarkersIfNecessary(); | |
413 } | 412 } |
414 | 413 |
415 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, | 414 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, |
416 bool canIgnoreRect, GrRenderTarget* renderTarget
) { | 415 bool canIgnoreRect, GrRenderTarget* renderTarget
) { |
417 SkIRect r; | 416 SkIRect r; |
418 if (NULL == renderTarget) { | 417 if (NULL == renderTarget) { |
419 renderTarget = this->drawState()->getRenderTarget(); | 418 renderTarget = this->drawState()->getRenderTarget(); |
420 SkASSERT(renderTarget); | 419 SkASSERT(renderTarget); |
421 } | 420 } |
422 if (NULL == rect) { | 421 if (NULL == rect) { |
423 // We could do something smart and remove previous draws and clears to | 422 // We could do something smart and remove previous draws and clears to |
424 // the current render target. If we get that smart we have to make sure | 423 // the current render target. If we get that smart we have to make sure |
425 // those draws aren't read before this clear (render-to-texture). | 424 // those draws aren't read before this clear (render-to-texture). |
426 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 425 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
427 rect = &r; | 426 rect = &r; |
428 } | 427 } |
429 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 428 Clear* clr = this->recordClear(renderTarget); |
430 GrColorIsPMAssert(color); | 429 GrColorIsPMAssert(color); |
431 clr->fColor = color; | 430 clr->fColor = color; |
432 clr->fRect = *rect; | 431 clr->fRect = *rect; |
433 clr->fCanIgnoreRect = canIgnoreRect; | 432 clr->fCanIgnoreRect = canIgnoreRect; |
434 this->recordTraceMarkersIfNecessary(); | |
435 } | 433 } |
436 | 434 |
437 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | 435 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { |
438 if (!this->caps()->discardRenderTargetSupport()) { | 436 if (!this->caps()->discardRenderTargetSupport()) { |
439 return; | 437 return; |
440 } | 438 } |
441 if (NULL == renderTarget) { | 439 if (NULL == renderTarget) { |
442 renderTarget = this->drawState()->getRenderTarget(); | 440 renderTarget = this->drawState()->getRenderTarget(); |
443 SkASSERT(renderTarget); | 441 SkASSERT(renderTarget); |
444 } | 442 } |
445 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 443 Clear* clr = this->recordClear(renderTarget); |
446 clr->fColor = GrColor_ILLEGAL; | 444 clr->fColor = GrColor_ILLEGAL; |
447 this->recordTraceMarkersIfNecessary(); | |
448 } | 445 } |
449 | 446 |
450 void GrInOrderDrawBuffer::reset() { | 447 void GrInOrderDrawBuffer::reset() { |
451 SkASSERT(1 == fGeoPoolStateStack.count()); | 448 SkASSERT(1 == fGeoPoolStateStack.count()); |
452 this->resetVertexSource(); | 449 this->resetVertexSource(); |
453 this->resetIndexSource(); | 450 this->resetIndexSource(); |
454 | 451 |
455 fCmdBuffer.reset(); | 452 fCmds.reset(); |
456 fLastState = NULL; | 453 fDraws.reset(); |
457 fLastClip = NULL; | 454 fStencilPaths.reset(); |
| 455 fDrawPath.reset(); |
| 456 fDrawPaths.reset(); |
| 457 fStates.reset(); |
| 458 fClears.reset(); |
458 fVertexPool.reset(); | 459 fVertexPool.reset(); |
459 fIndexPool.reset(); | 460 fIndexPool.reset(); |
| 461 fClips.reset(); |
| 462 fCopySurfaces.reset(); |
460 fGpuCmdMarkers.reset(); | 463 fGpuCmdMarkers.reset(); |
461 fClipSet = true; | 464 fClipSet = true; |
462 } | 465 } |
463 | 466 |
464 void GrInOrderDrawBuffer::flush() { | 467 void GrInOrderDrawBuffer::flush() { |
465 if (fFlushing) { | 468 if (fFlushing) { |
466 return; | 469 return; |
467 } | 470 } |
468 | 471 |
469 this->getContext()->getFontCache()->updateTextures(); | 472 this->getContext()->getFontCache()->updateTextures(); |
470 | 473 |
471 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); | 474 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); |
472 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); | 475 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); |
473 | 476 |
474 if (fCmdBuffer.empty()) { | 477 int numCmds = fCmds.count(); |
| 478 if (0 == numCmds) { |
475 return; | 479 return; |
476 } | 480 } |
477 | 481 |
478 GrAutoTRestore<bool> flushRestore(&fFlushing); | 482 GrAutoTRestore<bool> flushRestore(&fFlushing); |
479 fFlushing = true; | 483 fFlushing = true; |
480 | 484 |
481 fVertexPool.unmap(); | 485 fVertexPool.unmap(); |
482 fIndexPool.unmap(); | 486 fIndexPool.unmap(); |
483 | 487 |
484 GrDrawTarget::AutoClipRestore acr(fDstGpu); | 488 GrDrawTarget::AutoClipRestore acr(fDstGpu); |
485 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); | 489 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); |
486 | 490 |
487 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); | 491 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); |
488 | 492 |
489 CmdBuffer::Iter iter(fCmdBuffer); | 493 GrClipData clipData; |
490 | 494 |
491 int currCmdMarker = 0; | 495 StateAllocator::Iter stateIter(&fStates); |
| 496 ClipAllocator::Iter clipIter(&fClips); |
| 497 ClearAllocator::Iter clearIter(&fClears); |
| 498 DrawAllocator::Iter drawIter(&fDraws); |
| 499 StencilPathAllocator::Iter stencilPathIter(&fStencilPaths); |
| 500 DrawPathAllocator::Iter drawPathIter(&fDrawPath); |
| 501 DrawPathsAllocator::Iter drawPathsIter(&fDrawPaths); |
| 502 CopySurfaceAllocator::Iter copySurfaceIter(&fCopySurfaces); |
| 503 |
| 504 int currCmdMarker = 0; |
| 505 |
492 fDstGpu->saveActiveTraceMarkers(); | 506 fDstGpu->saveActiveTraceMarkers(); |
493 | 507 for (int c = 0; c < numCmds; ++c) { |
494 while (iter.next()) { | |
495 GrGpuTraceMarker newMarker("", -1); | 508 GrGpuTraceMarker newMarker("", -1); |
496 SkString traceString; | 509 SkString traceString; |
497 if (cmd_has_trace_marker(iter->fType)) { | 510 if (cmd_has_trace_marker(fCmds[c])) { |
498 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 511 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
499 newMarker.fMarker = traceString.c_str(); | 512 newMarker.fMarker = traceString.c_str(); |
500 fDstGpu->addGpuTraceMarker(&newMarker); | 513 fDstGpu->addGpuTraceMarker(&newMarker); |
501 ++currCmdMarker; | 514 ++currCmdMarker; |
502 } | 515 } |
503 | 516 switch (strip_trace_bit(fCmds[c])) { |
504 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || | 517 case kDraw_Cmd: { |
505 kStencilPath_Cmd == strip_trace_bit(iter->fTyp
e) || | 518 SkASSERT(fDstGpu->drawState() != prevDrawState); |
506 kDrawPath_Cmd == strip_trace_bit(iter->fType)
|| | 519 SkAssertResult(drawIter.next()); |
507 kDrawPaths_Cmd == strip_trace_bit(iter->fType)
); | 520 fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer()); |
508 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); | 521 if (drawIter->isIndexed()) { |
509 | 522 fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer()); |
510 iter->execute(fDstGpu); | 523 } |
511 | 524 fDstGpu->executeDraw(*drawIter); |
512 if (cmd_has_trace_marker(iter->fType)) { | 525 break; |
| 526 } |
| 527 case kStencilPath_Cmd: { |
| 528 SkASSERT(fDstGpu->drawState() != prevDrawState); |
| 529 SkAssertResult(stencilPathIter.next()); |
| 530 fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->f
Fill); |
| 531 break; |
| 532 } |
| 533 case kDrawPath_Cmd: { |
| 534 SkASSERT(fDstGpu->drawState() != prevDrawState); |
| 535 SkAssertResult(drawPathIter.next()); |
| 536 fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFi
ll, |
| 537 drawPathIter->fDstCopy.texture() ? |
| 538 &drawPathIter->fDstCopy : |
| 539 NULL); |
| 540 break; |
| 541 } |
| 542 case kDrawPaths_Cmd: { |
| 543 SkASSERT(fDstGpu->drawState() != prevDrawState); |
| 544 SkAssertResult(drawPathsIter.next()); |
| 545 const GrDeviceCoordTexture* dstCopy = |
| 546 drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy
: NULL; |
| 547 fDstGpu->executeDrawPaths(drawPathsIter->pathRange(), |
| 548 drawPathsIter->fIndices, |
| 549 drawPathsIter->fCount, |
| 550 drawPathsIter->fTransforms, |
| 551 drawPathsIter->fTransformsType, |
| 552 drawPathsIter->fFill, |
| 553 dstCopy); |
| 554 break; |
| 555 } |
| 556 case kSetState_Cmd: |
| 557 SkAssertResult(stateIter.next()); |
| 558 fDstGpu->setDrawState(stateIter.get()); |
| 559 break; |
| 560 case kSetClip_Cmd: |
| 561 SkAssertResult(clipIter.next()); |
| 562 clipData.fClipStack = &clipIter->fStack; |
| 563 clipData.fOrigin = clipIter->fOrigin; |
| 564 fDstGpu->setClip(&clipData); |
| 565 break; |
| 566 case kClear_Cmd: |
| 567 SkAssertResult(clearIter.next()); |
| 568 if (GrColor_ILLEGAL == clearIter->fColor) { |
| 569 fDstGpu->discard(clearIter->renderTarget()); |
| 570 } else { |
| 571 fDstGpu->clear(&clearIter->fRect, |
| 572 clearIter->fColor, |
| 573 clearIter->fCanIgnoreRect, |
| 574 clearIter->renderTarget()); |
| 575 } |
| 576 break; |
| 577 case kCopySurface_Cmd: |
| 578 SkAssertResult(copySurfaceIter.next()); |
| 579 fDstGpu->copySurface(copySurfaceIter->dst(), |
| 580 copySurfaceIter->src(), |
| 581 copySurfaceIter->fSrcRect, |
| 582 copySurfaceIter->fDstPoint); |
| 583 break; |
| 584 } |
| 585 if (cmd_has_trace_marker(fCmds[c])) { |
513 fDstGpu->removeGpuTraceMarker(&newMarker); | 586 fDstGpu->removeGpuTraceMarker(&newMarker); |
514 } | 587 } |
515 } | 588 } |
| 589 fDstGpu->restoreActiveTraceMarkers(); |
| 590 // we should have consumed all the states, clips, etc. |
| 591 SkASSERT(!stateIter.next()); |
| 592 SkASSERT(!clipIter.next()); |
| 593 SkASSERT(!clearIter.next()); |
| 594 SkASSERT(!drawIter.next()); |
| 595 SkASSERT(!copySurfaceIter.next()); |
| 596 SkASSERT(!stencilPathIter.next()); |
| 597 SkASSERT(!drawPathIter.next()); |
| 598 SkASSERT(!drawPathsIter.next()); |
516 | 599 |
517 fDstGpu->restoreActiveTraceMarkers(); | |
518 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 600 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
519 | 601 |
520 fDstGpu->setDrawState(prevDrawState); | 602 fDstGpu->setDrawState(prevDrawState); |
521 prevDrawState->unref(); | 603 prevDrawState->unref(); |
522 this->reset(); | 604 this->reset(); |
523 ++fDrawID; | 605 ++fDrawID; |
524 } | 606 } |
525 | 607 |
526 void GrInOrderDrawBuffer::Draw::execute(GrDrawTarget* gpu) { | |
527 gpu->setVertexSourceToBuffer(this->vertexBuffer()); | |
528 if (fInfo.isIndexed()) { | |
529 gpu->setIndexSourceToBuffer(this->indexBuffer()); | |
530 } | |
531 gpu->executeDraw(fInfo); | |
532 } | |
533 | |
534 void GrInOrderDrawBuffer::StencilPath::execute(GrDrawTarget* gpu) { | |
535 gpu->stencilPath(this->path(), fFill); | |
536 } | |
537 | |
538 void GrInOrderDrawBuffer::DrawPath::execute(GrDrawTarget* gpu) { | |
539 gpu->executeDrawPath(this->path(), fFill, fDstCopy.texture() ? &fDstCopy : N
ULL); | |
540 } | |
541 | |
542 void GrInOrderDrawBuffer::DrawPaths::execute(GrDrawTarget* gpu) { | |
543 gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->tran
sforms(), | |
544 fTransformsType, fFill, fDstCopy.texture() ? &fDstCopy
: NULL); | |
545 } | |
546 | |
547 void GrInOrderDrawBuffer::SetState::execute(GrDrawTarget* gpu) { | |
548 gpu->setDrawState(&fState); | |
549 } | |
550 | |
551 void GrInOrderDrawBuffer::SetClip::execute(GrDrawTarget* gpu) { | |
552 // Our fClipData is referenced directly, so we must remain alive for the ent
ire | |
553 // duration of the flush (after which the gpu's previous clip is restored). | |
554 gpu->setClip(&fClipData); | |
555 } | |
556 | |
557 void GrInOrderDrawBuffer::Clear::execute(GrDrawTarget* gpu) { | |
558 if (GrColor_ILLEGAL == fColor) { | |
559 gpu->discard(this->renderTarget()); | |
560 } else { | |
561 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); | |
562 } | |
563 } | |
564 | |
565 void GrInOrderDrawBuffer::CopySurface::execute(GrDrawTarget* gpu) { | |
566 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); | |
567 } | |
568 | |
569 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, | 608 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, |
570 GrSurface* src, | 609 GrSurface* src, |
571 const SkIRect& srcRect, | 610 const SkIRect& srcRect, |
572 const SkIPoint& dstPoint) { | 611 const SkIPoint& dstPoint) { |
573 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { | 612 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { |
574 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst
, src)); | 613 CopySurface* cs = this->recordCopySurface(dst, src); |
575 cs->fSrcRect = srcRect; | 614 cs->fSrcRect = srcRect; |
576 cs->fDstPoint = dstPoint; | 615 cs->fDstPoint = dstPoint; |
577 this->recordTraceMarkersIfNecessary(); | |
578 return true; | 616 return true; |
579 } else { | 617 } else { |
580 return false; | 618 return false; |
581 } | 619 } |
582 } | 620 } |
583 | 621 |
584 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, | 622 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, |
585 GrSurface* src, | 623 GrSurface* src, |
586 const SkIRect& srcRect, | 624 const SkIRect& srcRect, |
587 const SkIPoint& dstPoint) { | 625 const SkIPoint& dstPoint) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 825 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
788 } | 826 } |
789 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || | 827 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || |
790 kArray_GeometrySrcType == restoredState.fIndexSrc) { | 828 kArray_GeometrySrcType == restoredState.fIndexSrc) { |
791 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * | 829 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * |
792 restoredState.fIndexCount; | 830 restoredState.fIndexCount; |
793 } | 831 } |
794 } | 832 } |
795 | 833 |
796 void GrInOrderDrawBuffer::recordStateIfNecessary() { | 834 void GrInOrderDrawBuffer::recordStateIfNecessary() { |
797 if (!fLastState) { | 835 if (fStates.empty()) { |
798 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get
DrawState())); | 836 this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawStat
e())); |
799 fLastState = &ss->fState; | 837 this->addToCmdBuffer(kSetState_Cmd); |
800 this->convertDrawStateToPendingExec(fLastState); | |
801 this->recordTraceMarkersIfNecessary(); | |
802 return; | 838 return; |
803 } | 839 } |
804 const GrDrawState& curr = this->getDrawState(); | 840 const GrDrawState& curr = this->getDrawState(); |
805 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { | 841 GrDrawState& prev = fStates.back(); |
| 842 switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) { |
806 case GrDrawState::kIncompatible_CombinedState: | 843 case GrDrawState::kIncompatible_CombinedState: |
807 fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))
->fState; | 844 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); |
808 this->convertDrawStateToPendingExec(fLastState); | 845 this->addToCmdBuffer(kSetState_Cmd); |
809 this->recordTraceMarkersIfNecessary(); | |
810 break; | 846 break; |
811 case GrDrawState::kA_CombinedState: | 847 case GrDrawState::kA_CombinedState: |
812 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | 848 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
813 break; | 849 break; |
814 case GrDrawState::kB_CombinedState: | 850 case GrDrawState::kB_CombinedState: |
815 // prev has already been converted to pending execution. That is a o
ne-way ticket. | 851 // prev has already been converted to pending execution. That is a o
ne-way ticket. |
816 // So here we just destruct the previous state and reinit with a new
copy of curr. | 852 // So here we just delete prev and push back a new copy of curr. Not
e that this |
817 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots | 853 // goes away when we move GrIODB over to taking optimized snapshots
of draw states. |
818 // of draw states. | 854 fStates.pop_back(); |
819 fLastState->~GrDrawState(); | 855 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); |
820 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); | |
821 this->convertDrawStateToPendingExec(fLastState); | |
822 break; | 856 break; |
823 } | 857 } |
824 } | 858 } |
825 | 859 |
826 void GrInOrderDrawBuffer::recordClipIfNecessary() { | 860 bool GrInOrderDrawBuffer::needsNewClip() const { |
827 if (this->getDrawState().isClipState() && | 861 if (this->getDrawState().isClipState()) { |
828 fClipSet && | 862 if (fClipSet && |
829 (!fLastClip || *fLastClip != *this->getClip())) { | 863 (fClips.empty() || |
830 fLastClip = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetClip, (this->getCli
p()))->fClipData; | 864 fClips.back().fStack != *this->getClip()->fClipStack || |
831 this->recordTraceMarkersIfNecessary(); | 865 fClips.back().fOrigin != this->getClip()->fOrigin)) { |
832 fClipSet = false; | 866 return true; |
| 867 } |
| 868 } |
| 869 return false; |
| 870 } |
| 871 |
| 872 void GrInOrderDrawBuffer::addToCmdBuffer(uint8_t cmd) { |
| 873 SkASSERT(!cmd_has_trace_marker(cmd)); |
| 874 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
| 875 if (activeTraceMarkers.count() > 0) { |
| 876 fCmds.push_back(add_trace_bit(cmd)); |
| 877 fGpuCmdMarkers.push_back(activeTraceMarkers); |
| 878 } else { |
| 879 fCmds.push_back(cmd); |
833 } | 880 } |
834 } | 881 } |
835 | 882 |
836 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 883 void GrInOrderDrawBuffer::recordClip() { |
837 SkASSERT(!fCmdBuffer.empty()); | 884 fClips.push_back().fStack = *this->getClip()->fClipStack; |
838 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 885 fClips.back().fOrigin = this->getClip()->fOrigin; |
839 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 886 fClipSet = false; |
840 if (activeTraceMarkers.count() > 0) { | 887 this->addToCmdBuffer(kSetClip_Cmd); |
841 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 888 } |
842 fGpuCmdMarkers.push_back(activeTraceMarkers); | 889 |
843 } | 890 GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info, |
| 891 const GrVertexBuffer*
vb, |
| 892 const GrIndexBuffer*
ib) { |
| 893 this->addToCmdBuffer(kDraw_Cmd); |
| 894 return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib)); |
| 895 } |
| 896 |
| 897 GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const G
rPath* path) { |
| 898 this->addToCmdBuffer(kStencilPath_Cmd); |
| 899 return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path)); |
| 900 } |
| 901 |
| 902 GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath*
path) { |
| 903 this->addToCmdBuffer(kDrawPath_Cmd); |
| 904 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path)); |
| 905 } |
| 906 |
| 907 GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPat
hRange* pathRange) { |
| 908 this->addToCmdBuffer(kDrawPaths_Cmd); |
| 909 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange)); |
| 910 } |
| 911 |
| 912 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt)
{ |
| 913 this->addToCmdBuffer(kClear_Cmd); |
| 914 return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt)); |
| 915 } |
| 916 |
| 917 GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurfa
ce* dst, |
| 918 GrSurfa
ce* src) { |
| 919 this->addToCmdBuffer(kCopySurface_Cmd); |
| 920 return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src)); |
844 } | 921 } |
845 | 922 |
846 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { | 923 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { |
847 INHERITED::clipWillBeSet(newClipData); | 924 INHERITED::clipWillBeSet(newClipData); |
848 fClipSet = true; | 925 fClipSet = true; |
849 fClipProxyState = kUnknown_ClipProxyState; | 926 fClipProxyState = kUnknown_ClipProxyState; |
850 } | 927 } |
OLD | NEW |