Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: src/gpu/GrInOrderDrawBuffer.cpp

Issue 712223002: Combine similar DrawPaths calls in GrInOrderDrawBuffer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/gpu/GrInOrderDrawBuffer.h ('K') | « src/gpu/GrInOrderDrawBuffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 : INHERITED(gpu->getContext()) 20 : INHERITED(gpu->getContext())
21 , fCmdBuffer(kCmdBufferInitialSizeInBytes) 21 , fCmdBuffer(kCmdBufferInitialSizeInBytes)
22 , fLastState(NULL) 22 , fLastState(NULL)
23 , fDstGpu(gpu) 23 , fDstGpu(gpu)
24 , fVertexPool(*vertexPool) 24 , fVertexPool(*vertexPool)
25 , fIndexPool(*indexPool) 25 , fIndexPool(*indexPool)
26 , fPathIndexBuffer(kPathIdxBufferMinAllocCnt)
27 , fPathTransformBuffer(kPathXformBufferMinAllocCnt)
26 , fFlushing(false) 28 , fFlushing(false)
27 , fDrawID(0) { 29 , fDrawID(0) {
28 30
29 fDstGpu->ref(); 31 fDstGpu->ref();
30 fCaps.reset(SkRef(fDstGpu->caps())); 32 fCaps.reset(SkRef(fDstGpu->caps()));
31 33
32 SkASSERT(vertexPool); 34 SkASSERT(vertexPool);
33 SkASSERT(indexPool); 35 SkASSERT(indexPool);
34 36
35 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 37 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 if (hasLocalCoords) { 96 if (hasLocalCoords) {
95 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeo f(SkColor)); 97 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeo f(SkColor));
96 } else { 98 } else {
97 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(Sk Color)); 99 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(Sk Color));
98 } 100 }
99 if (0xFF == GrColorUnpackA(color)) { 101 if (0xFF == GrColorUnpackA(color)) {
100 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); 102 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
101 } 103 }
102 } 104 }
103 105
106 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin gs) {
107 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa ce;
108 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
109 if (isWinding) {
110 // Double check that it is in fact winding.
111 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
112 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
113 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
114 SkASSERT(!pathStencilSettings.isTwoSided());
115 }
116 return isWinding;
117 }
118
119 static bool draw_state_is_opaque(const GrDrawState& drawState) {
egdaniel 2014/11/11 18:39:07 I don't believe this function fully captures what
Chris Dalton 2014/11/11 19:29:15 Ok, so while we wait for isUnblended can I capture
120 GrBlendCoeff dstBlendCoeff = drawState.getDstBlendCoeff();
121 return (kZero_GrBlendCoeff == dstBlendCoeff ||
122 (kISA_GrBlendCoeff == dstBlendCoeff && drawState.srcAlphaWillBeOne() ));
123 }
124
104 enum { 125 enum {
105 kTraceCmdBit = 0x80, 126 kTraceCmdBit = 0x80,
106 kCmdMask = 0x7f, 127 kCmdMask = 0x7f,
107 }; 128 };
108 129
109 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } 130 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
110 131
111 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } 132 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
112 133
113 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); } 134 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); }
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 PathTransformType transformsType, 347 PathTransformType transformsType,
327 const GrClipMaskManager::ScissorState& sci ssorState, 348 const GrClipMaskManager::ScissorState& sci ssorState,
328 const GrStencilSettings& stencilSettings, 349 const GrStencilSettings& stencilSettings,
329 const GrDeviceCoordTexture* dstCopy) { 350 const GrDeviceCoordTexture* dstCopy) {
330 SkASSERT(pathRange); 351 SkASSERT(pathRange);
331 SkASSERT(indices); 352 SkASSERT(indices);
332 SkASSERT(transforms); 353 SkASSERT(transforms);
333 354
334 this->recordStateIfNecessary(); 355 this->recordStateIfNecessary();
335 356
336 int sizeOfIndices = sizeof(uint32_t) * count; 357 int indicesLocation = fPathIndexBuffer.append(indices, count);
337 int sizeOfTransforms = sizeof(float) * count * 358 int transformsLocation = fPathTransformBuffer.append(transforms,
338 GrPathRendering::PathTransformSize(transformsType); 359 GrPathRendering::PathTransformSize(transformsTy pe) * count);
339 360
340 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p athRange), 361 if (kDrawPaths_Cmd == fCmdBuffer.back().fType) {
341 sizeOfIndices + sizeOfTra nsforms); 362 // The previous command was also DrawPaths. Try to collapse this call in to the one
342 memcpy(dp->indices(), indices, sizeOfIndices); 363 // before. Note that stencilling all the paths at once, then covering, m ay not be
364 // equivalent to two separate draw calls if there is overlap. Blending w on't work,
365 // and the combined calls may also cancel each other's winding numbers i n some
366 // places. For now the winding numbers are only an issue if the fill is even/odd,
367 // because DrawPaths is currently only used for glyphs, and glyphs in th e same
368 // font tend to all wind in the same direction.
369 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
370 if (pathRange == previous->pathRange() &&
371 transformsType == previous->fTransformsType &&
372 scissorState == previous->fScissorState &&
373 stencilSettings == previous->fStencilSettings &&
374 path_fill_type_is_winding(stencilSettings) &&
375 draw_state_is_opaque(this->getDrawState())) {
bsalomon 2014/11/11 14:41:25 Could/should you check that the b.boxes don't over
Chris Dalton 2014/11/11 17:49:07 In theory, yes. But right now there isn't a way of
376 // Fold this DrawPaths call into the one previous.
377 SkASSERT(!dstCopy || !dstCopy->texture());
378 previous->fCount += count;
379 return;
380 }
381 }
382
383 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ;
384 dp->fIndicesLocation = indicesLocation;
343 dp->fCount = count; 385 dp->fCount = count;
344 memcpy(dp->transforms(), transforms, sizeOfTransforms); 386 dp->fTransformsLocation = transformsLocation;
345 dp->fTransformsType = transformsType; 387 dp->fTransformsType = transformsType;
346 dp->fScissorState = scissorState; 388 dp->fScissorState = scissorState;
347 dp->fStencilSettings = stencilSettings; 389 dp->fStencilSettings = stencilSettings;
348 if (dstCopy) { 390 if (dstCopy) {
349 dp->fDstCopy = *dstCopy; 391 dp->fDstCopy = *dstCopy;
350 } 392 }
351 393
352 this->recordTraceMarkersIfNecessary(); 394 this->recordTraceMarkersIfNecessary();
353 } 395 }
354 396
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 clr->fColor = GrColor_ILLEGAL; 438 clr->fColor = GrColor_ILLEGAL;
397 this->recordTraceMarkersIfNecessary(); 439 this->recordTraceMarkersIfNecessary();
398 } 440 }
399 441
400 void GrInOrderDrawBuffer::reset() { 442 void GrInOrderDrawBuffer::reset() {
401 SkASSERT(1 == fGeoPoolStateStack.count()); 443 SkASSERT(1 == fGeoPoolStateStack.count());
402 this->resetVertexSource(); 444 this->resetVertexSource();
403 this->resetIndexSource(); 445 this->resetIndexSource();
404 446
405 fCmdBuffer.reset(); 447 fCmdBuffer.reset();
448 fPathIndexBuffer.reset();
449 fPathTransformBuffer.reset();
406 fLastState = NULL; 450 fLastState = NULL;
407 fVertexPool.reset(); 451 fVertexPool.reset();
408 fIndexPool.reset(); 452 fIndexPool.reset();
409 fGpuCmdMarkers.reset(); 453 fGpuCmdMarkers.reset();
410 } 454 }
411 455
412 void GrInOrderDrawBuffer::flush() { 456 void GrInOrderDrawBuffer::flush() {
413 if (fFlushing) { 457 if (fFlushing) {
414 return; 458 return;
415 } 459 }
(...skipping 29 matching lines...) Expand all
445 fDstGpu->addGpuTraceMarker(&newMarker); 489 fDstGpu->addGpuTraceMarker(&newMarker);
446 ++currCmdMarker; 490 ++currCmdMarker;
447 } 491 }
448 492
449 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || 493 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) ||
450 kStencilPath_Cmd == strip_trace_bit(iter->fTyp e) || 494 kStencilPath_Cmd == strip_trace_bit(iter->fTyp e) ||
451 kDrawPath_Cmd == strip_trace_bit(iter->fType) || 495 kDrawPath_Cmd == strip_trace_bit(iter->fType) ||
452 kDrawPaths_Cmd == strip_trace_bit(iter->fType) ); 496 kDrawPaths_Cmd == strip_trace_bit(iter->fType) );
453 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); 497 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState);
454 498
455 iter->execute(fDstGpu); 499 iter->execute(this);
456 500
457 if (cmd_has_trace_marker(iter->fType)) { 501 if (cmd_has_trace_marker(iter->fType)) {
458 fDstGpu->removeGpuTraceMarker(&newMarker); 502 fDstGpu->removeGpuTraceMarker(&newMarker);
459 } 503 }
460 } 504 }
461 505
462 fDstGpu->restoreActiveTraceMarkers(); 506 fDstGpu->restoreActiveTraceMarkers();
463 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); 507 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
464 508
465 fDstGpu->setDrawState(prevDrawState); 509 fDstGpu->setDrawState(prevDrawState);
466 prevDrawState->unref(); 510 prevDrawState->unref();
467 this->reset(); 511 this->reset();
468 ++fDrawID; 512 ++fDrawID;
469 } 513 }
470 514
471 void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) { 515 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf) {
516 GrGpu* gpu = buf->dstGpu();
472 gpu->setVertexSourceToBuffer(this->vertexBuffer()); 517 gpu->setVertexSourceToBuffer(this->vertexBuffer());
473 if (fInfo.isIndexed()) { 518 if (fInfo.isIndexed()) {
474 gpu->setIndexSourceToBuffer(this->indexBuffer()); 519 gpu->setIndexSourceToBuffer(this->indexBuffer());
475 } 520 }
476 gpu->draw(fInfo, fScissorState); 521 gpu->draw(fInfo, fScissorState);
477 } 522 }
478 523
479 void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) { 524 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf) {
525 GrGpu* gpu = buf->dstGpu();
480 gpu->stencilPath(this->path(), fScissorState, fStencilSettings); 526 gpu->stencilPath(this->path(), fScissorState, fStencilSettings);
481 } 527 }
482 528
483 void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) { 529 void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf) {
530 GrGpu* gpu = buf->dstGpu();
484 gpu->drawPath(this->path(), fScissorState, fStencilSettings, 531 gpu->drawPath(this->path(), fScissorState, fStencilSettings,
485 fDstCopy.texture() ? &fDstCopy : NULL); 532 fDstCopy.texture() ? &fDstCopy : NULL);
486 } 533 }
487 534
488 void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) { 535 void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf) {
489 gpu->drawPaths(this->pathRange(), this->indices(), fCount, this->transforms( ), 536 GrGpu* gpu = buf->dstGpu();
490 fTransformsType, fScissorState, fStencilSettings, 537 gpu->drawPaths(this->pathRange(), buf->pathIndexBuffer() + fIndicesLocation, fCount,
491 fDstCopy.texture() ? &fDstCopy : NULL); 538 buf->pathTransformBuffer() + fTransformsLocation, fTransforms Type,
539 fScissorState, fStencilSettings, fDstCopy.texture() ? &fDstCo py : NULL);
492 } 540 }
493 541
494 void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) { 542 void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer* buf) {
543 GrGpu* gpu = buf->dstGpu();
495 gpu->setDrawState(&fState); 544 gpu->setDrawState(&fState);
496 } 545 }
497 546
498 void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) { 547 void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf) {
548 GrGpu* gpu = buf->dstGpu();
499 if (GrColor_ILLEGAL == fColor) { 549 if (GrColor_ILLEGAL == fColor) {
500 gpu->discard(this->renderTarget()); 550 gpu->discard(this->renderTarget());
501 } else { 551 } else {
502 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); 552 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
503 } 553 }
504 } 554 }
505 555
506 void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) { 556 void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf) {
507 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); 557 GrGpu* gpu = buf->dstGpu();
558 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
508 } 559 }
509 560
510 void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) { 561 void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf) {
562 GrGpu* gpu = buf->dstGpu();
511 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); 563 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
512 } 564 }
513 565
514 bool GrInOrderDrawBuffer::copySurface(GrSurface* dst, 566 bool GrInOrderDrawBuffer::copySurface(GrSurface* dst,
515 GrSurface* src, 567 GrSurface* src,
516 const SkIRect& srcRect, 568 const SkIRect& srcRect,
517 const SkIPoint& dstPoint) { 569 const SkIPoint& dstPoint) {
518 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { 570 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
519 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src)); 571 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src));
520 cs->fSrcRect = srcRect; 572 cs->fSrcRect = srcRect;
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 776
725 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { 777 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
726 SkASSERT(!fCmdBuffer.empty()); 778 SkASSERT(!fCmdBuffer.empty());
727 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); 779 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
728 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); 780 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
729 if (activeTraceMarkers.count() > 0) { 781 if (activeTraceMarkers.count() > 0) {
730 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); 782 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
731 fGpuCmdMarkers.push_back(activeTraceMarkers); 783 fGpuCmdMarkers.push_back(activeTraceMarkers);
732 } 784 }
733 } 785 }
786
787 template<typename T> int GrInOrderDrawBuffer::DataBuffer<T>::append(const T* arr ay, int count) {
788 if (fCount + count > fAllocCnt) {
789 fAllocCnt = SkTMax(2 * fAllocCnt, (fCount + count) * 3 / 2);
790 fBuffer.realloc(fAllocCnt);
791 }
792 int location = fCount;
793 memcpy(fBuffer + location, array, sizeof(T) * count);
794 fCount += count;
795 return location;
796 }
797
798 template<typename T> void GrInOrderDrawBuffer::DataBuffer<T>::reset() {
799 // Assume the next time this buffer fills up it will use approximately the s ame amount
800 // of space as last time. Only resize if we're using less than a third of th e
801 // allocated space, and leave enough for 50% growth over last time.
802 if (3 * fCount < fAllocCnt && fAllocCnt > fMinAllocCnt) {
803 fAllocCnt = SkTMax(fMinAllocCnt, fCount * 3 / 2);
804 fBuffer.reset(fAllocCnt);
805 }
806 fCount = 0;
807 }
OLDNEW
« src/gpu/GrInOrderDrawBuffer.h ('K') | « src/gpu/GrInOrderDrawBuffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698