Only support SkVertices in GrDrawVerticesOp and GrRenderTargetContext

Allow overriding the primitive type at draw time, so everyone can
funnel through the same code path. Simplifies the color array type
logic, and saves one memcpy (of indices) in the drawWireframe case.

Bug: skia:
Change-Id: I46653d34169842b9b5304cff48d804b2a9ace529
Reviewed-on: https://skia-review.googlesource.com/17783
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index fa1e0b3..37de07e 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -836,42 +836,8 @@
 void GrRenderTargetContext::drawVertices(const GrClip& clip,
                                          GrPaint&& paint,
                                          const SkMatrix& viewMatrix,
-                                         GrPrimitiveType primitiveType,
-                                         int vertexCount,
-                                         const SkPoint positions[],
-                                         const SkPoint texCoords[],
-                                         const uint32_t colors[],
-                                         const uint16_t indices[],
-                                         int indexCount,
-                                         ColorArrayType colorArrayType) {
-    ASSERT_SINGLE_OWNER
-    RETURN_IF_ABANDONED
-    SkDEBUGCODE(this->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawVertices");
-
-    AutoCheckFlush acf(this->drawingManager());
-
-    // TODO clients should give us bounds
-    SkRect bounds;
-    if (!bounds.setBoundsCheck(positions, vertexCount)) {
-        SkDebugf("drawVertices call empty bounds\n");
-        return;
-    }
-
-    std::unique_ptr<GrLegacyMeshDrawOp> op = GrDrawVerticesOp::Make(
-            paint.getColor(), primitiveType, viewMatrix, positions, vertexCount, indices,
-            indexCount, colors, texCoords, bounds, colorArrayType);
-    if (!op) {
-        return;
-    }
-    GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
-    this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
-}
-
-void GrRenderTargetContext::drawVertices(const GrClip& clip,
-                                         GrPaint&& paint,
-                                         const SkMatrix& viewMatrix,
-                                         sk_sp<SkVertices> vertices) {
+                                         sk_sp<SkVertices> vertices,
+                                         GrPrimitiveType* overridePrimType) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
@@ -880,8 +846,9 @@
     AutoCheckFlush acf(this->drawingManager());
 
     SkASSERT(vertices);
-    std::unique_ptr<GrLegacyMeshDrawOp> op =
-            GrDrawVerticesOp::Make(paint.getColor(), std::move(vertices), viewMatrix);
+    std::unique_ptr<GrLegacyMeshDrawOp> op = GrDrawVerticesOp::Make(paint.getColor(),
+                                                                    std::move(vertices), viewMatrix,
+                                                                    overridePrimType);
     if (!op) {
         return;
     }
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index fe20a6d..20df4c5 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -201,52 +201,19 @@
                   const SkPath&,
                   const GrStyle& style);
 
-    enum class ColorArrayType {
-        kPremulGrColor,
-        kSkColor,
-    };
     /**
      * Draws vertices with a paint.
      *
-     * @param   paint           describes how to color pixels.
-     * @param   viewMatrix      transformation matrix
-     * @param   primitiveType   primitives type to draw.
-     * @param   vertexCount     number of vertices.
-     * @param   positions       array of vertex positions, required.
-     * @param   texCoords       optional array of texture coordinates used
-     *                          to access the paint.
-     * @param   colors          optional array of per-vertex colors, supercedes
-     *                          the paint's color field.
-     * @param   indices         optional array of indices. If NULL vertices
-     *                          are drawn non-indexed.
-     * @param   indexCount      if indices is non-null then this is the
-     *                          number of indices.
-     * @param   ColorArrayType  Determines how the color array should be interpreted.
+     * @param   paint            describes how to color pixels.
+     * @param   viewMatrix       transformation matrix
+     * @param   vertices         specifies the mesh to draw.
+     * @param   overridePrimType primitive type to draw. If NULL, derive prim type from vertices.
      */
     void drawVertices(const GrClip&,
                       GrPaint&& paint,
                       const SkMatrix& viewMatrix,
-                      GrPrimitiveType primitiveType,
-                      int vertexCount,
-                      const SkPoint positions[],
-                      const SkPoint texs[],
-                      const uint32_t colors[],
-                      const uint16_t indices[],
-                      int indexCount,
-                      ColorArrayType = ColorArrayType::kPremulGrColor);
-
-    /**
-     * Draws vertices with a paint.
-     *
-     * @param   paint           describes how to color pixels.
-     * @param   viewMatrix      transformation matrix
-     * @param   veritces        specifies the mesh to draw.
-     * @param   flags           A bitfield of options specified by SkCanvas::VerticesFlags.
-     */
-    void drawVertices(const GrClip&,
-                      GrPaint&& paint,
-                      const SkMatrix& viewMatrix,
-                      sk_sp<SkVertices> vertices);
+                      sk_sp<SkVertices> vertices,
+                      GrPrimitiveType* overridePrimType = nullptr);
 
     /**
      * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c48e8d5..56dc4cc 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -389,16 +389,12 @@
         return;
     }
 
-    fRenderTargetContext->drawVertices(this->clip(),
-                                       std::move(grPaint),
-                                       *viewMatrix,
-                                       primitiveType,
-                                       SkToS32(count),
-                                       (SkPoint*)pts,
-                                       nullptr,
-                                       nullptr,
-                                       nullptr,
-                                       0);
+    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
+    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, SkToS32(count), pts, nullptr,
+                                                      nullptr);
+
+    fRenderTargetContext->drawVertices(this->clip(), std::move(grPaint), *viewMatrix,
+                                       std::move(vertices), &primitiveType);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1614,7 +1610,11 @@
     //number of indices for lines per triangle with kLines
     indexCount = triangleCount * 6;
 
-    std::unique_ptr<uint16_t[]> lineIndices(new uint16_t[indexCount]);
+    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
+    SkVertices::Builder builder(kIgnoredMode, vertexCount, indexCount, 0);
+    memcpy(builder.positions(), vertices, vertexCount * sizeof(SkPoint));
+
+    uint16_t* lineIndices = builder.indices();
     int i = 0;
     while (vertProc(&state)) {
         lineIndices[i]     = state.f0;
@@ -1625,16 +1625,13 @@
         lineIndices[i + 5] = state.f0;
         i += 6;
     }
+
+    GrPrimitiveType primitiveType = kLines_GrPrimitiveType;
     fRenderTargetContext->drawVertices(this->clip(),
                                        std::move(grPaint),
                                        this->ctm(),
-                                       kLines_GrPrimitiveType,
-                                       vertexCount,
-                                       vertices,
-                                       nullptr,
-                                       nullptr,
-                                       lineIndices.get(),
-                                       indexCount);
+                                       builder.detach(),
+                                       &primitiveType);
 }
 
 void SkGpuDevice::drawVertices(const SkVertices* vertices, SkBlendMode mode,
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index 73d29ea..2a61f3c 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -10,48 +10,26 @@
 #include "GrOpFlushState.h"
 #include "SkGr.h"
 
-std::unique_ptr<GrLegacyMeshDrawOp> GrDrawVerticesOp::Make(
-        GrColor color, GrPrimitiveType primitiveType, const SkMatrix& viewMatrix,
-        const SkPoint* positions, int vertexCount, const uint16_t* indices, int indexCount,
-        const uint32_t* colors, const SkPoint* localCoords, const SkRect& bounds,
-        GrRenderTargetContext::ColorArrayType colorArrayType) {
-    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
-    SkASSERT(positions);
-    if (!colors) {
-        // When we tessellate we will fill a color array with the GrColor value passed above as
-        // 'color'.
-        colorArrayType = GrRenderTargetContext::ColorArrayType::kPremulGrColor;
-    }
-    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions,
-                                                      localCoords, colors, indexCount, indices);
-    if (!vertices) {
-        return nullptr;
-    }
-    return std::unique_ptr<GrLegacyMeshDrawOp>(new GrDrawVerticesOp(
-            std::move(vertices), primitiveType, color, colorArrayType, viewMatrix));
-}
-
 std::unique_ptr<GrLegacyMeshDrawOp> GrDrawVerticesOp::Make(GrColor color,
                                                            sk_sp<SkVertices> vertices,
-                                                           const SkMatrix& viewMatrix) {
+                                                           const SkMatrix& viewMatrix,
+                                                           GrPrimitiveType* overridePrimType) {
     SkASSERT(vertices);
-    GrPrimitiveType primType = SkVertexModeToGrPrimitiveType(vertices->mode());
-    GrRenderTargetContext::ColorArrayType colorArrayType =
-            vertices->hasColors() ? GrRenderTargetContext::ColorArrayType::kSkColor
-                                  : GrRenderTargetContext::ColorArrayType::kPremulGrColor;
+    GrPrimitiveType primType = overridePrimType ? *overridePrimType
+                                                : SkVertexModeToGrPrimitiveType(vertices->mode());
     return std::unique_ptr<GrLegacyMeshDrawOp>(
-            new GrDrawVerticesOp(std::move(vertices), primType, color, colorArrayType, viewMatrix));
+            new GrDrawVerticesOp(std::move(vertices), primType, color, viewMatrix));
 }
 
 GrDrawVerticesOp::GrDrawVerticesOp(sk_sp<SkVertices> vertices, GrPrimitiveType primitiveType,
-                                   GrColor color,
-                                   GrRenderTargetContext::ColorArrayType colorArrayType,
-                                   const SkMatrix& viewMatrix)
-        : INHERITED(ClassID()), fColorArrayType(colorArrayType) {
+                                   GrColor color, const SkMatrix& viewMatrix)
+        : INHERITED(ClassID()) {
     SkASSERT(vertices);
 
     fVertexCount = vertices->vertexCount();
     fIndexCount = vertices->indexCount();
+    fColorArrayType = vertices->hasColors() ? ColorArrayType::kSkColor
+                                            : ColorArrayType::kPremulGrColor;
     fPrimitiveType = primitiveType;
 
     Mesh& mesh = fMeshes.push_back();
@@ -95,7 +73,7 @@
         fMeshes[0].fColor = overrideColor;
         fMeshes[0].fIgnoreColors = true;
         fFlags &= ~kRequiresPerVertexColors_Flag;
-        fColorArrayType = GrRenderTargetContext::ColorArrayType::kPremulGrColor;
+        fColorArrayType = ColorArrayType::kPremulGrColor;
     }
     if (optimizations.readsLocalCoords()) {
         fFlags |= kPipelineRequiresLocalCoords_Flag;
@@ -126,7 +104,7 @@
 
     Color color(fMeshes[0].fColor);
     if (this->requiresPerVertexColors()) {
-        color.fType = (fColorArrayType == GrRenderTargetContext::ColorArrayType::kPremulGrColor)
+        color.fType = (fColorArrayType == ColorArrayType::kPremulGrColor)
                               ? Color::kPremulGrColorAttribute_Type
                               : Color::kUnpremulSkColorAttribute_Type;
         *hasColorAttribute = true;
@@ -384,18 +362,17 @@
                          hasIndices);
     }
 
-    GrRenderTargetContext::ColorArrayType colorArrayType =
-            random->nextBool() ? GrRenderTargetContext::ColorArrayType::kPremulGrColor
-                               : GrRenderTargetContext::ColorArrayType::kSkColor;
     SkMatrix viewMatrix = GrTest::TestMatrix(random);
-    SkRect bounds;
-    SkDEBUGCODE(bool result =) bounds.setBoundsCheck(positions.begin(), vertexCount);
-    SkASSERT(result);
 
     GrColor color = GrRandomColor(random);
-    return GrDrawVerticesOp::Make(color, type, viewMatrix, positions.begin(), vertexCount,
-                                  indices.begin(), hasIndices ? indices.count() : 0, colors.begin(),
-                                  texCoords.begin(), bounds, colorArrayType);
+
+    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
+    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions.begin(),
+                                                      texCoords.begin(), colors.begin(),
+                                                      hasIndices ? indices.count() : 0,
+                                                      indices.begin());
+    return std::unique_ptr<GrLegacyMeshDrawOp>(
+            new GrDrawVerticesOp(std::move(vertices), type, color, viewMatrix));
 }
 
 #endif
diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h
index 009c5e0..0c75dcf 100644
--- a/src/gpu/ops/GrDrawVerticesOp.h
+++ b/src/gpu/ops/GrDrawVerticesOp.h
@@ -17,6 +17,10 @@
 #include "SkTDArray.h"
 #include "SkVertices.h"
 
+#if GR_TEST_UTILS
+#include "GrDrawOpTest.h"
+#endif
+
 class GrOpFlushState;
 class SkVertices;
 struct GrInitInvariantOutput;
@@ -26,27 +30,13 @@
     DEFINE_OP_CLASS_ID
 
     /**
-     * The 'color' param is used if the 'colors' array is null. 'bounds' is the bounds of the
-     * 'positions' array (in local space prior to application of 'viewMatrix'). If 'indices' is null
-     * then 'indexCnt' must be zero and vice versa. In this case the vertices are indexed as 0, 1,
-     * ..., 'vertexCount' - 1. 'localCoords' are optional and if null the vertex positions are used
-     * as local coords. 'colorArrayType' specifies whether the colors are premul GrColors or
-     * unpremul SkColors.
-     */
-    static std::unique_ptr<GrLegacyMeshDrawOp> Make(
-            GrColor color, GrPrimitiveType primitiveType, const SkMatrix& viewMatrix,
-            const SkPoint* positions, int vertexCount, const uint16_t* indices, int indexCount,
-            const uint32_t* colors, const SkPoint* localCoords, const SkRect& bounds,
-            GrRenderTargetContext::ColorArrayType colorArrayType);
-
-    /**
-     * Draw a SkVertices. The GrColor param is used if the vertices lack per-vertex color or 'flags'
-     * indicates that the per-vertex color should be ignored.  The 'flags' options are those
-     * specified by SkCanvas::VerticesFlags. If the vertices lack local coords or 'flags' indicates
-     * that they should be ignored then the vertex positions are used as local coords.
+     * Draw a SkVertices. The GrColor param is used if the vertices lack per-vertex color. If the
+     * vertices lack local coords then the vertex positions are used as local coords. The primitive
+     * type drawn is derived from the SkVertices object, unless overridePrimType is specified.
      */
     static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, sk_sp<SkVertices>,
-                                                    const SkMatrix& viewMatrix);
+                                                    const SkMatrix& viewMatrix,
+                                                    GrPrimitiveType* overridePrimType = nullptr);
 
     const char* name() const override { return "DrawVerticesOp"; }
 
@@ -60,8 +50,12 @@
     }
 
 private:
-    GrDrawVerticesOp(sk_sp<SkVertices>, GrPrimitiveType, GrColor,
-                     GrRenderTargetContext::ColorArrayType, const SkMatrix& viewMatrix);
+    enum class ColorArrayType {
+        kPremulGrColor,
+        kSkColor,
+    };
+
+    GrDrawVerticesOp(sk_sp<SkVertices>, GrPrimitiveType, GrColor, const SkMatrix& viewMatrix);
 
     void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
                                     GrProcessorAnalysisCoverage* coverage) const override;
@@ -130,10 +124,14 @@
     uint32_t fFlags;
     int fVertexCount;
     int fIndexCount;
-    GrRenderTargetContext::ColorArrayType fColorArrayType;
+    ColorArrayType fColorArrayType;
     SkSTArray<1, Mesh, true> fMeshes;
 
     typedef GrLegacyMeshDrawOp INHERITED;
+
+#if GR_TEST_UTILS
+    GR_LEGACY_MESH_DRAW_OP_TEST_FRIEND(VerticesOp);
+#endif
 };
 
 #endif