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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 319 |
320 SkRect bounds = rect; | 320 SkRect bounds = rect; |
321 viewMatrix.mapRect(&bounds); | 321 viewMatrix.mapRect(&bounds); |
322 this->drawBatch(pipelineBuilder, batch, &bounds); | 322 this->drawBatch(pipelineBuilder, batch, &bounds); |
323 } | 323 } |
324 | 324 |
325 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { | 325 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { |
326 SkASSERT(!fCmdBuffer.empty()); | 326 SkASSERT(!fCmdBuffer.empty()); |
327 SkASSERT(info.isInstanced()); | 327 SkASSERT(info.isInstanced()); |
328 | 328 |
329 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 329 const GrIndexBuffer* ib; |
330 | 330 if (!this->canConcatToIndexBuffer(&ib)) { |
331 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | |
332 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | |
333 // between draws. | |
334 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | |
335 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | |
336 return 0; | 331 return 0; |
337 } | 332 } |
| 333 |
338 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 334 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
339 // the same IB | 335 // the same IB |
340 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) { | 336 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) { |
341 return 0; | 337 return 0; |
342 } | 338 } |
343 | 339 |
344 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); | 340 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); |
345 | 341 |
346 if (!draw->fInfo.isInstanced() || | 342 if (!draw->fInfo.isInstanced() || |
347 draw->fInfo.primitiveType() != info.primitiveType() || | 343 draw->fInfo.primitiveType() != info.primitiveType() || |
348 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || | 344 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || |
349 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || | 345 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || |
350 draw->fInfo.vertexBuffer() != info.vertexBuffer() || | 346 draw->fInfo.vertexBuffer() != info.vertexBuffer() || |
351 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) { | 347 draw->fInfo.indexBuffer() != ib) { |
352 return 0; | 348 return 0; |
353 } | 349 } |
354 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVerte
x()) { | 350 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVerte
x()) { |
355 return 0; | 351 return 0; |
356 } | 352 } |
357 | 353 |
358 // how many instances can be concat'ed onto draw given the size of the index
buffer | 354 // how many instances can be concat'ed onto draw given the size of the index
buffer |
359 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); | 355 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); |
360 instancesToConcat -= draw->fInfo.instanceCount(); | 356 instancesToConcat -= draw->fInfo.instanceCount(); |
361 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 357 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 const PipelineInfo& pipelineInfo) { | 452 const PipelineInfo& pipelineInfo) { |
457 SkASSERT(pathRange); | 453 SkASSERT(pathRange); |
458 SkASSERT(indices); | 454 SkASSERT(indices); |
459 SkASSERT(transformValues); | 455 SkASSERT(transformValues); |
460 this->closeBatch(); | 456 this->closeBatch(); |
461 | 457 |
462 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) { | 458 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) { |
463 return; | 459 return; |
464 } | 460 } |
465 | 461 |
466 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType); | 462 char* savedIndices; |
467 char* savedIndices = (char*) fPathIndexBuffer.alloc(count * indexBytes, | 463 float* savedTransforms; |
468 SkChunkAlloc::kThrow_All
ocFailType); | |
469 SkASSERT(SkIsAlign4((uintptr_t)savedIndices)); | |
470 memcpy(savedIndices, reinterpret_cast<const char*>(indices), count * indexBy
tes); | |
471 | 464 |
472 const int xformSize = GrPathRendering::PathTransformSize(transformType); | 465 this->appendIndicesAndTransforms(indices, indexType, |
473 const int xformBytes = xformSize * sizeof(float); | 466 transformValues, transformType, |
474 float* savedTransforms = NULL; | 467 count, &savedIndices, &savedTransforms); |
475 if (0 != xformBytes) { | |
476 savedTransforms = (float*) fPathTransformBuffer.alloc(count * xformBytes
, | |
477 SkChunkAlloc::kThr
ow_AllocFailType); | |
478 SkASSERT(SkIsAlign4((uintptr_t)savedTransforms)); | |
479 memcpy(savedTransforms, transformValues, count * xformBytes); | |
480 } | |
481 | 468 |
482 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) { | 469 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) { |
483 // The previous command was also DrawPaths. Try to collapse this call in
to the one | 470 // The previous command was also DrawPaths. Try to collapse this call in
to the one |
484 // before. Note that stenciling all the paths at once, then covering, ma
y not be | 471 // before. Note that stenciling all the paths at once, then covering, ma
y not be |
485 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, | 472 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, |
486 // and the combined calls may also cancel each other's winding numbers i
n some | 473 // and the combined calls may also cancel each other's winding numbers i
n some |
487 // places. For now the winding numbers are only an issue if the fill is
even/odd, | 474 // places. For now the winding numbers are only an issue if the fill is
even/odd, |
488 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same | 475 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same |
489 // font tend to all wind in the same direction. | 476 // font tend to all wind in the same direction. |
490 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); | 477 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); |
491 if (pathRange == previous->pathRange() && | 478 if (pathRange == previous->pathRange() && |
492 indexType == previous->fIndexType && | 479 indexType == previous->fIndexType && |
493 transformType == previous->fTransformType && | 480 transformType == previous->fTransformType && |
494 stencilSettings == previous->fStencilSettings && | 481 stencilSettings == previous->fStencilSettings && |
495 path_fill_type_is_winding(stencilSettings) && | 482 path_fill_type_is_winding(stencilSettings) && |
496 !pipelineInfo.willBlendWithDst(pathProc)) { | 483 !pipelineInfo.willBlendWithDst(pathProc)) { |
| 484 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType); |
| 485 const int xformSize = GrPathRendering::PathTransformSize(transformTy
pe); |
497 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices
&& | 486 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices
&& |
498 (0 == xformBytes || | 487 (0 == xformSize || |
499 &previous->fTransforms[previous->fCount*xformSize] == savedTran
sforms)) { | 488 &previous->fTransforms[previous->fCount*xformSize] == savedTran
sforms)) { |
500 // Fold this DrawPaths call into the one previous. | 489 // Fold this DrawPaths call into the one previous. |
501 previous->fCount += count; | 490 previous->fCount += count; |
502 return; | 491 return; |
503 } | 492 } |
504 } | 493 } |
505 } | 494 } |
506 | 495 |
507 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; | 496 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; |
508 dp->fIndices = savedIndices; | 497 dp->fIndices = savedIndices; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 } | 761 } |
773 } | 762 } |
774 | 763 |
775 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, | 764 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, |
776 size_t vertexStride, | 765 size_t vertexStride, |
777 int indexCount) { | 766 int indexCount) { |
778 this->closeBatch(); | 767 this->closeBatch(); |
779 | 768 |
780 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i
ndexCount); | 769 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i
ndexCount); |
781 } | 770 } |
OLD | NEW |