Decrease GrInOrderDrawBuffer::Cmd's reliance on GrInOrderDrawBuffer
authorrobertphillips <robertphillips@google.com>
Fri, 27 Feb 2015 16:50:34 +0000 (08:50 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 27 Feb 2015 16:50:34 +0000 (08:50 -0800)
Review URL: https://codereview.chromium.org/940533003

src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h

index 0f10623..0807bf3 100644 (file)
@@ -21,15 +21,14 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
     : INHERITED(gpu, vertexPool, indexPool)
     , fCmdBuffer(kCmdBufferInitialSizeInBytes)
     , fPrevState(NULL)
+    , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
+    , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
     , fDrawID(0)
     , fBatchTarget(gpu, vertexPool, indexPool)
     , fDrawBatch(NULL) {
 
     SkASSERT(vertexPool);
     SkASSERT(indexPool);
-
-    fPathIndexBuffer.setReserve(kPathIdxBufferMinReserve);
-    fPathTransformBuffer.setReserve(kPathXformBufferMinReserve);
 }
 
 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
@@ -76,19 +75,6 @@ static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
     return isWinding;
 }
 
-template<typename T> static void reset_data_buffer(SkTDArray<T>* buffer, int minReserve) {
-    // Assume the next time this buffer fills up it will use approximately the same amount
-    // of space as last time. Only resize if we're using less than a third of the
-    // allocated space, and leave enough for 50% growth over last time.
-    if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minReserve) {
-        int reserve = SkTMax(minReserve, buffer->count() * 3 / 2);
-        buffer->reset();
-        buffer->setReserve(reserve);
-    } else {
-        buffer->rewind();
-    }
-}
-
 class RectBatch : public GrBatch {
 public:
     struct Geometry {
@@ -413,7 +399,7 @@ void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
 
     // Check if there is a Batch Draw we can batch with
     if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
-        fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
+        fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
         return;
     }
 
@@ -422,7 +408,7 @@ void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
         return;
     } else {
         this->closeBatch();
-        fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
+        fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
     }
     this->recordTraceMarkersIfNecessary();
 }
@@ -478,16 +464,20 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
     }
 
     int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
-    if (int misalign = fPathIndexBuffer.count() % indexBytes) {
-        // Add padding to the index buffer so the indices are aligned properly.
-        fPathIndexBuffer.append(indexBytes - misalign);
-    }
+    char* savedIndices = (char*) fPathIndexBuffer.alloc(count * indexBytes,
+                                                        SkChunkAlloc::kThrow_AllocFailType);
+    SkASSERT(SkIsAlign4((uintptr_t)savedIndices));
+    memcpy(savedIndices, reinterpret_cast<const char*>(indices), count * indexBytes);
 
-    char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
-                                                 reinterpret_cast<const char*>(indices));
-    float* savedTransforms = fPathTransformBuffer.append(
-                                 count * GrPathRendering::PathTransformSize(transformType),
-                                 transformValues);
+    const int xformSize = GrPathRendering::PathTransformSize(transformType);
+    const int xformBytes = xformSize * sizeof(float);
+    float* savedTransforms = NULL;
+    if (0 != xformBytes) {
+        savedTransforms = (float*) fPathTransformBuffer.alloc(count * xformBytes,
+                                                              SkChunkAlloc::kThrow_AllocFailType);
+        SkASSERT(SkIsAlign4((uintptr_t)savedTransforms));
+        memcpy(savedTransforms, transformValues, count * xformBytes);
+    }
 
     if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
         // The previous command was also DrawPaths. Try to collapse this call into the one
@@ -504,16 +494,20 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
             stencilSettings == previous->fStencilSettings &&
             path_fill_type_is_winding(stencilSettings) &&
             !pipelineInfo.willBlendWithDst(pathProc)) {
-            // Fold this DrawPaths call into the one previous.
-            previous->fCount += count;
-            return;
+            if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
+                (0 == xformBytes ||
+                 &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) {
+                // Fold this DrawPaths call into the one previous.
+                previous->fCount += count;
+                return;
+            }
         }
     }
 
     DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
-    dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
+    dp->fIndices = savedIndices;
     dp->fIndexType = indexType;
-    dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
+    dp->fTransforms = savedTransforms;
     dp->fTransformType = transformType;
     dp->fCount = count;
     dp->fStencilSettings = stencilSettings;
@@ -569,8 +563,8 @@ void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
 void GrInOrderDrawBuffer::onReset() {
     fCmdBuffer.reset();
     fPrevState = NULL;
-    reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
-    reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
+    fPathIndexBuffer.rewind();
+    fPathTransformBuffer.rewind();
     fGpuCmdMarkers.reset();
     fDrawBatch = NULL;
 }
@@ -626,7 +620,7 @@ void GrInOrderDrawBuffer::onFlush() {
             }
             currentState = ss;
         } else {
-            iter->execute(this, currentState);
+            iter->execute(this->getGpu(), currentState);
         }
 
         if (iter->isTraced()) {
@@ -641,14 +635,14 @@ void GrInOrderDrawBuffer::onFlush() {
     ++fDrawID;
 }
 
-void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
+void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const SetState* state) {
     SkASSERT(state);
     DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
                   &state->fBatchTracker);
-    buf->getGpu()->draw(args, fInfo);
+    gpu->draw(args, fInfo);
 }
 
-void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
+void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const SetState*) {
     GrGpu::StencilPathState state;
     state.fRenderTarget = fRenderTarget.get();
     state.fScissor = &fScissor;
@@ -656,47 +650,47 @@ void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const S
     state.fUseHWAA = fUseHWAA;
     state.fViewMatrix = &fViewMatrix;
 
-    buf->getGpu()->stencilPath(this->path(), state);
+    gpu->stencilPath(this->path(), state);
 }
 
-void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
+void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const SetState* state) {
     SkASSERT(state);
     DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
                   &state->fBatchTracker);
-    buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
+    gpu->drawPath(args, this->path(), fStencilSettings);
 }
 
-void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
+void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
     SkASSERT(state);
     DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
                   &state->fBatchTracker);
-    buf->getGpu()->drawPaths(args, this->pathRange(),
-                            &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
-                            &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
-                            fCount, fStencilSettings);
+    gpu->drawPaths(args, this->pathRange(),
+                   fIndices, fIndexType,
+                   fTransforms, fTransformType,
+                   fCount, fStencilSettings);
 }
 
-void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
+void GrInOrderDrawBuffer::DrawBatch::execute(GrGpu* gpu, const SetState* state) {
     SkASSERT(state);
-    fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
+    fBatch->generateGeometry(fBatchTarget, state->getPipeline());
 }
 
-void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
+void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const SetState*) {}
 
-void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
+void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const SetState*) {
     if (GrColor_ILLEGAL == fColor) {
-        buf->getGpu()->discard(this->renderTarget());
+        gpu->discard(this->renderTarget());
     } else {
-        buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
+        gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
     }
 }
 
-void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
-    buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
+    gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
 }
 
-void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
-    buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
+void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const SetState*) {
+    gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
 }
 
 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
index 286c545..5876169 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "GrBatch.h"
 #include "GrBatchTarget.h"
+#include "SkChunkAlloc.h"
 #include "GrPipeline.h"
 #include "GrPath.h"
 #include "GrTRecorder.h"
@@ -78,7 +79,7 @@ private:
         Cmd(uint8_t type) : fType(type) {}
         virtual ~Cmd() {}
 
-        virtual void execute(GrInOrderDrawBuffer*, const SetState*) = 0;
+        virtual void execute(GrGpu*, const SetState*) = 0;
 
         uint8_t type() const { return fType & kCmdMask; }
 
@@ -95,7 +96,7 @@ private:
     struct Draw : public Cmd {
         Draw(const DrawInfo& info) : Cmd(kDraw_Cmd), fInfo(info) {}
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         DrawInfo     fInfo;
     };
@@ -108,7 +109,7 @@ private:
 
         const GrPath* path() const { return fPath.get(); }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         SkMatrix                                                fViewMatrix;
         bool                                                    fUseHWAA;
@@ -124,7 +125,7 @@ private:
 
         const GrPath* path() const { return fPath.get(); }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         GrStencilSettings       fStencilSettings;
 
@@ -137,11 +138,11 @@ private:
 
         const GrPathRange* pathRange() const { return fPathRange.get();  }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
-        int                     fIndicesLocation;
+        char*                   fIndices;
         PathIndexType           fIndexType;
-        int                     fTransformsLocation;
+        float*                  fTransforms;
         PathTransformType       fTransformType;
         int                     fCount;
         GrStencilSettings       fStencilSettings;
@@ -156,7 +157,7 @@ private:
 
         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         SkIRect fRect;
         GrColor fColor;
@@ -172,7 +173,7 @@ private:
 
         GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         SkIRect fRect;
         bool    fInsideClip;
@@ -187,7 +188,7 @@ private:
         GrSurface* dst() const { return fDst.get(); }
         GrSurface* src() const { return fSrc.get(); }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         SkIPoint    fDstPoint;
         SkIRect     fSrcRect;
@@ -214,7 +215,7 @@ private:
             return reinterpret_cast<const GrPipeline*>(fPipeline.get());
         }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
         ProgramPrimitiveProcessor               fPrimitiveProcessor;
@@ -224,14 +225,20 @@ private:
     };
 
     struct DrawBatch : public Cmd {
-        DrawBatch(GrBatch* batch) : Cmd(kDrawBatch_Cmd), fBatch(SkRef(batch)) {
+        DrawBatch(GrBatch* batch, GrBatchTarget* batchTarget) 
+            : Cmd(kDrawBatch_Cmd)
+            , fBatch(SkRef(batch))
+            , fBatchTarget(batchTarget) {
             SkASSERT(!batch->isUsed());
         }
 
-        void execute(GrInOrderDrawBuffer*, const SetState*) SK_OVERRIDE;
+        void execute(GrGpu*, const SetState*) SK_OVERRIDE;
 
         // TODO it wouldn't be too hard to let batches allocate in the cmd buffer
         SkAutoTUnref<GrBatch>  fBatch;
+
+    private:
+        GrBatchTarget*         fBatchTarget;
     };
 
     typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
@@ -308,8 +315,8 @@ private:
     CmdBuffer                           fCmdBuffer;
     SetState*                           fPrevState;
     SkTArray<GrTraceMarkerSet, false>   fGpuCmdMarkers;
-    SkTDArray<char>                     fPathIndexBuffer;
-    SkTDArray<float>                    fPathTransformBuffer;
+    SkChunkAlloc                        fPathIndexBuffer;
+    SkChunkAlloc                        fPathTransformBuffer;
     uint32_t                            fDrawID;
     GrBatchTarget                       fBatchTarget;
     // TODO hack until batch is everywhere
@@ -320,7 +327,7 @@ private:
     void closeBatch() {
         if (fDrawBatch) {
             fBatchTarget.resetNumberOfDraws();
-            fDrawBatch->execute(this, fPrevState);
+            fDrawBatch->execute(this->getGpu(), fPrevState);
             fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
             fDrawBatch = NULL;
         }