add SkVertices::Builder

Possible next iterations:
- remove another allocation use the SkData trick to share
  the object and its (trailing) data
- store a bit that tells use to free each pointer, allowing
  the builder to "adopt" some allocations instead of copy.

Larger idea:
- merge with drawPoints to have a single object for both.

BUG=skia:6366

Change-Id: Iec33239aa2ad5d00b36469ca0b88934ddf6f22eb
Reviewed-on: https://skia-review.googlesource.com/9604
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/gm/vertices.cpp b/gm/vertices.cpp
index a8f74bf..864ac3d 100644
--- a/gm/vertices.cpp
+++ b/gm/vertices.cpp
@@ -105,24 +105,8 @@
         fShader2 = make_shader2();
         fColorFilter = make_color_filter();
         if (fUseObject) {
-            std::unique_ptr<SkPoint[]> points(new SkPoint[kMeshVertexCnt]);
-            std::unique_ptr<SkPoint[]> texs(new SkPoint[kMeshVertexCnt]);
-            std::unique_ptr<SkColor[]> colors(new SkColor[kMeshVertexCnt]);
-            std::unique_ptr<uint16_t[]> indices(new uint16_t[kMeshIndexCnt]);
-            memcpy(points.get(), fPts, sizeof(SkPoint) * kMeshVertexCnt);
-            memcpy(colors.get(), fColors, sizeof(SkColor) * kMeshVertexCnt);
-            memcpy(texs.get(), fTexs, sizeof(SkPoint) * kMeshVertexCnt);
-            memcpy(indices.get(), kMeshFan, sizeof(uint16_t) * kMeshIndexCnt);
-            // Older libstdc++ does not allow moving a std::unique_ptr<T[]> into a
-            // std::unique_ptr<const T[]>. Hence the release() calls below.
-            fVertices = SkVertices::MakeIndexed(
-                    SkCanvas::kTriangleFan_VertexMode,
-                    std::unique_ptr<const SkPoint[]>((const SkPoint*)points.release()),
-                    std::unique_ptr<const SkColor[]>((const SkColor*)colors.release()),
-                    std::unique_ptr<const SkPoint[]>((const SkPoint*)texs.release()),
-                    kMeshVertexCnt,
-                    std::unique_ptr<const uint16_t[]>((const uint16_t*)indices.release()),
-                    kMeshIndexCnt);
+            fVertices = SkVertices::MakeCopy(SkCanvas::kTriangleFan_VertexMode, kMeshVertexCnt,
+                                             fPts, fTexs, fColors, kMeshIndexCnt, kMeshFan);
         }
     }
 
@@ -227,10 +211,15 @@
 DEF_GM(return new VerticesGM(false, 1 / kShaderSize);)
 
 static void draw_batching(SkCanvas* canvas, bool useObject) {
-    std::unique_ptr<SkPoint[]> pts(new SkPoint[kMeshVertexCnt]);
-    std::unique_ptr<SkPoint[]> texs(new SkPoint[kMeshVertexCnt]);
-    std::unique_ptr<SkColor[]> colors(new SkColor[kMeshVertexCnt]);
-    fill_mesh(pts.get(), texs.get(), colors.get(), 1);
+    // Triangle fans can't batch so we convert to regular triangles,
+    static constexpr int kNumTris = kMeshIndexCnt - 2;
+    SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, 3 * kNumTris,
+                                SkVertices::kHasColors_Flag | SkVertices::kHasTexs_Flag);
+
+    SkPoint* pts = builder.positions();
+    SkPoint* texs = builder.texCoords();
+    SkColor* colors = builder.colors();
+    fill_mesh(pts, texs, colors, 1);
 
     SkTDArray<SkMatrix> matrices;
     matrices.push()->reset();
@@ -242,26 +231,17 @@
 
     auto shader = make_shader1(1);
 
-    // Triangle fans can't batch so we convert to regular triangles,
-    static constexpr int kNumTris = kMeshIndexCnt - 2;
-    std::unique_ptr<uint16_t[]> indices(new uint16_t[3 * kNumTris]);
+    uint16_t* indices = builder.indices();
     for (size_t i = 0; i < kNumTris; ++i) {
         indices[3 * i] = kMeshFan[0];
         indices[3 * i + 1] = kMeshFan[i + 1];
         indices[3 * i + 2] = kMeshFan[i + 2];
+
     }
 
     sk_sp<SkVertices> vertices;
     if (useObject) {
-        // Older libstdc++ does not allow moving a std::unique_ptr<T[]> into a
-        // std::unique_ptr<const T[]>. Hence the release() calls below.
-        vertices = SkVertices::MakeIndexed(
-                SkCanvas::kTriangles_VertexMode,
-                std::unique_ptr<const SkPoint[]>((const SkPoint*)pts.release()),
-                std::unique_ptr<const SkColor[]>((const SkColor*)colors.release()),
-                std::unique_ptr<const SkPoint[]>((const SkPoint*)texs.release()), kMeshVertexCnt,
-                std::unique_ptr<const uint16_t[]>((const uint16_t*)indices.release()),
-                3 * kNumTris);
+        vertices = builder.detach();
     }
     canvas->save();
     canvas->translate(10, 10);
@@ -276,9 +256,9 @@
                     uint32_t flags = useTex ? 0 : SkCanvas::kIgnoreTexCoords_VerticesFlag;
                     canvas->drawVertices(vertices, SkBlendMode::kModulate, paint, flags);
                 } else {
-                    const SkPoint* t = useTex ? texs.get() : nullptr;
-                    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, pts.get(),
-                                         t, colors.get(), indices.get(), kNumTris * 3, paint);
+                    const SkPoint* t = useTex ? texs : nullptr;
+                    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, pts,
+                                         t, colors, indices, kNumTris * 3, paint);
                 }
                 canvas->restore();
             }