Snap optdrawstate in inorder draw buffer and pass into gpu
authorjoshualitt <joshualitt@chromium.org>
Tue, 11 Nov 2014 00:03:14 +0000 (16:03 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 11 Nov 2014 00:03:15 +0000 (16:03 -0800)
BUG=skia:

Review URL: https://codereview.chromium.org/709133003

src/gpu/GrContext.cpp
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h
src/gpu/GrTest.cpp
src/gpu/gl/GrGLPathRendering.cpp
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp

index 6f9395b..fee62a8 100755 (executable)
@@ -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,
index ab24c54..d3fcddf 100644 (file)
@@ -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;
     }
 
index 5279ce8..dfc71fe 100644 (file)
@@ -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;
index 9835200..1789c49 100644 (file)
@@ -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;
index ed62a93..7780e40 100644 (file)
@@ -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<uint32_t*>(CmdBuffer::GetDataForItem(this)); }
         float* transforms() { return reinterpret_cast<float*>(&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.
index b176d3c..611059a 100644 (file)
@@ -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;
index 66b129e..2a46078 100644 (file)
@@ -154,8 +154,6 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface,
 
 void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
     GrGLuint id = static_cast<const GrGLPath*>(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<const GrGLPath*>(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<const GrGLPathRange*>(pathRange)->basePathID();
 
index 888f818..877c21f 100644 (file)
@@ -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));
 
index fc7ad4e..3757d76 100644 (file)
@@ -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
index b197dc9..68f38df 100644 (file)
@@ -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<GrOptDrawState> 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<GrGLRenderTarget*>(optState->getRenderTarget());
-    this->flushStencil(optState->getStencil(), type);
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(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<GrOptDrawState> 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<GrGLsizei>(optState->getVertexStride());
+void GrGpuGL::setupGeometry(const GrOptDrawState& optState,
+                            const GrDrawTarget::DrawInfo& info,
+                            size_t* indexOffsetInBytes) {
+    GrGLsizei stride = static_cast<GrGLsizei>(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) {