Index: src/gpu/GrInOrderDrawBuffer.cpp |
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp |
index 9835200598d76ddadb1cd94661b8d299b24c961b..1789c49aca35dcedebcfe6770296862c48ee1630 100644 |
--- a/src/gpu/GrInOrderDrawBuffer.cpp |
+++ b/src/gpu/GrInOrderDrawBuffer.cpp |
@@ -9,9 +9,10 @@ |
#include "GrBufferAllocPool.h" |
#include "GrDrawTargetCaps.h" |
-#include "GrTextStrike.h" |
#include "GrGpu.h" |
+#include "GrOptDrawState.h" |
#include "GrTemplates.h" |
+#include "GrTextStrike.h" |
#include "GrTexture.h" |
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
@@ -246,7 +247,8 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info, |
GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
const GrDrawState& drawState = this->getDrawState(); |
- this->recordStateIfNecessary(); |
+ this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType()), |
+ info.getDstCopy()); |
const GrVertexBuffer* vb; |
if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
@@ -297,7 +299,7 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, |
const GrClipMaskManager::ScissorState& scissorState, |
const GrStencilSettings& stencilSettings) { |
// Only compare the subset of GrDrawState relevant to path stenciling? |
- this->recordStateIfNecessary(); |
+ this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL); |
StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
sp->fScissorState = scissorState; |
sp->fStencilSettings = stencilSettings; |
@@ -309,7 +311,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, |
const GrStencilSettings& stencilSettings, |
const GrDeviceCoordTexture* dstCopy) { |
// TODO: Only compare the subset of GrDrawState relevant to path covering? |
- this->recordStateIfNecessary(); |
+ this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy); |
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
if (dstCopy) { |
dp->fDstCopy = *dstCopy; |
@@ -331,7 +333,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, |
SkASSERT(indices); |
SkASSERT(transforms); |
- this->recordStateIfNecessary(); |
+ this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy); |
int sizeOfIndices = sizeof(uint32_t) * count; |
int sizeOfTransforms = sizeof(float) * count * |
@@ -429,13 +431,15 @@ void GrInOrderDrawBuffer::flush() { |
fVertexPool.unmap(); |
fIndexPool.unmap(); |
- GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); |
- |
CmdBuffer::Iter iter(fCmdBuffer); |
int currCmdMarker = 0; |
fDstGpu->saveActiveTraceMarkers(); |
+ // Gpu no longer maintains the current drawstate, so we track the setstate calls below. |
+ // NOTE: we always record a new drawstate at flush boundaries |
+ SkAutoTUnref<const GrOptDrawState> currentOptState; |
+ |
while (iter.next()) { |
GrGpuTraceMarker newMarker("", -1); |
SkString traceString; |
@@ -446,13 +450,15 @@ void GrInOrderDrawBuffer::flush() { |
++currCmdMarker; |
} |
- SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || |
- kStencilPath_Cmd == strip_trace_bit(iter->fType) || |
- kDrawPath_Cmd == strip_trace_bit(iter->fType) || |
- kDrawPaths_Cmd == strip_trace_bit(iter->fType)); |
- SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); |
- |
- iter->execute(fDstGpu); |
+ if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
+ const SetState* ss = reinterpret_cast<const SetState*>(iter.get()); |
+ currentOptState.reset(GrOptDrawState::Create(ss->fState, |
+ fDstGpu, |
+ &ss->fDstCopy, |
+ ss->fDrawType)); |
+ } else { |
+ iter->execute(fDstGpu, currentOptState.get()); |
+ } |
if (cmd_has_trace_marker(iter->fType)) { |
fDstGpu->removeGpuTraceMarker(&newMarker); |
@@ -462,40 +468,49 @@ void GrInOrderDrawBuffer::flush() { |
fDstGpu->restoreActiveTraceMarkers(); |
SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
- fDstGpu->setDrawState(prevDrawState); |
- prevDrawState->unref(); |
this->reset(); |
++fDrawID; |
} |
-void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) { |
- gpu->setVertexSourceToBuffer(this->vertexBuffer()); |
+void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const GrOptDrawState* optState) { |
+ if (!optState) { |
+ return; |
+ } |
+ gpu->setVertexSourceToBuffer(this->vertexBuffer(), optState->getVertexStride()); |
if (fInfo.isIndexed()) { |
gpu->setIndexSourceToBuffer(this->indexBuffer()); |
} |
- gpu->draw(fInfo, fScissorState); |
+ gpu->draw(*optState, fInfo, fScissorState); |
} |
-void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) { |
- gpu->stencilPath(this->path(), fScissorState, fStencilSettings); |
+void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const GrOptDrawState* optState) { |
+ if (!optState) { |
+ return; |
+ } |
+ gpu->stencilPath(*optState, this->path(), fScissorState, fStencilSettings); |
} |
-void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) { |
- gpu->drawPath(this->path(), fScissorState, fStencilSettings, |
- fDstCopy.texture() ? &fDstCopy : NULL); |
+void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const GrOptDrawState* optState) { |
+ if (!optState) { |
+ return; |
+ } |
+ gpu->drawPath(*optState, this->path(), fScissorState, fStencilSettings, |
+ fDstCopy.texture() ? &fDstCopy : NULL); |
} |
-void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) { |
- gpu->drawPaths(this->pathRange(), this->indices(), fCount, this->transforms(), |
- fTransformsType, fScissorState, fStencilSettings, |
- fDstCopy.texture() ? &fDstCopy : NULL); |
+void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const GrOptDrawState* optState) { |
+ if (!optState) { |
+ return; |
+ } |
+ gpu->drawPaths(*optState, this->pathRange(), this->indices(), fCount, this->transforms(), |
+ fTransformsType, fScissorState, fStencilSettings, |
+ fDstCopy.texture() ? &fDstCopy : NULL); |
} |
-void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) { |
- gpu->setDrawState(&fState); |
+void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const GrOptDrawState*) { |
} |
-void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) { |
+void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const GrOptDrawState*) { |
if (GrColor_ILLEGAL == fColor) { |
gpu->discard(this->renderTarget()); |
} else { |
@@ -503,11 +518,11 @@ void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) { |
} |
} |
-void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) { |
- gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); |
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const GrOptDrawState*) { |
+ gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); |
} |
-void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) { |
+void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const GrOptDrawState*){ |
gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
} |
@@ -640,8 +655,7 @@ void GrInOrderDrawBuffer::releaseReservedVertexSpace() { |
// offset into the pool's pointer that was referenced. Now we return to the |
// pool any portion at the tail of the allocation that no draw referenced. |
size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount; |
- fVertexPool.putBack(reservedVertexBytes - |
- poolState.fUsedPoolVertexBytes); |
+ fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes); |
poolState.fUsedPoolVertexBytes = 0; |
poolState.fPoolVertexBuffer = NULL; |
poolState.fPoolStartVertex = 0; |
@@ -687,26 +701,36 @@ void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restored |
poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount; |
} |
if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { |
- poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * |
- restoredState.fIndexCount; |
+ poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexCount; |
} |
} |
-void GrInOrderDrawBuffer::recordStateIfNecessary() { |
+void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType, |
+ const GrDeviceCoordTexture* dstCopy) { |
if (!fLastState) { |
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState())); |
fLastState = &ss->fState; |
+ if (dstCopy) { |
+ ss->fDstCopy = *dstCopy; |
+ } |
+ ss->fDrawType = drawType; |
this->convertDrawStateToPendingExec(fLastState); |
this->recordTraceMarkersIfNecessary(); |
return; |
} |
const GrDrawState& curr = this->getDrawState(); |
switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { |
- case GrDrawState::kIncompatible_CombinedState: |
- fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))->fState; |
+ case GrDrawState::kIncompatible_CombinedState: { |
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr)); |
+ fLastState = &ss->fState; |
+ if (dstCopy) { |
+ ss->fDstCopy = *dstCopy; |
+ } |
+ ss->fDrawType = drawType; |
this->convertDrawStateToPendingExec(fLastState); |
this->recordTraceMarkersIfNecessary(); |
break; |
+ } |
case GrDrawState::kA_CombinedState: |
case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
break; |