diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 6f9395b5c3..fee62a8dc4 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -127,7 +127,6 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { void GrContext::initCommon() { fDrawState = SkNEW(GrDrawState); - fGpu->setDrawState(fDrawState); fResourceCache = SkNEW_ARGS(GrResourceCache, (fGpu->caps(), MAX_RESOURCE_CACHE_COUNT, diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index ab24c5447f..d3fcddf432 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -26,14 +26,10 @@ GrGpu::GrGpu(GrContext* context) , fResetBits(kAll_GrBackendState) , fQuadIndexBuffer(NULL) , fContext(context) { - fDrawState = &fDefaultDrawState; - // We assume that fDrawState always owns a ref to the object it points at. - fDefaultDrawState.ref(); } GrGpu::~GrGpu() { SkSafeSetNull(fQuadIndexBuffer); - SkSafeUnref(fDrawState); SkSafeUnref(fGeoSrcState.fVertexBuffer); SkSafeUnref(fGeoSrcState.fIndexBuffer); } @@ -187,13 +183,7 @@ void GrGpu::clear(const SkIRect* rect, void GrGpu::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* renderTarget) { - if (NULL == renderTarget) { - renderTarget = this->getDrawState().getRenderTarget(); - } - if (NULL == renderTarget) { - SkASSERT(0); - return; - } + SkASSERT(renderTarget); this->handleDirtyContext(); this->onClearStencilClip(renderTarget, rect, insideClip); } @@ -270,11 +260,11 @@ void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { } } -void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) { +void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) { SkSafeUnref(fGeoSrcState.fVertexBuffer); fGeoSrcState.fVertexBuffer = buffer; buffer->ref(); - fGeoSrcState.fVertexSize = this->drawState()->getVertexStride(); + fGeoSrcState.fVertexSize = vertexStride; } void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { @@ -283,18 +273,6 @@ void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { buffer->ref(); } -void GrGpu::setDrawState(GrDrawState* drawState) { - SkASSERT(fDrawState); - if (NULL == drawState) { - drawState = &fDefaultDrawState; - } - if (fDrawState != drawState) { - fDrawState->unref(); - drawState->ref(); - fDrawState = drawState; - } -} - //////////////////////////////////////////////////////////////////////////////// static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; @@ -320,23 +298,26 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { //////////////////////////////////////////////////////////////////////////////// -void GrGpu::draw(const GrDrawTarget::DrawInfo& info, - const GrClipMaskManager::ScissorState& scissorState) { +void GrGpu::draw(const GrOptDrawState& ds, + const GrDrawTarget::DrawInfo& info, + const GrClipMaskManager::ScissorState& scissorState) { this->handleDirtyContext(); - if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()), + if (!this->flushGraphicsState(ds, + PrimTypeToDrawType(info.primitiveType()), scissorState, info.getDstCopy())) { return; } - this->onDraw(info); + this->onDraw(ds, info); } -void GrGpu::stencilPath(const GrPath* path, - const GrClipMaskManager::ScissorState& scissorState, - const GrStencilSettings& stencilSettings) { +void GrGpu::stencilPath(const GrOptDrawState& ds, + const GrPath* path, + const GrClipMaskManager::ScissorState& scissorState, + const GrStencilSettings& stencilSettings) { this->handleDirtyContext(); - if (!this->flushGraphicsState(kStencilPath_DrawType, scissorState, NULL)) { + if (!this->flushGraphicsState(ds, kStencilPath_DrawType, scissorState, NULL)) { return; } @@ -344,30 +325,32 @@ void GrGpu::stencilPath(const GrPath* path, } -void GrGpu::drawPath(const GrPath* path, - const GrClipMaskManager::ScissorState& scissorState, - const GrStencilSettings& stencilSettings, - const GrDeviceCoordTexture* dstCopy) { +void GrGpu::drawPath(const GrOptDrawState& ds, + const GrPath* path, + const GrClipMaskManager::ScissorState& scissorState, + const GrStencilSettings& stencilSettings, + const GrDeviceCoordTexture* dstCopy) { this->handleDirtyContext(); - if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) { + if (!this->flushGraphicsState(ds, kDrawPath_DrawType, scissorState, dstCopy)) { return; } this->pathRendering()->drawPath(path, stencilSettings); } -void GrGpu::drawPaths(const GrPathRange* pathRange, - const uint32_t indices[], - int count, - const float transforms[], - GrDrawTarget::PathTransformType transformsType, - const GrClipMaskManager::ScissorState& scissorState, - const GrStencilSettings& stencilSettings, - const GrDeviceCoordTexture* dstCopy) { +void GrGpu::drawPaths(const GrOptDrawState& ds, + const GrPathRange* pathRange, + const uint32_t indices[], + int count, + const float transforms[], + GrDrawTarget::PathTransformType transformsType, + const GrClipMaskManager::ScissorState& scissorState, + const GrStencilSettings& stencilSettings, + const GrDeviceCoordTexture* dstCopy) { this->handleDirtyContext(); - if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) { + if (!this->flushGraphicsState(ds, kDrawPaths_DrawType, scissorState, dstCopy)) { return; } diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 5279ce8b39..dfc71fe970 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -60,25 +60,6 @@ public: */ const GrDrawTargetCaps* caps() const { return fCaps.get(); } - /** - * Sets the draw state object for the gpu. Note that this does not - * make a copy. The GrGpu will take a reference to passed object. - * Passing NULL will cause the GrGpu to use its own internal draw - * state object rather than an externally provided one. - */ - void setDrawState(GrDrawState* drawState); - - /** - * Read-only access to the GrGpu current draw state. - */ - const GrDrawState& getDrawState() const { return *fDrawState; } - - /** - * Read-write access to the GrGpu current draw state. Note that - * this doesn't ref. - */ - GrDrawState* drawState() { return fDrawState; } - GrPathRendering* pathRendering() { return fPathRendering.get(); } @@ -302,7 +283,7 @@ public: void clearStencilClip(const SkIRect& rect, bool insideClip, - GrRenderTarget* renderTarget = NULL); + GrRenderTarget* renderTarget); /** * Discards the contents render target. NULL indicates that the current render target should @@ -401,7 +382,7 @@ public: * unlocked before draw call. Vertex size is queried * from current GrDrawState. */ - void setVertexSourceToBuffer(const GrVertexBuffer* buffer); + void setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride); /** * Sets source of index data for the next indexed draw. Data does not have @@ -412,16 +393,20 @@ public: */ void setIndexSourceToBuffer(const GrIndexBuffer* buffer); - virtual void draw(const GrDrawTarget::DrawInfo&, + virtual void draw(const GrOptDrawState&, + const GrDrawTarget::DrawInfo&, const GrClipMaskManager::ScissorState&); - virtual void stencilPath(const GrPath*, + virtual void stencilPath(const GrOptDrawState&, + const GrPath*, const GrClipMaskManager::ScissorState&, const GrStencilSettings&); - virtual void drawPath(const GrPath*, + virtual void drawPath(const GrOptDrawState&, + const GrPath*, const GrClipMaskManager::ScissorState&, const GrStencilSettings&, const GrDeviceCoordTexture* dstCopy); - virtual void drawPaths(const GrPathRange*, + virtual void drawPaths(const GrOptDrawState&, + const GrPathRange*, const uint32_t indices[], int count, const float transforms[], @@ -430,8 +415,7 @@ public: const GrStencilSettings&, const GrDeviceCoordTexture*); -protected: - DrawType PrimTypeToDrawType(GrPrimitiveType type) { + static DrawType PrimTypeToDrawType(GrPrimitiveType type) { switch (type) { case kTriangles_GrPrimitiveType: case kTriangleStrip_GrPrimitiveType: @@ -448,6 +432,7 @@ protected: } } +protected: // Functions used to map clip-respecting stencil tests into normal // stencil funcs supported by GPUs. static GrStencilFunc ConvertStencilFunc(bool stencilInClip, @@ -513,7 +498,7 @@ private: bool insideClip) = 0; // overridden by backend-specific derived class to perform the draw call. - virtual void onDraw(const GrDrawTarget::DrawInfo&) = 0; + virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) = 0; // overridden by backend-specific derived class to perform the read pixels. virtual bool onReadPixels(GrRenderTarget* target, @@ -543,7 +528,8 @@ private: // deltas from previous state at draw time. This function does the // backend-specific flush of the state. // returns false if current state is unsupported. - virtual bool flushGraphicsState(DrawType, + virtual bool flushGraphicsState(const GrOptDrawState&, + DrawType, const GrClipMaskManager::ScissorState&, const GrDeviceCoordTexture* dstCopy) = 0; @@ -573,8 +559,6 @@ private: uint32_t fResetBits; // these are mutable so they can be created on-demand mutable GrIndexBuffer* fQuadIndexBuffer; - GrDrawState fDefaultDrawState; - GrDrawState* fDrawState; // To keep track that we always have at least as many debug marker adds as removes int fGpuTraceMarkerCount; GrTraceMarkerSet fActiveTraceMarkers; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 9835200598..1789c49aca 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 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(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; diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index ed62a93247..7780e402ed 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -11,6 +11,7 @@ #include "GrDrawTarget.h" #include "GrAllocPool.h" #include "GrAllocator.h" +#include "GrGpu.h" #include "GrIndexBuffer.h" #include "GrRenderTarget.h" #include "GrPath.h" @@ -23,7 +24,6 @@ #include "SkTemplates.h" #include "SkTypes.h" -class GrGpu; class GrIndexBufferAllocPool; class GrVertexBufferAllocPool; @@ -110,7 +110,7 @@ private: Cmd(uint8_t type) : fType(type) {} virtual ~Cmd() {} - virtual void execute(GrGpu*) = 0; + virtual void execute(GrGpu*, const GrOptDrawState*) = 0; uint8_t fType; }; @@ -129,7 +129,7 @@ private: const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); } const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); DrawInfo fInfo; ScissorState fScissorState; @@ -144,7 +144,7 @@ private: const GrPath* path() const { return fPath.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); ScissorState fScissorState; GrStencilSettings fStencilSettings; @@ -158,7 +158,7 @@ private: const GrPath* path() const { return fPath.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); GrDeviceCoordTexture fDstCopy; ScissorState fScissorState; @@ -175,7 +175,7 @@ private: uint32_t* indices() { return reinterpret_cast(CmdBuffer::GetDataForItem(this)); } float* transforms() { return reinterpret_cast(&this->indices()[fCount]); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); size_t fCount; PathTransformType fTransformsType; @@ -193,7 +193,7 @@ private: GrRenderTarget* renderTarget() const { return fRenderTarget.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); SkIRect fRect; GrColor fColor; @@ -209,7 +209,7 @@ private: GrRenderTarget* renderTarget() const { return fRenderTarget.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); SkIRect fRect; bool fInsideClip; @@ -224,7 +224,7 @@ private: GrSurface* dst() const { return fDst.get(); } GrSurface* src() const { return fSrc.get(); } - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); SkIPoint fDstPoint; SkIRect fSrcRect; @@ -237,9 +237,11 @@ private: struct SetState : public Cmd { SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {} - virtual void execute(GrGpu*); + virtual void execute(GrGpu*, const GrOptDrawState*); GrDrawState fState; + GrGpu::DrawType fDrawType; + GrDeviceCoordTexture fDstCopy; }; typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double. @@ -288,7 +290,7 @@ private: int concatInstancedDraw(const DrawInfo& info, const GrClipMaskManager::ScissorState&); // Determines whether the current draw operation requieres a new drawstate and if so records it. - void recordStateIfNecessary(); + void recordStateIfNecessary(GrGpu::DrawType, const GrDeviceCoordTexture*); // We lazily record clip changes in order to skip clips that have no effect. void recordClipIfNecessary(); // Records any trace markers for a command after adding it to the buffer. diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp index b176d3c0fc..611059ae4c 100644 --- a/src/gpu/GrTest.cpp +++ b/src/gpu/GrTest.cpp @@ -49,6 +49,8 @@ void GrContext::purgeAllUnlockedResources() { #include "GrInOrderDrawBuffer.h" #include "GrGpu.h" +class GrOptDrawState; + class MockGpu : public GrGpu { public: MockGpu(GrContext* context) : INHERITED(context) { fCaps.reset(SkNEW(GrDrawTargetCaps)); } @@ -118,7 +120,7 @@ private: const SkIRect& rect, bool insideClip) SK_OVERRIDE { } - virtual void onDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE { } + virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE { } virtual bool onReadPixels(GrRenderTarget* target, int left, int top, int width, int height, GrPixelConfig, @@ -147,7 +149,8 @@ private: return false; } - virtual bool flushGraphicsState(DrawType, + virtual bool flushGraphicsState(const GrOptDrawState&, + DrawType, const GrClipMaskManager::ScissorState&, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE { return false; diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index 66b129e876..2a46078d03 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -154,8 +154,6 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) { GrGLuint id = static_cast(path)->pathID(); - SkASSERT(fGpu->drawState()->getRenderTarget()); - SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); @@ -176,8 +174,6 @@ void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& stencilSettings) { GrGLuint id = static_cast(path)->pathID(); - SkASSERT(fGpu->drawState()->getRenderTarget()); - SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); @@ -202,8 +198,6 @@ void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i const float transforms[], PathTransformType transformsType, const GrStencilSettings& stencilSettings) { SkASSERT(fGpu->caps()->pathRenderingSupport()); - SkASSERT(fGpu->drawState()->getRenderTarget()); - SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); GrGLuint baseID = static_cast(pathRange)->basePathID(); diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 888f818993..877c21fc7e 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1729,9 +1729,9 @@ GrGLenum gPrimitiveType2GLMode[] = { #endif #endif -void GrGpuGL::onDraw(const GrDrawTarget::DrawInfo& info) { +void GrGpuGL::onDraw(const GrOptDrawState& ds, const GrDrawTarget::DrawInfo& info) { size_t indexOffsetInBytes; - this->setupGeometry(info, &indexOffsetInBytes); + this->setupGeometry(ds, info, &indexOffsetInBytes); SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode)); diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index fc7ad4e273..3757d76204 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -153,11 +153,12 @@ private: virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE; - virtual void onDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE; + virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE; virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE; - virtual bool flushGraphicsState(DrawType, + virtual bool flushGraphicsState(const GrOptDrawState&, + DrawType, const GrClipMaskManager::ScissorState&, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; @@ -171,7 +172,9 @@ private: // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start // index is relative to the returned offset. - void setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes); + void setupGeometry(const GrOptDrawState&, + const GrDrawTarget::DrawInfo& info, + size_t* indexOffsetInBytes); // Subclasses should call this to flush the blend state. // The params should be the final coefficients to apply diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index b197dc9caa..68f38df9f0 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -201,39 +201,31 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState, D #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) -bool GrGpuGL::flushGraphicsState(DrawType type, +bool GrGpuGL::flushGraphicsState(const GrOptDrawState& optState, + DrawType type, const GrClipMaskManager::ScissorState& scissorState, const GrDeviceCoordTexture* dstCopy) { - SkAutoTUnref optState(GrOptDrawState::Create(this->getDrawState(), - this, - dstCopy, - type)); - - if (!optState) { - return false; - } - // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true. - SkASSERT(optState->getRenderTarget()); + SkASSERT(optState.getRenderTarget()); if (kStencilPath_DrawType == type) { - const GrRenderTarget* rt = optState->getRenderTarget(); + const GrRenderTarget* rt = optState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); - this->glPathRendering()->setProjectionMatrix(optState->getViewMatrix(), size, rt->origin()); + this->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); } else { - this->flushMiscFixedFunctionState(*optState.get()); + this->flushMiscFixedFunctionState(optState); - GrBlendCoeff srcCoeff = optState->getSrcBlendCoeff(); - GrBlendCoeff dstCoeff = optState->getDstBlendCoeff(); + GrBlendCoeff srcCoeff = optState.getSrcBlendCoeff(); + GrBlendCoeff dstCoeff = optState.getDstBlendCoeff(); // In these blend coeff's we end up drawing nothing so we can skip draw all together if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff && - !optState->getStencil().doesWrite()) { + !optState.getStencil().doesWrite()) { return false; } - fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), type)); + fCurrentProgram.reset(fProgramCache->getProgram(optState, type)); if (NULL == fCurrentProgram.get()) { SkDEBUGFAIL("Failed to create program!"); return false; @@ -247,15 +239,15 @@ bool GrGpuGL::flushGraphicsState(DrawType type, fHWProgramID = programID; } - this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff); + this->flushBlend(optState, kDrawLines_DrawType == type, srcCoeff, dstCoeff); - fCurrentProgram->setData(*optState.get(), type, dstCopy); + fCurrentProgram->setData(optState, type, dstCopy); } - GrGLRenderTarget* glRT = static_cast(optState->getRenderTarget()); - this->flushStencil(optState->getStencil(), type); + GrGLRenderTarget* glRT = static_cast(optState.getRenderTarget()); + this->flushStencil(optState.getStencil(), type); this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); - this->flushAAState(*optState.get(), type); + this->flushAAState(optState, type); // This must come after textures are flushed because a texture may need // to be msaa-resolved (which will modify bound FBO state). @@ -264,16 +256,10 @@ bool GrGpuGL::flushGraphicsState(DrawType type, return true; } -void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes) { - SkAutoTUnref optState( - GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(), - PrimTypeToDrawType(info.primitiveType()))); - - // If the optState would is NULL it should have been caught in flushGraphicsState before getting - // here. - SkASSERT(optState); - - GrGLsizei stride = static_cast(optState->getVertexStride()); +void GrGpuGL::setupGeometry(const GrOptDrawState& optState, + const GrDrawTarget::DrawInfo& info, + size_t* indexOffsetInBytes) { + GrGLsizei stride = static_cast(optState.getVertexStride()); size_t vertexOffsetInBytes = stride * info.startVertex(); @@ -299,9 +285,9 @@ void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOff fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); if (fCurrentProgram->hasVertexShader()) { - int vertexAttribCount = optState->getVertexAttribCount(); + int vertexAttribCount = optState.getVertexAttribCount(); uint32_t usedAttribArraysMask = 0; - const GrVertexAttrib* vertexAttrib = optState->getVertexAttribs(); + const GrVertexAttrib* vertexAttrib = optState.getVertexAttribs(); for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount; ++vertexAttribIndex, ++vertexAttrib) {