Refactor DrawTarget and GPU to be independent
authorjoshualitt <joshualitt@chromium.org>
Fri, 7 Nov 2014 16:48:51 +0000 (08:48 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 7 Nov 2014 16:48:51 +0000 (08:48 -0800)
BUG=skia:

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

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

index a456a799c89af7f1388a68e5919151eebd093d05..83ef58f3debb4c6d642068c249d2431d0bba4ee7 100755 (executable)
@@ -213,7 +213,6 @@ void GrContext::resetContext(uint32_t state) {
 void GrContext::freeGpuResources() {
     this->flush();
 
-    fGpu->purgeResources();
     if (fDrawBuffer) {
         fDrawBuffer->purgeResources();
     }
index 60ce788e6277968431416cf043d36f927ee5888b..74be6460e106bffb00af354426333cf39562a071 100644 (file)
@@ -32,9 +32,6 @@ class GrPathRange;
 class GrVertexBuffer;
 
 class GrDrawTarget : public SkRefCnt {
-protected:
-    class DrawInfo;
-
 public:
     SK_DECLARE_INST_COUNT(GrDrawTarget)
 
@@ -460,6 +457,7 @@ public:
      */
     virtual void purgeResources() {};
 
+    class DrawInfo;
     /**
      * For subclass internal use to invoke a call to onDraw(). See DrawInfo below.
      */
@@ -690,6 +688,73 @@ public:
 
     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
 
+    /**
+     * Used to communicate draws to GPUs / subclasses
+     */
+    class DrawInfo {
+    public:
+        DrawInfo(const DrawInfo& di) { (*this) = di; }
+        DrawInfo& operator =(const DrawInfo& di);
+
+        GrPrimitiveType primitiveType() const { return fPrimitiveType; }
+        int startVertex() const { return fStartVertex; }
+        int startIndex() const { return fStartIndex; }
+        int vertexCount() const { return fVertexCount; }
+        int indexCount() const { return fIndexCount; }
+        int verticesPerInstance() const { return fVerticesPerInstance; }
+        int indicesPerInstance() const { return fIndicesPerInstance; }
+        int instanceCount() const { return fInstanceCount; }
+
+        bool isIndexed() const { return fIndexCount > 0; }
+#ifdef SK_DEBUG
+        bool isInstanced() const; // this version is longer because of asserts
+#else
+        bool isInstanced() const { return fInstanceCount > 0; }
+#endif
+
+        // adds or remove instances
+        void adjustInstanceCount(int instanceOffset);
+        // shifts the start vertex
+        void adjustStartVertex(int vertexOffset);
+        // shifts the start index
+        void adjustStartIndex(int indexOffset);
+
+        void setDevBounds(const SkRect& bounds) {
+            fDevBoundsStorage = bounds;
+            fDevBounds = &fDevBoundsStorage;
+        }
+        const SkRect* getDevBounds() const { return fDevBounds; }
+
+        // NULL if no copy of the dst is needed for the draw.
+        const GrDeviceCoordTexture* getDstCopy() const {
+            if (fDstCopy.texture()) {
+                return &fDstCopy;
+            } else {
+                return NULL;
+            }
+        }
+
+    private:
+        DrawInfo() { fDevBounds = NULL; }
+
+        friend class GrDrawTarget;
+
+        GrPrimitiveType         fPrimitiveType;
+
+        int                     fStartVertex;
+        int                     fStartIndex;
+        int                     fVertexCount;
+        int                     fIndexCount;
+
+        int                     fInstanceCount;
+        int                     fVerticesPerInstance;
+        int                     fIndicesPerInstance;
+
+        SkRect                  fDevBoundsStorage;
+        SkRect*                 fDevBounds;
+
+        GrDeviceCoordTexture    fDstCopy;
+    };
 
     bool programUnitTest(int maxStages);
 
@@ -766,74 +831,6 @@ protected:
 
     const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
 
-    /**
-     * Used to communicate draws to subclass's onDraw function.
-     */
-    class DrawInfo {
-    public:
-        DrawInfo(const DrawInfo& di) { (*this) = di; }
-        DrawInfo& operator =(const DrawInfo& di);
-
-        GrPrimitiveType primitiveType() const { return fPrimitiveType; }
-        int startVertex() const { return fStartVertex; }
-        int startIndex() const { return fStartIndex; }
-        int vertexCount() const { return fVertexCount; }
-        int indexCount() const { return fIndexCount; }
-        int verticesPerInstance() const { return fVerticesPerInstance; }
-        int indicesPerInstance() const { return fIndicesPerInstance; }
-        int instanceCount() const { return fInstanceCount; }
-
-        bool isIndexed() const { return fIndexCount > 0; }
-#ifdef SK_DEBUG
-        bool isInstanced() const; // this version is longer because of asserts
-#else
-        bool isInstanced() const { return fInstanceCount > 0; }
-#endif
-
-        // adds or remove instances
-        void adjustInstanceCount(int instanceOffset);
-        // shifts the start vertex
-        void adjustStartVertex(int vertexOffset);
-        // shifts the start index
-        void adjustStartIndex(int indexOffset);
-
-        void setDevBounds(const SkRect& bounds) {
-            fDevBoundsStorage = bounds;
-            fDevBounds = &fDevBoundsStorage;
-        }
-        const SkRect* getDevBounds() const { return fDevBounds; }
-
-        // NULL if no copy of the dst is needed for the draw.
-        const GrDeviceCoordTexture* getDstCopy() const {
-            if (fDstCopy.texture()) {
-                return &fDstCopy;
-            } else {
-                return NULL;
-            }
-        }
-
-    private:
-        DrawInfo() { fDevBounds = NULL; }
-
-        friend class GrDrawTarget;
-
-        GrPrimitiveType         fPrimitiveType;
-
-        int                     fStartVertex;
-        int                     fStartIndex;
-        int                     fVertexCount;
-        int                     fIndexCount;
-
-        int                     fInstanceCount;
-        int                     fVerticesPerInstance;
-        int                     fIndicesPerInstance;
-
-        SkRect                  fDevBoundsStorage;
-        SkRect*                 fDevBounds;
-
-        GrDeviceCoordTexture    fDstCopy;
-    };
-
     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
     // needs to be accessed by GLPrograms to setup a correct drawstate
@@ -929,6 +926,10 @@ private:
     GrTraceMarkerSet                                                fActiveTraceMarkers;
     GrTraceMarkerSet                                                fStoredTraceMarkers;
 
+    // TODO fix this
+    friend class GrGpu;
+    friend class GrGpuGL;
+
     typedef SkRefCnt INHERITED;
 };
 
index 2a1f5b6331d79327eb72b12be4b276b13dfe389f..47863bb6fcf56848248b56f8e8816a00eceecd57 100644 (file)
@@ -28,15 +28,18 @@ static const int INDEX_POOL_IB_COUNT = 4;
 #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 @@ GrGpu::GrGpu(GrContext* context)
     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 @@ GrGpu::~GrGpu() {
     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 @@ GrIndexBuffer* GrGpu::createInstancedIndexBuffer(const uint16_t* pattern,
     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 @@ void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
     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 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
 ////////////////////////////////////////////////////////////////////////////////
 
 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 @@ void GrGpu::geometrySourceWillPush() {
 #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 @@ void GrGpu::onDrawPath(const GrPath* path,
                        const GrDeviceCoordTexture* dstCopy) {
     this->handleDirtyContext();
 
-    drawState()->setDefaultVertexAttribs();
-
     if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
         return;
     }
@@ -333,14 +462,12 @@ void GrGpu::onDrawPaths(const GrPathRange* pathRange,
                         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 @@ bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
 }
 
 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();
+}
index 9139405cf5adb6c039f7a69b269bb8bb966e18c7..02fc75e5545a54595e3355bcbb232dca4c1f5d89 100644 (file)
@@ -22,7 +22,7 @@ class GrPathRendererChain;
 class GrStencilBuffer;
 class GrVertexBufferAllocPool;
 
-class GrGpu : public GrClipTarget {
+class GrGpu : public SkRefCnt {
 public:
 
     /**
@@ -52,8 +52,32 @@ public:
     GrGpu(GrContext* context);
     virtual ~GrGpu();
 
-    GrContext* getContext() { return this->INHERITED::getContext(); }
-    const GrContext* getContext() const { return this->INHERITED::getContext(); }
+    GrContext* getContext() { return fContext; }
+    const GrContext* getContext() const { return fContext; }
+
+    /**
+     * Gets the capabilities of the draw target.
+     */
+    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();
@@ -265,10 +289,33 @@ public:
                             GrPixelConfig config, const void* buffer,
                             size_t rowBytes);
 
-    // GrDrawTarget overrides
-    virtual void clearStencilClip(const SkIRect& rect,
-                                  bool insideClip,
-                                  GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
+    /**
+     * Clear the passed in render target. Ignores the draw state and clip. Clears the whole thing if
+     * rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
+     * can be optionally cleared.
+     */
+    void clear(const SkIRect* rect,
+               GrColor color,
+               bool canIgnoreRect,
+               GrRenderTarget* renderTarget);
+
+
+    void clearStencilClip(const SkIRect& rect,
+                          bool insideClip,
+                          GrRenderTarget* renderTarget = NULL);
+
+    /**
+     * Discards the contents render target. NULL indicates that the current render target should
+     * be discarded.
+     **/
+    virtual void discard(GrRenderTarget* = NULL) = 0;
+
+    /**
+     * This is can be called before allocating a texture to be a dst for copySurface. It will
+     * populate the origin, config, and flags fields of the desc such that copySurface is more
+     * likely to succeed and be efficient.
+     */
+    virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc);
 
     // After the client interacts directly with the 3D context state the GrGpu
     // must resync its internal state and assumptions about 3D context state.
@@ -308,6 +355,99 @@ public:
                                   const GrDeviceCoordTexture* dstCopy,
                                   GrProgramDesc*) = 0;
 
+    /**
+     * Called at start and end of gpu trace marking
+     * GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
+     * and end of a code block respectively
+     */
+    void addGpuTraceMarker(const GrGpuTraceMarker* marker);
+    void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
+
+    /**
+     * Takes the current active set of markers and stores them for later use. Any current marker
+     * in the active set is removed from the active set and the targets remove function is called.
+     * These functions do not work as a stack so you cannot call save a second time before calling
+     * restore. Also, it is assumed that when restore is called the current active set of markers
+     * is empty. When the stored markers are added back into the active set, the targets add marker
+     * is called.
+     */
+    void saveActiveTraceMarkers();
+    void restoreActiveTraceMarkers();
+
+    /**
+     * Query to find out if the vertex or index source is reserved.
+     */
+    bool hasReservedVerticesOrIndices() const {
+        return GrDrawTarget::kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc ||
+               GrDrawTarget::kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
+    }
+
+    // Called to determine whether an onCopySurface call would succeed or not. This is useful for
+    // proxy subclasses to test whether the copy would succeed without executing it yet. Derived
+    // classes must keep this consistent with their implementation of onCopySurface(). The inputs
+    // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src
+    // and dst bounds.
+    virtual bool canCopySurface(GrSurface* dst,
+                                GrSurface* src,
+                                const SkIRect& srcRect,
+                                const SkIPoint& dstPoint) = 0;
+
+    // This method is called by copySurface  The srcRect is guaranteed to be entirely within the
+    // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls
+    // entirely within the dst. The default implementation will draw a rect from the src to the
+    // dst if the src is a texture and the dst is a render target and fail otherwise.
+    virtual bool copySurface(GrSurface* dst,
+                             GrSurface* src,
+                             const SkIRect& srcRect,
+                             const SkIPoint& dstPoint) = 0;
+
+    /**
+     * Sets source of vertex data for the next draw. Data does not have to be
+     * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances.
+     *
+     * @param buffer        vertex buffer containing vertex data. Must be
+     *                      unlocked before draw call. Vertex size is queried
+     *                      from current GrDrawState.
+     */
+    void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
+
+    /**
+     * Sets source of index data for the next indexed draw. Data does not have
+     * to be in the buffer until drawIndexed.
+     *
+     * @param buffer index buffer containing indices. Must be unlocked
+     *               before indexed draw call.
+     */
+    void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+    /**
+     * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
+     * source to reserved, array, or buffer before next draw. May be able to free
+     * up temporary storage allocated by setVertexSourceToArray or
+     * reserveVertexSpace.
+     */
+    void resetVertexSource();
+
+    /**
+     * Resets index source. Indexed Drawing from reset indices is illegal. Set
+     * index source to reserved, array, or buffer before next indexed draw. May
+     * be able to free up temporary storage allocated by setIndexSourceToArray
+     * or reserveIndexSpace.
+     */
+    void resetIndexSource();
+
+    /**
+     * Pushes and resets the vertex/index sources. Any reserved vertex / index
+     * data is finalized (i.e. cannot be updated after the matching pop but can
+     * be drawn from). Must be balanced by a pop.
+     */
+    void pushGeometrySource();
+
+    /**
+     * Pops the vertex / index sources from the matching push.
+     */
+    void popGeometrySource();
+
 protected:
     DrawType PrimTypeToDrawType(GrPrimitiveType type) {
         switch (type) {
@@ -337,6 +477,23 @@ protected:
                                           unsigned int* ref,
                                           unsigned int* mask);
 
+    // subclasses must call this in their destructors to ensure all vertex
+    // and index sources have been released (including those held by
+    // pushGeometrySource())
+    void releaseGeometry();
+
+    // accessors for derived classes
+    const GrDrawTarget::GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); }
+
+    // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert.
+    size_t getVertexSize() const {
+        // the vertex layout is only valid if a vertex source has been specified.
+        SkASSERT(this->getGeomSrc().fVertexSrc != GrDrawTarget::kNone_GeometrySrcType);
+        return this->getGeomSrc().fVertexSize;
+    }
+
+    const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
+
     GrContext::GPUStats         fGPUStats;
 
     struct GeometryPoolState {
@@ -356,16 +513,17 @@ protected:
 
     SkAutoTDelete<GrPathRendering> fPathRendering;
 
+    // Subclass must initialize this in its constructor.
+    SkAutoTUnref<const GrDrawTargetCaps> fCaps;
+
 private:
     // GrDrawTarget overrides
-    virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE;
-    virtual bool onReserveIndexSpace(int indexCount, void** indices) SK_OVERRIDE;
-    virtual void releaseReservedVertexSpace() SK_OVERRIDE;
-    virtual void releaseReservedIndexSpace() SK_OVERRIDE;
-    virtual void geometrySourceWillPush() SK_OVERRIDE;
-    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
-    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
-                         GrRenderTarget* renderTarget) SK_OVERRIDE;
+    virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices);
+    virtual bool onReserveIndexSpace(int indexCount, void** indices);
+    virtual void releaseReservedVertexSpace();
+    virtual void releaseReservedIndexSpace();
+    virtual void geometrySourceWillPush();
+    virtual void geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restoredState);
 
     // called when the 3D context state is unknown. Subclass should emit any
     // assumed 3D context state and dirty any state cache.
@@ -394,7 +552,7 @@ private:
                                     bool insideClip) = 0;
 
     // overridden by backend-specific derived class to perform the draw call.
-    virtual void onGpuDraw(const DrawInfo&) = 0;
+    virtual void onGpuDraw(const GrDrawTarget::DrawInfo&) = 0;
 
     // overridden by backend-specific derived class to perform the read pixels.
     virtual bool onReadPixels(GrRenderTarget* target,
@@ -435,22 +593,27 @@ private:
     bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
 
     // GrDrawTarget overrides
-    virtual void onDraw(const DrawInfo&, const GrClipMaskManager::ScissorState&) SK_OVERRIDE;
+    virtual void onDraw(const GrDrawTarget::DrawInfo&,
+                        const GrClipMaskManager::ScissorState&);
     virtual void onStencilPath(const GrPath*,
                                const GrClipMaskManager::ScissorState&,
-                               const GrStencilSettings&) SK_OVERRIDE;
+                               const GrStencilSettings&);
     virtual void onDrawPath(const GrPath*,
                             const GrClipMaskManager::ScissorState&,
                             const GrStencilSettings&,
-                            const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
+                            const GrDeviceCoordTexture* dstCopy);
     virtual void onDrawPaths(const GrPathRange*,
                              const uint32_t indices[],
                              int count,
                              const float transforms[],
-                             PathTransformType,
+                             GrDrawTarget::PathTransformType,
                              const GrClipMaskManager::ScissorState&,
                              const GrStencilSettings&,
-                             const GrDeviceCoordTexture*) SK_OVERRIDE;
+                             const GrDeviceCoordTexture*);
+
+    virtual void didAddGpuTraceMarker() = 0;
+    virtual void didRemoveGpuTraceMarker() = 0;
+
 
     // readies the pools to provide vertex/index data.
     void prepareVertexPool();
@@ -468,6 +631,15 @@ private:
         }
     }
 
+    // called when setting a new vert/idx source to unref prev vb/ib
+    void releasePreviousVertexSource();
+    void releasePreviousIndexSource();
+
+    enum {
+        kPreallocGeoSrcStateStackCnt = 4,
+    };
+    SkSTArray<kPreallocGeoSrcStateStackCnt, GrDrawTarget::GeometrySrcState, true> fGeoSrcStateStack;
+
     enum {
         kPreallocGeomPoolStateStackCnt = 4,
     };
@@ -481,8 +653,19 @@ private:
     int                                                                 fIndexPoolUseCnt;
     // these are mutable so they can be created on-demand
     mutable GrIndexBuffer*                                              fQuadIndexBuffer;
-
-    typedef GrClipTarget INHERITED;
+    GrDrawState                                                     fDefaultDrawState;
+    GrDrawState*                                                        fDrawState;
+    // To keep track that we always have at least as many debug marker adds as removes
+    int                                                                 fGpuTraceMarkerCount;
+    GrTraceMarkerSet                                                    fActiveTraceMarkers;
+    GrTraceMarkerSet                                                    fStoredTraceMarkers;
+    // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu.
+    GrContext*                                                          fContext;
+
+    // TODO fix this
+    friend class GrInOrderDrawBuffer;
+
+    typedef SkRefCnt INHERITED;
 };
 
 #endif
index d9926fd50aa7694c496b921bd85ad4fb16b160d0..f1031ce17cbfa8c30456a5b504a4840b2114f53f 100644 (file)
@@ -468,34 +468,34 @@ void GrInOrderDrawBuffer::flush() {
     ++fDrawID;
 }
 
-void GrInOrderDrawBuffer::Draw::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) {
     gpu->setVertexSourceToBuffer(this->vertexBuffer());
     if (fInfo.isIndexed()) {
         gpu->setIndexSourceToBuffer(this->indexBuffer());
     }
-    gpu->executeDraw(fInfo, fScissorState);
+    gpu->onDraw(fInfo, fScissorState);
 }
 
-void GrInOrderDrawBuffer::StencilPath::execute(GrClipTarget* gpu) {
-    gpu->executeStencilPath(this->path(), fScissorState, fStencilSettings);
+void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) {
+    gpu->onStencilPath(this->path(), fScissorState, fStencilSettings);
 }
 
-void GrInOrderDrawBuffer::DrawPath::execute(GrClipTarget* gpu) {
-    gpu->executeDrawPath(this->path(), fScissorState, fStencilSettings,
+void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) {
+    gpu->onDrawPath(this->path(), fScissorState, fStencilSettings,
                          fDstCopy.texture() ? &fDstCopy : NULL);
 }
 
-void GrInOrderDrawBuffer::DrawPaths::execute(GrClipTarget* gpu) {
-    gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
+void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) {
+    gpu->onDrawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
                           fTransformsType, fScissorState, fStencilSettings,
                           fDstCopy.texture() ? &fDstCopy : NULL);
 }
 
-void GrInOrderDrawBuffer::SetState::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) {
     gpu->setDrawState(&fState);
 }
 
-void GrInOrderDrawBuffer::Clear::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) {
     if (GrColor_ILLEGAL == fColor) {
         gpu->discard(this->renderTarget());
     } else {
@@ -503,11 +503,11 @@ void GrInOrderDrawBuffer::Clear::execute(GrClipTarget* gpu) {
     }
 }
 
-void GrInOrderDrawBuffer::ClearStencilClip::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) {
         gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
 }
 
-void GrInOrderDrawBuffer::CopySurface::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) {
     gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
 }
 
index 9b4124ab8f341ad1015dead3170449b524907f39..e86a5288d4f80ad4e2a633e1b26be190c46f6892 100644 (file)
@@ -110,7 +110,7 @@ private:
         Cmd(uint8_t type) : fType(type) {}
         virtual ~Cmd() {}
 
-        virtual void execute(GrClipTarget*) = 0;
+        virtual void execute(GrGpu*) = 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(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         DrawInfo     fInfo;
         ScissorState fScissorState;
@@ -144,7 +144,7 @@ private:
 
         const GrPath* path() const { return fPath.get(); }
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         ScissorState      fScissorState;
         GrStencilSettings fStencilSettings;
@@ -158,7 +158,7 @@ private:
 
         const GrPath* path() const { return fPath.get(); }
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         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(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         size_t                  fCount;
         PathTransformType       fTransformsType;
@@ -193,7 +193,7 @@ private:
 
         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         SkIRect fRect;
         GrColor fColor;
@@ -209,7 +209,7 @@ private:
 
         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         SkIRect fRect;
         bool    fInsideClip;
@@ -224,7 +224,7 @@ private:
         GrSurface* dst() const { return fDst.get(); }
         GrSurface* src() const { return fSrc.get(); }
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         SkIPoint    fDstPoint;
         SkIRect     fSrcRect;
@@ -237,7 +237,7 @@ private:
     struct SetState : public Cmd {
         SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {}
 
-        virtual void execute(GrClipTarget*);
+        virtual void execute(GrGpu*);
 
         GrDrawState fState;
     };
@@ -308,7 +308,7 @@ private:
     CmdBuffer                         fCmdBuffer;
     GrDrawState*                      fLastState;
     SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
-    GrClipTarget*                     fDstGpu;
+    GrGpu*                            fDstGpu;
     GrVertexBufferAllocPool&          fVertexPool;
     GrIndexBufferAllocPool&           fIndexPool;
 
index efb37ca88c38ac023c44684a39b02802de68c324..5d31c15c060573d6010fcd2745c40103ed80b79f 100644 (file)
@@ -71,6 +71,16 @@ public:
 
     virtual void discard(GrRenderTarget*) SK_OVERRIDE { }
 
+    virtual bool canCopySurface(GrSurface* dst,
+                                GrSurface* src,
+                                const SkIRect& srcRect,
+                                const SkIPoint& dstPoint) SK_OVERRIDE { return false; };
+
+    virtual bool copySurface(GrSurface* dst,
+                             GrSurface* src,
+                             const SkIRect& srcRect,
+                             const SkIPoint& dstPoint) SK_OVERRIDE { return false; };
+
 private:
     virtual void onResetContext(uint32_t resetBits) { };
     virtual GrTexture* onCreateTexture(const GrSurfaceDesc& desc,
@@ -108,7 +118,7 @@ private:
                                     const SkIRect& rect,
                                     bool insideClip)  SK_OVERRIDE { }
 
-                                    virtual void onGpuDraw(const DrawInfo&)  SK_OVERRIDE { }
+    virtual void onGpuDraw(const GrDrawTarget::DrawInfo&)  SK_OVERRIDE { }
     virtual bool onReadPixels(GrRenderTarget* target,
                               int left, int top, int width, int height,
                               GrPixelConfig,
index 73dd9bb15c1714e62b02d0772499fc72c6575f6c..665785c53c6f0417ab424a35053571504090e90e 100644 (file)
@@ -1731,7 +1731,7 @@ GrGLenum gPrimitiveType2GLMode[] = {
     #endif
 #endif
 
-void GrGpuGL::onGpuDraw(const DrawInfo& info) {
+void GrGpuGL::onGpuDraw(const GrDrawTarget::DrawInfo& info) {
     size_t indexOffsetInBytes;
     this->setupGeometry(info, &indexOffsetInBytes);
 
index 9a491906ba73b2ae427df0cdf69335031d7fb013..bba6400f468ee7cb40f90a14bc21af00dfc76dc9 100644 (file)
@@ -153,7 +153,7 @@ private:
 
     virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
 
-    virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
+    virtual void onGpuDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE;
 
 
     virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
@@ -171,7 +171,7 @@ 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 DrawInfo& info, size_t* indexOffsetInBytes);
+    void setupGeometry(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 96ad411fc7f0c8e75444395352274ffab3400ae0..60692f8fe3ed19dbd79a7ddcb562a6f1c5b8ea11 100644 (file)
@@ -264,7 +264,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
     return true;
 }
 
-void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
+void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes) {
     SkAutoTUnref<GrOptDrawState> optState(
         GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(),
                                PrimTypeToDrawType(info.primitiveType())));
@@ -281,10 +281,10 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
 
     GrGLVertexBuffer* vbuf;
     switch (this->getGeomSrc().fVertexSrc) {
-        case kBuffer_GeometrySrcType:
+        case GrDrawTarget::kBuffer_GeometrySrcType:
             vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
             break;
-        case kReserved_GeometrySrcType:
+        case GrDrawTarget::kReserved_GeometrySrcType:
             this->finalizeReservedVertices();
             vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeomSrc().fVertexSize;
             vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
@@ -303,11 +303,11 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
         SkASSERT(indexOffsetInBytes);
 
         switch (this->getGeomSrc().fIndexSrc) {
-        case kBuffer_GeometrySrcType:
+        case GrDrawTarget::kBuffer_GeometrySrcType:
             *indexOffsetInBytes = 0;
             ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
             break;
-        case kReserved_GeometrySrcType:
+        case GrDrawTarget::kReserved_GeometrySrcType:
             this->finalizeReservedIndices();
             *indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLushort);
             ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;