Refactor DrawTarget and GPU to be independent

BUG=skia:

Review URL: https://codereview.chromium.org/705593002
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 2a1f5b6..47863bb 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -28,15 +28,18 @@
 #define DEBUG_INVAL_START_IDX -1
 
 GrGpu::GrGpu(GrContext* context)
-    : INHERITED(context)
-    , fResetTimestamp(kExpiredTimestamp+1)
+    : fResetTimestamp(kExpiredTimestamp+1)
     , fResetBits(kAll_GrBackendState)
     , fVertexPool(NULL)
     , fIndexPool(NULL)
     , fVertexPoolUseCnt(0)
     , fIndexPoolUseCnt(0)
-    , fQuadIndexBuffer(NULL) {
+    , fQuadIndexBuffer(NULL)
+    , fContext(context) {
     fGeomPoolStateStack.push_back();
+    fDrawState = &fDefaultDrawState;
+    // We assume that fDrawState always owns a ref to the object it points at.
+    fDefaultDrawState.ref();
 #ifdef SK_DEBUG
     GeometryPoolState& poolState = fGeomPoolStateStack.back();
     poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
@@ -44,6 +47,16 @@
     poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
     poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
 #endif
+
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
+#ifdef SK_DEBUG
+    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
+    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
+    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+    geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+    geoSrc.fIndexSrc  = GrDrawTarget::kNone_GeometrySrcType;
 }
 
 GrGpu::~GrGpu() {
@@ -52,6 +65,11 @@
     fVertexPool = NULL;
     delete fIndexPool;
     fIndexPool = NULL;
+    SkASSERT(1 == fGeoSrcStateStack.count());
+    SkDEBUGCODE(GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
+    SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fIndexSrc);
+    SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fVertexSrc);
+    SkSafeUnref(fDrawState);
 }
 
 void GrGpu::contextAbandoned() {}
@@ -194,10 +212,10 @@
     return buffer;
 }
 
-void GrGpu::onClear(const SkIRect* rect,
-                    GrColor color,
-                    bool canIgnoreRect,
-                    GrRenderTarget* renderTarget) {
+void GrGpu::clear(const SkIRect* rect,
+                  GrColor color,
+                  bool canIgnoreRect,
+                  GrRenderTarget* renderTarget) {
     SkASSERT(renderTarget);
     this->handleDirtyContext();
     this->onGpuClear(renderTarget, rect, color, canIgnoreRect);
@@ -241,6 +259,118 @@
     this->onResolveRenderTarget(target);
 }
 
+void GrGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
+    // Make the dst of the copy be a render target because the default copySurface draws to the dst.
+    desc->fOrigin = kDefault_GrSurfaceOrigin;
+    desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+    desc->fConfig = src->config();
+}
+
+typedef GrTraceMarkerSet::Iter TMIter;
+void GrGpu::saveActiveTraceMarkers() {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(0 == fStoredTraceMarkers.count());
+        fStoredTraceMarkers.addSet(fActiveTraceMarkers);
+        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+            this->removeGpuTraceMarker(&(*iter));
+        }
+    }
+}
+
+void GrGpu::restoreActiveTraceMarkers() {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(0 == fActiveTraceMarkers.count());
+        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+            this->addGpuTraceMarker(&(*iter));
+        }
+        for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
+            this->fStoredTraceMarkers.remove(*iter);
+        }
+    }
+}
+
+void GrGpu::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(fGpuTraceMarkerCount >= 0);
+        this->fActiveTraceMarkers.add(*marker);
+        this->didAddGpuTraceMarker();
+        ++fGpuTraceMarkerCount;
+    }
+}
+
+void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(fGpuTraceMarkerCount >= 1);
+        this->fActiveTraceMarkers.remove(*marker);
+        this->didRemoveGpuTraceMarker();
+        --fGpuTraceMarkerCount;
+    }
+}
+
+void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
+    this->releasePreviousVertexSource();
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fVertexSrc    = GrDrawTarget::kBuffer_GeometrySrcType;
+    geoSrc.fVertexBuffer = buffer;
+    buffer->ref();
+    geoSrc.fVertexSize = this->drawState()->getVertexStride();
+}
+
+void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
+    this->releasePreviousIndexSource();
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fIndexSrc     = GrDrawTarget::kBuffer_GeometrySrcType;
+    geoSrc.fIndexBuffer  = buffer;
+    buffer->ref();
+}
+
+void GrGpu::setDrawState(GrDrawState*  drawState) {
+    SkASSERT(fDrawState);
+    if (NULL == drawState) {
+        drawState = &fDefaultDrawState;
+    }
+    if (fDrawState != drawState) {
+        fDrawState->unref();
+        drawState->ref();
+        fDrawState = drawState;
+    }
+}
+
+void GrGpu::resetVertexSource() {
+    this->releasePreviousVertexSource();
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+}
+
+void GrGpu::resetIndexSource() {
+    this->releasePreviousIndexSource();
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
+}
+
+void GrGpu::pushGeometrySource() {
+    this->geometrySourceWillPush();
+    GrDrawTarget::GeometrySrcState& newState = fGeoSrcStateStack.push_back();
+    newState.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
+    newState.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+#ifdef SK_DEBUG
+    newState.fVertexCount  = ~0;
+    newState.fVertexBuffer = (GrVertexBuffer*)~0;
+    newState.fIndexCount   = ~0;
+    newState.fIndexBuffer = (GrIndexBuffer*)~0;
+#endif
+}
+
+void GrGpu::popGeometrySource() {
+    // if popping last element then pops are unbalanced with pushes
+    SkASSERT(fGeoSrcStateStack.count() > 1);
+
+    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
+    this->releasePreviousVertexSource();
+    this->releasePreviousIndexSource();
+    fGeoSrcStateStack.pop_back();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
@@ -267,11 +397,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrGpu::geometrySourceWillPush() {
-    const GeometrySrcState& geoSrc = this->getGeomSrc();
-    if (kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
+    const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+    if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
         this->finalizeReservedVertices();
     }
-    if (kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
+    if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
         this->finalizeReservedIndices();
     }
     GeometryPoolState& newState = fGeomPoolStateStack.push_back();
@@ -285,13 +415,14 @@
 #endif
 }
 
-void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
+void GrGpu::geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restoredState) {
     // if popping last entry then pops are unbalanced with pushes
     SkASSERT(fGeomPoolStateStack.count() > 1);
     fGeomPoolStateStack.pop_back();
 }
 
-void GrGpu::onDraw(const DrawInfo& info, const GrClipMaskManager::ScissorState& scissorState) {
+void GrGpu::onDraw(const GrDrawTarget::DrawInfo& info,
+                   const GrClipMaskManager::ScissorState& scissorState) {
     this->handleDirtyContext();
     if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()),
                                   scissorState,
@@ -320,8 +451,6 @@
                        const GrDeviceCoordTexture* dstCopy) {
     this->handleDirtyContext();
 
-    drawState()->setDefaultVertexAttribs();
-
     if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
         return;
     }
@@ -333,14 +462,12 @@
                         const uint32_t indices[],
                         int count,
                         const float transforms[],
-                        PathTransformType transformsType,
+                        GrDrawTarget::PathTransformType transformsType,
                         const GrClipMaskManager::ScissorState& scissorState,
                         const GrStencilSettings& stencilSettings,
                         const GrDeviceCoordTexture* dstCopy) {
     this->handleDirtyContext();
 
-    drawState()->setDefaultVertexAttribs();
-
     if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) {
         return;
     }
@@ -426,17 +553,67 @@
 }
 
 void GrGpu::releaseReservedVertexSpace() {
-    const GeometrySrcState& geoSrc = this->getGeomSrc();
-    SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+    const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+    SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc);
     size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize;
     fVertexPool->putBack(bytes);
     --fVertexPoolUseCnt;
 }
 
 void GrGpu::releaseReservedIndexSpace() {
-    const GeometrySrcState& geoSrc = this->getGeomSrc();
-    SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+    const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+    SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc);
     size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
     fIndexPool->putBack(bytes);
     --fIndexPoolUseCnt;
 }
+
+void GrGpu::releasePreviousVertexSource() {
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    switch (geoSrc.fVertexSrc) {
+        case GrDrawTarget::kNone_GeometrySrcType:
+            break;
+        case GrDrawTarget::kReserved_GeometrySrcType:
+            this->releaseReservedVertexSpace();
+            break;
+        case GrDrawTarget::kBuffer_GeometrySrcType:
+            geoSrc.fVertexBuffer->unref();
+#ifdef SK_DEBUG
+            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+            break;
+        default:
+            SkFAIL("Unknown Vertex Source Type.");
+            break;
+    }
+}
+
+void GrGpu::releasePreviousIndexSource() {
+    GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    switch (geoSrc.fIndexSrc) {
+        case GrDrawTarget::kNone_GeometrySrcType:   // these two don't require
+            break;
+        case GrDrawTarget::kReserved_GeometrySrcType:
+            this->releaseReservedIndexSpace();
+            break;
+        case GrDrawTarget::kBuffer_GeometrySrcType:
+            geoSrc.fIndexBuffer->unref();
+#ifdef SK_DEBUG
+            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+            break;
+        default:
+            SkFAIL("Unknown Index Source Type.");
+            break;
+    }
+}
+
+void GrGpu::releaseGeometry() {
+    int popCnt = fGeoSrcStateStack.count() - 1;
+    while (popCnt) {
+        this->popGeometrySource();
+        --popCnt;
+    }
+    this->resetVertexSource();
+    this->resetIndexSource();
+}