Add IndexType parameter to GrDrawTarget::drawPaths
authorcdalton <cdalton@nvidia.com>
Tue, 25 Nov 2014 19:00:56 +0000 (11:00 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 25 Nov 2014 19:00:56 +0000 (11:00 -0800)
Allows the caller to decide whether they sent 8, 16, or 32 bit path
indices.

BUG=skia:

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

13 files changed:
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h
src/gpu/GrPathRange.cpp
src/gpu/GrPathRange.h
src/gpu/GrPathRendering.h
src/gpu/GrStencilAndCoverTextContext.cpp
src/gpu/GrStencilAndCoverTextContext.h
src/gpu/gl/GrGLPathRendering.cpp
src/gpu/gl/GrGLPathRendering.h

index 688a744..bbf3eca 100644 (file)
@@ -617,15 +617,17 @@ void GrDrawTarget::drawPath(GrDrawState* ds,
 
 void GrDrawTarget::drawPaths(GrDrawState* ds,
                              const GrPathRange* pathRange,
-                             const uint32_t indices[],
+                             const void* indices,
+                             PathIndexType indexType,
+                             const float transformValues[],
+                             PathTransformType transformType,
                              int count,
-                             const float transforms[],
-                             PathTransformType transformsType,
                              GrPathRendering::FillType fill) {
     SkASSERT(this->caps()->pathRenderingSupport());
     SkASSERT(pathRange);
     SkASSERT(indices);
-    SkASSERT(transforms);
+    SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType));
+    SkASSERT(transformValues);
     SkASSERT(ds);
 
     // Setup clip
@@ -652,8 +654,8 @@ void GrDrawTarget::drawPaths(GrDrawState* ds,
         return;
     }
 
-    this->onDrawPaths(*ds, pathRange, indices, count, transforms, transformsType, scissorState,
-                      stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
+    this->onDrawPaths(*ds, pathRange, indices, indexType, transformValues, transformType, count,
+                      scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
 }
 
 void GrDrawTarget::clear(const SkIRect* rect,
index b86584d..0afbe66 100644 (file)
@@ -35,7 +35,8 @@ class GrDrawTarget : public SkRefCnt {
 public:
     SK_DECLARE_INST_COUNT(GrDrawTarget)
 
-    typedef GrPathRendering::PathTransformType PathTransformType ;
+    typedef GrPathRange::PathIndexType PathIndexType;
+    typedef GrPathRendering::PathTransformType PathTransformType;
 
     ///////////////////////////////////////////////////////////////////////////
 
@@ -279,22 +280,24 @@ public:
     void drawPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
 
     /**
-     * Draws many paths. It will respect the HW
-     * antialias flag on the draw state (if possible in the 3D API).
+     * Draws the aggregate path from combining multiple. Note that this will not
+     * always be equivalent to back-to-back calls to drawPath(). It will respect
+     * the HW antialias flag on the draw state (if possible in the 3D API).
      *
-     * @param pathRange       Source of paths to draw from
-     * @param indices         Array of indices into the the pathRange
-     * @param count           Number of paths to draw (length of indices array)
-     * @param transforms      Array of individual transforms, one for each path
-     * @param transformsType  Type of transformations in the array. Array contains
-                              PathTransformSize(transformsType) * count elements
+     * @param pathRange       Source paths to draw from
+     * @param indices         Array of path indices to draw
+     * @param indexType       Data type of the array elements in indexBuffer
+     * @param transformValues Array of transforms for the individual paths
+     * @param transformType   Type of transforms in transformBuffer
+     * @param count           Number of paths to draw
      * @param fill            Fill type for drawing all the paths
      */
     void drawPaths(GrDrawState*, const GrPathRange* pathRange,
-                   const uint32_t indices[],
+                   const void* indices,
+                   PathIndexType indexType,
+                   const float transformValues[],
+                   PathTransformType transformType,
                    int count,
-                   const float transforms[],
-                   PathTransformType transformsType,
                    GrPathRendering::FillType fill);
 
     /**
@@ -704,10 +707,11 @@ private:
                             const GrDeviceCoordTexture* dstCopy) = 0;
     virtual void onDrawPaths(const GrDrawState&,
                              const GrPathRange*,
-                             const uint32_t indices[],
-                             int count,
-                             const float transforms[],
+                             const void* indices,
+                             PathIndexType,
+                             const float transformValues[],
                              PathTransformType,
+                             int count,
                              const GrClipMaskManager::ScissorState&,
                              const GrStencilSettings&,
                              const GrDeviceCoordTexture*) = 0;
index 6b742c4..74e9419 100644 (file)
@@ -317,10 +317,11 @@ void GrGpu::drawPath(const GrOptDrawState& ds,
 
 void GrGpu::drawPaths(const GrOptDrawState& ds,
                       const GrPathRange* pathRange,
-                      const uint32_t indices[],
+                      const void* indices,
+                      GrDrawTarget::PathIndexType indexType,
+                      const float transformValues[],
+                      GrDrawTarget::PathTransformType transformType,
                       int count,
-                      const float transforms[],
-                      GrDrawTarget::PathTransformType transformsType,
                       const GrStencilSettings& stencilSettings) {
     this->handleDirtyContext();
 
@@ -328,7 +329,7 @@ void GrGpu::drawPaths(const GrOptDrawState& ds,
         return;
     }
 
-    pathRange->willDrawPaths(indices, count);
-    this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType,
-                                     stencilSettings);
+    pathRange->willDrawPaths(indices, indexType, count);
+    this->pathRendering()->drawPaths(pathRange, indices, indexType, transformValues,
+                                     transformType, count, stencilSettings);
 }
index 956f083..b10a63f 100644 (file)
@@ -365,10 +365,11 @@ public:
                           const GrStencilSettings&);
     virtual void drawPaths(const GrOptDrawState&,
                            const GrPathRange*,
-                           const uint32_t indices[],
-                           int count,
-                           const float transforms[],
+                           const void* indices,
+                           GrDrawTarget::PathIndexType,
+                           const float transformValues[],
                            GrDrawTarget::PathTransformType,
+                           int count,
                            const GrStencilSettings&);
 
     static DrawType PrimTypeToDrawType(GrPrimitiveType type) {
index 7fc201f..624c774 100644 (file)
@@ -324,24 +324,33 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
 
 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
                                       const GrPathRange* pathRange,
-                                      const uint32_t indices[],
+                                      const void* indices,
+                                      PathIndexType indexType,
+                                      const float transformValues[],
+                                      PathTransformType transformType,
                                       int count,
-                                      const float transforms[],
-                                      PathTransformType transformsType,
                                       const GrClipMaskManager::ScissorState& scissorState,
                                       const GrStencilSettings& stencilSettings,
                                       const GrDeviceCoordTexture* dstCopy) {
     SkASSERT(pathRange);
     SkASSERT(indices);
-    SkASSERT(transforms);
+    SkASSERT(transformValues);
 
     if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) {
         return;
     }
 
-    uint32_t* savedIndices = fPathIndexBuffer.append(count, indices);
-    float* savedTransforms = fPathTransformBuffer.append(count *
-                                 GrPathRendering::PathTransformSize(transformsType), transforms);
+    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 = fPathIndexBuffer.append(count * indexBytes,
+                                                 reinterpret_cast<const char*>(indices));
+    float* savedTransforms = fPathTransformBuffer.append(
+                                 count * GrPathRendering::PathTransformSize(transformType),
+                                 transformValues);
 
     if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) {
         // The previous command was also DrawPaths. Try to collapse this call into the one
@@ -353,7 +362,8 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
         // font tend to all wind in the same direction.
         DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
         if (pathRange == previous->pathRange() &&
-            transformsType == previous->fTransformsType &&
+            indexType == previous->fIndexType &&
+            transformType == previous->fTransformType &&
             stencilSettings == previous->fStencilSettings &&
             path_fill_type_is_winding(stencilSettings) &&
             !ds.willBlendWithDst()) {
@@ -365,9 +375,10 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
 
     DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
     dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin();
-    dp->fCount = count;
+    dp->fIndexType = indexType;
     dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin();
-    dp->fTransformsType = transformsType;
+    dp->fTransformType = transformType;
+    dp->fCount = count;
     dp->fStencilSettings = stencilSettings;
 
     this->recordTraceMarkersIfNecessary();
@@ -522,9 +533,9 @@ void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf,
                                              const GrOptDrawState* optState) {
     SkASSERT(optState);
     buf->fDstGpu->drawPaths(*optState, this->pathRange(),
-                            &buf->fPathIndexBuffer[fIndicesLocation], fCount,
-                            &buf->fPathTransformBuffer[fTransformsLocation], fTransformsType,
-                            fStencilSettings);
+                            &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
+                            &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
+                            fCount, fStencilSettings);
 }
 
 void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const GrOptDrawState*) {}
index 9d9f23c..373c5b4 100644 (file)
@@ -157,9 +157,10 @@ private:
         void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
 
         int                     fIndicesLocation;
-        size_t                  fCount;
+        PathIndexType           fIndexType;
         int                     fTransformsLocation;
-        PathTransformType       fTransformsType;
+        PathTransformType       fTransformType;
+        int                     fCount;
         GrStencilSettings       fStencilSettings;
 
     private:
@@ -249,10 +250,11 @@ private:
                     const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
     void onDrawPaths(const GrDrawState&,
                      const GrPathRange*,
-                     const uint32_t indices[],
-                     int count,
-                     const float transforms[],
+                     const void* indices,
+                     PathIndexType,
+                     const float transformValues[],
                      PathTransformType,
+                     int count,
                      const ScissorState&,
                      const GrStencilSettings&,
                      const GrDeviceCoordTexture*) SK_OVERRIDE;
@@ -293,8 +295,8 @@ private:
     // TODO: Use a single allocator for commands and records
     enum {
         kCmdBufferInitialSizeInBytes = 8 * 1024,
-        kPathIdxBufferMinReserve     = 64,
-        kPathXformBufferMinReserve   = 2 * kPathIdxBufferMinReserve,
+        kPathIdxBufferMinReserve     = 2 * 64,  // 64 uint16_t's
+        kPathXformBufferMinReserve   = 2 * 64,  // 64 two-float transforms
         kGeoPoolStatePreAllocCnt     = 4,
     };
 
@@ -318,7 +320,7 @@ private:
     GrGpu*                              fDstGpu;
     GrVertexBufferAllocPool&            fVertexPool;
     GrIndexBufferAllocPool&             fIndexPool;
-    SkTDArray<uint32_t>                 fPathIndexBuffer;
+    SkTDArray<char>                     fPathIndexBuffer;
     SkTDArray<float>                    fPathTransformBuffer;
     GeoPoolStateStack                   fGeoPoolStateStack;
     bool                                fFlushing;
index 3d0f7cf..cfe89fe 100644 (file)
@@ -32,17 +32,29 @@ GrPathRange::GrPathRange(GrGpu* gpu,
       fStroke(stroke) {
 }
 
-void GrPathRange::willDrawPaths(const uint32_t indices[], int count) const {
-    if (NULL == fPathGenerator.get()) {
+void GrPathRange::willDrawPaths(const void* indices, PathIndexType indexType, int count) const {
+    if (!fPathGenerator) {
         return;
     }
 
+    switch (indexType) {
+        case kU8_PathIndexType: return this->willDrawPaths<uint8_t>(indices, count);
+        case kU16_PathIndexType: return this->willDrawPaths<uint16_t>(indices, count);
+        case kU32_PathIndexType: return this->willDrawPaths<uint32_t>(indices, count);
+        default: SkFAIL("Unknown path index type");
+    }
+}
+
+template<typename IndexType> void GrPathRange::willDrawPaths(const void* indices, int count) const {
+    SkASSERT(fPathGenerator);
+
+    const IndexType* indexArray = reinterpret_cast<const IndexType*>(indices);
     bool didLoadPaths = false;
 
     for (int i = 0; i < count; ++i) {
-        SkASSERT(indices[i] < static_cast<uint32_t>(fNumPaths));
+        SkASSERT(indexArray[i] < static_cast<uint32_t>(fNumPaths));
 
-        const int groupIndex = indices[i] / kPathsPerGroup;
+        const int groupIndex = indexArray[i] / kPathsPerGroup;
         const int groupByte = groupIndex / 8;
         const uint8_t groupBit = 1 << (groupIndex % 8);
 
index 5bfecb0..a1431b9 100644 (file)
@@ -36,8 +36,25 @@ public:
         return type;
     }
 
+    enum PathIndexType {
+        kU8_PathIndexType,   //!< uint8_t
+        kU16_PathIndexType,  //!< uint16_t
+        kU32_PathIndexType,  //!< uint32_t
+
+        kLast_PathIndexType = kU32_PathIndexType
+    };
+
+    static inline int PathIndexSizeInBytes(PathIndexType type) {
+        GR_STATIC_ASSERT(0 == kU8_PathIndexType);
+        GR_STATIC_ASSERT(1 == kU16_PathIndexType);
+        GR_STATIC_ASSERT(2 == kU32_PathIndexType);
+        GR_STATIC_ASSERT(kU32_PathIndexType == kLast_PathIndexType);
+
+        return 1 << type;
+    }
+
     /**
-     *  Class that generates the paths for a specific range.
+     * Class that generates the paths for a specific range.
      */
     class PathGenerator : public SkRefCnt {
     public:
@@ -76,7 +93,8 @@ protected:
 private:
     // Notify when paths will be drawn in case this is a lazy-loaded path range.
     friend class GrGpu;
-    void willDrawPaths(const uint32_t indices[], int count) const;
+    void willDrawPaths(const void* indices, PathIndexType, int count) const;
+    template<typename IndexType> void willDrawPaths(const void* indices, int count) const;
 
     mutable SkAutoTUnref<PathGenerator> fPathGenerator;
     mutable SkTArray<uint8_t, true /*MEM_COPY*/> fGeneratedPaths;
index cd42206..3e2cfc6 100644 (file)
@@ -34,17 +34,7 @@ class GrPathRendering {
 public:
     virtual ~GrPathRendering() { }
 
-    // No native support for inverse at this time
-    enum FillType {
-        /** Specifies that "inside" is computed by a non-zero sum of signed
-            edge crossings
-        */
-        kWinding_FillType,
-        /** Specifies that "inside" is computed by an odd number of edge
-            crossings
-        */
-        kEvenOdd_FillType,
-    };
+    typedef GrPathRange::PathIndexType PathIndexType;
 
     enum PathTransformType {
         kNone_PathTransformType,        //!< []
@@ -74,6 +64,18 @@ public:
         }
     }
 
+    // No native support for inverse at this time
+    enum FillType {
+        /** Specifies that "inside" is computed by a non-zero sum of signed
+            edge crossings
+        */
+        kWinding_FillType,
+        /** Specifies that "inside" is computed by an odd number of edge
+            crossings
+        */
+        kEvenOdd_FillType,
+    };
+
     /**
      * Creates a new gpu path, based on the specified path and stroke and returns it.
      * The caller owns a ref on the returned path which must be balanced by a call to unref.
@@ -126,8 +128,8 @@ public:
 
     virtual void stencilPath(const GrPath*, const GrStencilSettings&) = 0;
     virtual void drawPath(const GrPath*, const GrStencilSettings&) = 0;
-    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
-                           const float transforms[], PathTransformType,
+    virtual void drawPaths(const GrPathRange*, const void* indices, PathIndexType,
+                           const float transformValues[], PathTransformType, int count,
                            const GrStencilSettings&) = 0;
 protected:
     GrPathRendering() { }
index d70593e..d6efe98 100644 (file)
@@ -367,9 +367,9 @@ void GrStencilAndCoverTextContext::flush() {
         return;
     }
 
-    fDrawTarget->drawPaths(&fDrawState, fGlyphs, fIndexBuffer, fPendingGlyphCount, fTransformBuffer,
-                           GrPathRendering::kTranslate_PathTransformType,
-                           GrPathRendering::kWinding_FillType);
+    fDrawTarget->drawPaths(&fDrawState, fGlyphs, fIndexBuffer, GrPathRange::kU16_PathIndexType,
+                           fTransformBuffer, GrPathRendering::kTranslate_PathTransformType,
+                           fPendingGlyphCount, GrPathRendering::kWinding_FillType);
 
     fPendingGlyphCount = 0;
 }
index dabd3b3..88b4eec 100644 (file)
@@ -57,7 +57,7 @@ private:
     float                           fTextInverseRatio;
     SkGlyphCache*                   fGlyphCache;
     GrPathRange*                    fGlyphs;
-    uint32_t                        fIndexBuffer[kGlyphBufferSize];
+    uint16_t                        fIndexBuffer[kGlyphBufferSize];
     float                           fTransformBuffer[2 * kGlyphBufferSize];
     int                             fPendingGlyphCount;
     SkMatrix                        fContextInitialMatrix;
index 2a46078..c7aae42 100644 (file)
 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X)
 
 
+static const GrGLenum gIndexType2GLType[] = {
+    GR_GL_UNSIGNED_BYTE,
+    GR_GL_UNSIGNED_SHORT,
+    GR_GL_UNSIGNED_INT
+};
+
+GR_STATIC_ASSERT(0 == GrPathRange::kU8_PathIndexType);
+GR_STATIC_ASSERT(1 == GrPathRange::kU16_PathIndexType);
+GR_STATIC_ASSERT(2 == GrPathRange::kU32_PathIndexType);
+GR_STATIC_ASSERT(GrPathRange::kU32_PathIndexType == GrPathRange::kLast_PathIndexType);
+
 static const GrGLenum gXformType2GLType[] = {
     GR_GL_NONE,
     GR_GL_TRANSLATE_X,
@@ -194,9 +205,10 @@ void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& st
     }
 }
 
-void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
-                                  const float transforms[], PathTransformType transformsType,
-                                  const GrStencilSettings& stencilSettings) {
+void GrGLPathRendering::drawPaths(const GrPathRange* pathRange,
+                                  const void* indices, PathIndexType indexType,
+                                  const float transformValues[], PathTransformType transformType,
+                                  int count, const GrStencilSettings& stencilSettings) {
     SkASSERT(fGpu->caps()->pathRenderingSupport());
 
     GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
@@ -215,19 +227,18 @@ void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i
     if (stroke.needToApply()) {
         if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
             GL_CALL(StencilFillPathInstanced(
-                            count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
-                            writeMask, gXformType2GLType[transformsType],
-                            transforms));
+                            count, gIndexType2GLType[indexType], indices, baseID, fillMode,
+                            writeMask, gXformType2GLType[transformType], transformValues));
         }
         this->stencilThenCoverStrokePathInstanced(
-                            count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
-                            GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
-                            gXformType2GLType[transformsType], transforms);
+                            count, gIndexType2GLType[indexType], indices, baseID,
+                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+                            gXformType2GLType[transformType], transformValues);
     } else {
         this->stencilThenCoverFillPathInstanced(
-                            count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
-                            GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
-                            gXformType2GLType[transformsType], transforms);
+                            count, gIndexType2GLType[indexType], indices, baseID,
+                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
+                            gXformType2GLType[transformType], transformValues);
     }
 }
 
index f314563..1f1a33c 100644 (file)
@@ -41,8 +41,8 @@ public:
                                       const SkStrokeRec&) SK_OVERRIDE;
     virtual void stencilPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
     virtual void drawPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
-    virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
-                           const float transforms[], PathTransformType,
+    virtual void drawPaths(const GrPathRange*, const void* indices, PathIndexType,
+                           const float transformValues[], PathTransformType, int count,
                            const GrStencilSettings&) SK_OVERRIDE;
 
     /* Called when the 3D context state is unknown. */