Make GrIODB keep pending IO refs on all resources it records into its cmd stream.

BUG=skia:2889
R=robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/581123002
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 1f2692d..efbe861 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -11,13 +11,8 @@
 #include "GrDrawTargetCaps.h"
 #include "GrTextStrike.h"
 #include "GrGpu.h"
-#include "GrIndexBuffer.h"
-#include "GrPath.h"
-#include "GrPathRange.h"
-#include "GrRenderTarget.h"
 #include "GrTemplates.h"
 #include "GrTexture.h"
-#include "GrVertexBuffer.h"
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
                                          GrVertexBufferAllocPool* vertexPool,
@@ -239,15 +234,15 @@
         return 0;
     }
 
-    DrawRecord* draw = &fDraws.back();
+    Draw* draw = &fDraws.back();
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
 
     if (!draw->isInstanced() ||
         draw->verticesPerInstance() != info.verticesPerInstance() ||
         draw->indicesPerInstance() != info.indicesPerInstance() ||
-        draw->fVertexBuffer != vertexBuffer ||
-        draw->fIndexBuffer != geomSrc.fIndexBuffer) {
+        draw->vertexBuffer() != vertexBuffer ||
+        draw->indexBuffer() != geomSrc.fIndexBuffer) {
         return 0;
     }
     // info does not yet account for the offset from the start of the pool's VB while the previous
@@ -319,68 +314,47 @@
     }
     this->recordStateIfNecessary();
 
-    DrawRecord* draw;
+    const GrVertexBuffer* vb;
+    if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
+        vb = this->getGeomSrc().fVertexBuffer;
+    } else {
+        vb = poolState.fPoolVertexBuffer;
+    }
+
+    const GrIndexBuffer* ib = NULL;
+    if (info.isIndexed()) {
+        if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
+            ib = this->getGeomSrc().fIndexBuffer;
+        } else {
+            ib = poolState.fPoolIndexBuffer;
+        }
+    }
+
+    Draw* draw;
     if (info.isInstanced()) {
         int instancesConcated = this->concatInstancedDraw(info);
         if (info.instanceCount() > instancesConcated) {
-            draw = this->recordDraw(info);
+            draw = this->recordDraw(info, vb, ib);
             draw->adjustInstanceCount(-instancesConcated);
         } else {
             return;
         }
     } else {
-        draw = this->recordDraw(info);
+        draw = this->recordDraw(info, vb, ib);
     }
 
-    switch (this->getGeomSrc().fVertexSrc) {
-        case kBuffer_GeometrySrcType:
-            draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
-            break;
-        case kReserved_GeometrySrcType: // fallthrough
-        case kArray_GeometrySrcType: {
-            size_t vertexBytes = (info.vertexCount() + info.startVertex()) *
-                                 drawState.getVertexStride();
-            poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
-            draw->fVertexBuffer = poolState.fPoolVertexBuffer;
-            draw->adjustStartVertex(poolState.fPoolStartVertex);
-            break;
-        }
-        default:
-            SkFAIL("unknown geom src type");
+    // Adjust the starting vertex and index when we are using reserved or array sources to
+    // compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
+    if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
+        size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
+        poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
+        draw->adjustStartVertex(poolState.fPoolStartVertex);
     }
-    draw->fVertexBuffer->ref();
-
-    if (info.isIndexed()) {
-        switch (this->getGeomSrc().fIndexSrc) {
-            case kBuffer_GeometrySrcType:
-                draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
-                break;
-            case kReserved_GeometrySrcType: // fallthrough
-            case kArray_GeometrySrcType: {
-                size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
-                poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, indexBytes);
-                draw->fIndexBuffer = poolState.fPoolIndexBuffer;
-                draw->adjustStartIndex(poolState.fPoolStartIndex);
-                break;
-            }
-            default:
-                SkFAIL("unknown geom src type");
-        }
-        draw->fIndexBuffer->ref();
-    } else {
-        draw->fIndexBuffer = NULL;
-    }
-}
-
-GrInOrderDrawBuffer::StencilPath::StencilPath() {}
-GrInOrderDrawBuffer::DrawPath::DrawPath() {}
-GrInOrderDrawBuffer::DrawPaths::DrawPaths() {}
-GrInOrderDrawBuffer::DrawPaths::~DrawPaths() {
-    if (fTransforms) {
-        SkDELETE_ARRAY(fTransforms);
-    }
-    if (fIndices) {
-        SkDELETE_ARRAY(fIndices);
+    
+    if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndexSrc) {
+        size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
+        poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes);
+        draw->adjustStartIndex(poolState.fPoolStartIndex);
     }
 }
 
@@ -390,9 +364,7 @@
     }
     // Only compare the subset of GrDrawState relevant to path stenciling?
     this->recordStateIfNecessary();
-    StencilPath* sp = this->recordStencilPath();
-    sp->fPath.reset(path);
-    path->ref();
+    StencilPath* sp = this->recordStencilPath(path);
     sp->fFill = fill;
 }
 
@@ -403,9 +375,7 @@
     }
     // TODO: Only compare the subset of GrDrawState relevant to path covering?
     this->recordStateIfNecessary();
-    DrawPath* cp = this->recordDrawPath();
-    cp->fPath.reset(path);
-    path->ref();
+    DrawPath* cp = this->recordDrawPath(path);
     cp->fFill = fill;
     if (dstCopy) {
         cp->fDstCopy = *dstCopy;
@@ -424,8 +394,7 @@
         this->recordClip();
     }
     this->recordStateIfNecessary();
-    DrawPaths* dp = this->recordDrawPaths();
-    dp->fPathRange.reset(SkRef(pathRange));
+    DrawPaths* dp = this->recordDrawPaths(pathRange);
     dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this without a malloc
     memcpy(dp->fIndices, indices, sizeof(uint32_t) * count);
     dp->fCount = count;
@@ -456,13 +425,11 @@
         r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
         rect = &r;
     }
-    Clear* clr = this->recordClear();
+    Clear* clr = this->recordClear(renderTarget);
     GrColorIsPMAssert(color);
     clr->fColor = color;
     clr->fRect = *rect;
     clr->fCanIgnoreRect = canIgnoreRect;
-    clr->fRenderTarget = renderTarget;
-    renderTarget->ref();
 }
 
 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
@@ -473,10 +440,8 @@
         renderTarget = this->drawState()->getRenderTarget();
         SkASSERT(renderTarget);
     }
-    Clear* clr = this->recordClear();
+    Clear* clr = this->recordClear(renderTarget);
     clr->fColor = GrColor_ILLEGAL;
-    clr->fRenderTarget = renderTarget;
-    renderTarget->ref();
 }
 
 void GrInOrderDrawBuffer::reset() {
@@ -484,13 +449,6 @@
     this->resetVertexSource();
     this->resetIndexSource();
         
-    DrawAllocator::Iter drawIter(&fDraws);
-    while (drawIter.next()) {
-        // we always have a VB, but not always an IB
-        SkASSERT(drawIter->fVertexBuffer);
-        drawIter->fVertexBuffer->unref();
-        SkSafeUnref(drawIter->fIndexBuffer);
-    }
     fCmds.reset();
     fDraws.reset();
     fStencilPaths.reset();
@@ -559,9 +517,9 @@
             case kDraw_Cmd: {
                 SkASSERT(fDstGpu->drawState() != prevDrawState);
                 SkAssertResult(drawIter.next());
-                fDstGpu->setVertexSourceToBuffer(drawIter->fVertexBuffer);
+                fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer());
                 if (drawIter->isIndexed()) {
-                    fDstGpu->setIndexSourceToBuffer(drawIter->fIndexBuffer);
+                    fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer());
                 }
                 fDstGpu->executeDraw(*drawIter);
                 break;
@@ -569,13 +527,13 @@
             case kStencilPath_Cmd: {
                 SkASSERT(fDstGpu->drawState() != prevDrawState);
                 SkAssertResult(stencilPathIter.next());
-                fDstGpu->stencilPath(stencilPathIter->fPath.get(), stencilPathIter->fFill);
+                fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->fFill);
                 break;
             }
             case kDrawPath_Cmd: {
                 SkASSERT(fDstGpu->drawState() != prevDrawState);
                 SkAssertResult(drawPathIter.next());
-                fDstGpu->executeDrawPath(drawPathIter->fPath.get(), drawPathIter->fFill,
+                fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFill,
                                          drawPathIter->fDstCopy.texture() ?
                                             &drawPathIter->fDstCopy :
                                             NULL);
@@ -586,7 +544,7 @@
                 SkAssertResult(drawPathsIter.next());
                 const GrDeviceCoordTexture* dstCopy =
                     drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy : NULL;
-                fDstGpu->executeDrawPaths(drawPathsIter->fPathRange.get(),
+                fDstGpu->executeDrawPaths(drawPathsIter->pathRange(),
                                           drawPathsIter->fIndices,
                                           drawPathsIter->fCount,
                                           drawPathsIter->fTransforms,
@@ -608,18 +566,18 @@
             case kClear_Cmd:
                 SkAssertResult(clearIter.next());
                 if (GrColor_ILLEGAL == clearIter->fColor) {
-                    fDstGpu->discard(clearIter->fRenderTarget);
+                    fDstGpu->discard(clearIter->renderTarget());
                 } else {
                     fDstGpu->clear(&clearIter->fRect,
                                    clearIter->fColor,
                                    clearIter->fCanIgnoreRect,
-                                   clearIter->fRenderTarget);
+                                   clearIter->renderTarget());
                 }
                 break;
             case kCopySurface_Cmd:
                 SkAssertResult(copySurfaceIter.next());
-                fDstGpu->copySurface(copySurfaceIter->fDst.get(),
-                                     copySurfaceIter->fSrc.get(),
+                fDstGpu->copySurface(copySurfaceIter->dst(),
+                                     copySurfaceIter->src(),
                                      copySurfaceIter->fSrcRect,
                                      copySurfaceIter->fDstPoint);
                 break;
@@ -652,9 +610,7 @@
                                         const SkIRect& srcRect,
                                         const SkIPoint& dstPoint) {
     if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
-        CopySurface* cs = this->recordCopySurface();
-        cs->fDst.reset(SkRef(dst));
-        cs->fSrc.reset(SkRef(src));
+        CopySurface* cs = this->recordCopySurface(dst, src);
         cs->fSrcRect = srcRect;
         cs->fDstPoint = dstPoint;
         return true;
@@ -805,9 +761,7 @@
     poolState.fPoolStartIndex = 0;
 }
 
-void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
-                                                   int vertexCount) {
-
+void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
     SkASSERT(0 == poolState.fUsedPoolVertexBytes);
 #ifdef SK_DEBUG
@@ -859,8 +813,7 @@
 #endif
 }
 
-void GrInOrderDrawBuffer::geometrySourceWillPop(
-                                        const GeometrySrcState& restoredState) {
+void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
     SkASSERT(fGeoPoolStateStack.count() > 1);
     fGeoPoolStateStack.pop_back();
     GeometryPoolState& poolState = fGeoPoolStateStack.back();
@@ -934,34 +887,37 @@
     this->addToCmdBuffer(kSetClip_Cmd);
 }
 
-GrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) {
+GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info,
+                                                           const GrVertexBuffer* vb,
+                                                           const GrIndexBuffer* ib) {
     this->addToCmdBuffer(kDraw_Cmd);
-    return &fDraws.push_back(info);
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib));
 }
 
-GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
+GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const GrPath* path) {
     this->addToCmdBuffer(kStencilPath_Cmd);
-    return &fStencilPaths.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path));
 }
 
-GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath() {
+GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath* path) {
     this->addToCmdBuffer(kDrawPath_Cmd);
-    return &fDrawPath.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path));
 }
 
-GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths() {
+GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPathRange* pathRange) {
     this->addToCmdBuffer(kDrawPaths_Cmd);
-    return &fDrawPaths.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange));
 }
 
-GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
+GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt) {
     this->addToCmdBuffer(kClear_Cmd);
-    return &fClears.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt));
 }
 
-GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface() {
+GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurface* dst,
+                                                                         GrSurface* src) {
     this->addToCmdBuffer(kCopySurface_Cmd);
-    return &fCopySurfaces.push_back();
+    return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src));
 }
 
 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {