Revert of Move state management to GrInOrderDrawBuffer (patchset #4 id:60001 of https://codereview.chromium.org/1120143002/)

Reason for revert:
Breaks windows

Original issue's description:
> Move state management to GrInOrderDrawBuffer
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/5d6bb6f795143ca360b868560b52165de51fa269

TBR=bsalomon@google.com,robertphillips@google.com,joshualitt@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1119353002
diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp
index d68a242..a6d3148 100644
--- a/src/gpu/GrTargetCommands.cpp
+++ b/src/gpu/GrTargetCommands.cpp
@@ -26,19 +26,27 @@
     return isWinding;
 }
 
-GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch* batch) {
+GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
+                                                  GrInOrderDrawBuffer* iodb,
+                                                  GrBatch* batch,
+                                                  const GrDrawTarget::PipelineInfo& pipelineInfo) {
+    if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
+        return NULL;
+    }
+
     // Check if there is a Batch Draw we can batch with
-    if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
+    if (Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
         DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back());
-        if (previous->fState == state && previous->fBatch->combineIfPossible(batch)) {
+        if (previous->fBatch->combineIfPossible(batch)) {
             return NULL;
         }
     }
 
-    return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatchTarget));
+    return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
 }
 
 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
+                                                        GrInOrderDrawBuffer* iodb,
                                                         const GrPipelineBuilder& pipelineBuilder,
                                                         const GrPathProcessor* pathProc,
                                                         const GrPath* path,
@@ -55,17 +63,21 @@
 }
 
 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
-                                                  State* state,
+                                                  GrInOrderDrawBuffer* iodb,
                                                   const GrPathProcessor* pathProc,
                                                   const GrPath* path,
-                                                  const GrStencilSettings& stencilSettings) {
-    DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path));
+                                                  const GrStencilSettings& stencilSettings,
+                                                  const GrDrawTarget::PipelineInfo& pipelineInfo) {
+    // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
+    if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
+        return NULL;
+    }
+    DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
     dp->fStencilSettings = stencilSettings;
     return dp;
 }
 
 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
-                                                  State* state,
                                                   GrInOrderDrawBuffer* iodb,
                                                   const GrPathProcessor* pathProc,
                                                   const GrPathRange* pathRange,
@@ -80,6 +92,10 @@
     SkASSERT(indexValues);
     SkASSERT(transformValues);
 
+    if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
+        return NULL;
+    }
+
     char* savedIndices;
     float* savedTransforms;
     
@@ -87,7 +103,7 @@
                                      transformValues, transformType,
                                      count, &savedIndices, &savedTransforms);
 
-    if (!fCmdBuffer.empty() && Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
+    if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
         // The previous command was also DrawPaths. Try to collapse this call into the one
         // before. Note that stenciling all the paths at once, then covering, may not be
         // equivalent to two separate draw calls if there is overlap. Blending won't work,
@@ -101,8 +117,7 @@
             transformType == previous->fTransformType &&
             stencilSettings == previous->fStencilSettings &&
             path_fill_type_is_winding(stencilSettings) &&
-            !pipelineInfo.willBlendWithDst(pathProc) &&
-            previous->fState == state) {
+            !pipelineInfo.willBlendWithDst(pathProc)) {
                 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
                 const int xformSize = GrPathRendering::PathTransformSize(transformType);
                 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
@@ -115,7 +130,7 @@
         }
     }
 
-    DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, pathRange));
+    DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
     dp->fIndices = savedIndices;
     dp->fIndexType = indexType;
     dp->fTransforms = savedTransforms;
@@ -125,7 +140,8 @@
     return dp;
 }
 
-GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect,
+GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
+                                                     const SkIRect* rect, 
                                                      GrColor color,
                                                      bool canIgnoreRect,
                                                      GrRenderTarget* renderTarget) {
@@ -147,7 +163,8 @@
     return clr;
 }
 
-GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& rect,
+GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuffer* iodb,
+                                                                const SkIRect& rect,
                                                                 bool insideClip,
                                                                 GrRenderTarget* renderTarget) {
     SkASSERT(renderTarget);
@@ -158,7 +175,8 @@
     return clr;
 }
 
-GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTarget) {
+GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb,
+                                                       GrRenderTarget* renderTarget) {
     SkASSERT(renderTarget);
 
     Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
@@ -168,6 +186,7 @@
 
 void GrTargetCommands::reset() {
     fCmdBuffer.reset();
+    fPrevState = NULL;
 }
 
 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
@@ -175,6 +194,10 @@
         return;
     }
 
+    // Updated every time we find a set state cmd to reflect the current state in the playback
+    // stream.
+    SetState* currentState = NULL;
+
     GrGpu* gpu = iodb->getGpu();
 
     // Loop over all batches and generate geometry
@@ -183,8 +206,13 @@
         if (Cmd::kDrawBatch_CmdType == genIter->type()) {
             DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get());
             fBatchTarget.resetNumberOfDraws();
-            db->fBatch->generateGeometry(&fBatchTarget, db->fState->getPipeline());
+            db->execute(NULL, currentState);
             db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
+        } else if (Cmd::kSetState_CmdType == genIter->type()) {
+            SetState* ss = reinterpret_cast<SetState*>(genIter.get());
+
+            ss->execute(gpu, currentState);
+            currentState = ss;
         }
     }
 
@@ -203,7 +231,29 @@
             gpu->addGpuTraceMarker(&newMarker);
         }
 
-        iter->execute(gpu);
+        if (Cmd::kDrawBatch_CmdType == iter->type()) {
+            DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
+            fBatchTarget.flushNext(db->fBatch->numberOfDraws());
+
+            if (iter->isTraced()) {
+                gpu->removeGpuTraceMarker(&newMarker);
+            }
+            continue;
+        }
+
+        if (Cmd::kSetState_CmdType == iter->type()) {
+            // TODO this is just until NVPR is in batch
+            SetState* ss = reinterpret_cast<SetState*>(iter.get());
+
+            if (ss->fPrimitiveProcessor) {
+                ss->execute(gpu, currentState);
+            }
+            currentState = ss;
+
+        } else {
+            iter->execute(gpu, currentState);
+        }
+
         if (iter->isTraced()) {
             gpu->removeGpuTraceMarker(&newMarker);
         }
@@ -212,7 +262,7 @@
     fBatchTarget.postFlush();
 }
 
-void GrTargetCommands::StencilPath::execute(GrGpu* gpu) {
+void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
     GrGpu::StencilPathState state;
     state.fRenderTarget = fRenderTarget.get();
     state.fScissor = &fScissor;
@@ -223,36 +273,37 @@
     gpu->stencilPath(this->path(), state);
 }
 
-void GrTargetCommands::DrawPath::execute(GrGpu* gpu) {
-    if (!fState->fCompiled) {
-        gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
-                              fState->fBatchTracker);
-        fState->fCompiled = true;
-    }
-    DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
-                  &fState->fDesc, &fState->fBatchTracker);
+void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) {
+    SkASSERT(state);
+    DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
+                  &state->fBatchTracker);
     gpu->drawPath(args, this->path(), fStencilSettings);
 }
 
-void GrTargetCommands::DrawPaths::execute(GrGpu* gpu) {
-    if (!fState->fCompiled) {
-        gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
-                              fState->fBatchTracker);
-        fState->fCompiled = true;
-    }
-    DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
-                  &fState->fDesc, &fState->fBatchTracker);
+void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
+    SkASSERT(state);
+    DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
+                  &state->fBatchTracker);
     gpu->drawPaths(args, this->pathRange(),
                    fIndices, fIndexType,
                    fTransforms, fTransformType,
                    fCount, fStencilSettings);
 }
 
-void GrTargetCommands::DrawBatch::execute(GrGpu*) {
-    fBatchTarget->flushNext(fBatch->numberOfDraws());
+void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) {
+    SkASSERT(state);
+    fBatch->generateGeometry(fBatchTarget, state->getPipeline());
 }
 
-void GrTargetCommands::Clear::execute(GrGpu* gpu) {
+void GrTargetCommands::SetState::execute(GrGpu* gpu, const SetState*) {
+    // TODO sometimes we have a prim proc, othertimes we have a GrBatch.  Eventually we
+    // will only have GrBatch and we can delete this
+    if (fPrimitiveProcessor) {
+        gpu->buildProgramDesc(&fDesc, *fPrimitiveProcessor, *getPipeline(), fBatchTracker);
+    }
+}
+
+void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
     if (GrColor_ILLEGAL == fColor) {
         gpu->discard(this->renderTarget());
     } else {
@@ -260,15 +311,15 @@
     }
 }
 
-void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu) {
+void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
     gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
 }
 
-void GrTargetCommands::CopySurface::execute(GrGpu* gpu) {
+void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
     gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
 }
 
-void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) {
+void GrTargetCommands::XferBarrier::execute(GrGpu* gpu, const SetState* state) {
     gpu->xferBarrier(fBarrierType);
 }
 
@@ -282,10 +333,65 @@
     return cs;
 }
 
-void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline,
-                                                    GrInOrderDrawBuffer* iodb) {
-    const GrXferProcessor& xp = *pipeline.getXferProcessor();
-    GrRenderTarget* rt = pipeline.getRenderTarget();
+bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
+                                                  const GrPrimitiveProcessor* primProc,
+                                                  const GrDrawTarget::PipelineInfo& pipelineInfo) {
+    SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
+    iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); 
+
+    if (ss->getPipeline()->mustSkip()) {
+        fCmdBuffer.pop_back();
+        return false;
+    }
+
+    ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
+                                              ss->getPipeline()->getInitBatchTracker());
+
+    if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
+        fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
+                                                      *ss->fPrimitiveProcessor,
+                                                      ss->fBatchTracker) &&
+        fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
+        fCmdBuffer.pop_back();
+    } else {
+        fPrevState = ss;
+        iodb->recordTraceMarkersIfNecessary(ss);
+    }
+
+    this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
+    return true;
+}
+
+bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
+                                                  GrBatch* batch,
+                                                  const GrDrawTarget::PipelineInfo& pipelineInfo) {
+    SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
+    iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); 
+
+    if (ss->getPipeline()->mustSkip()) {
+        fCmdBuffer.pop_back();
+        return false;
+    }
+
+    batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
+
+    if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
+        fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
+        fCmdBuffer.pop_back();
+    } else {
+        fPrevState = ss;
+        iodb->recordTraceMarkersIfNecessary(ss);
+    }
+
+    this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
+    return true;
+}
+
+void GrTargetCommands::recordXferBarrierIfNecessary(GrInOrderDrawBuffer* iodb,
+                                                    const GrDrawTarget::PipelineInfo& info) {
+    SkASSERT(fPrevState);
+    const GrXferProcessor& xp = *fPrevState->getXferProcessor();
+    GrRenderTarget* rt = fPrevState->getRenderTarget();
 
     GrXferBarrierType barrierType;
     if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) {