Added GrMeshDrawOp::WriteVertexData

This is a utility to make vertex generation code in ops simpler and more
consistent. Some existing ops use tricks that may not translate well,
but most will. It enforces writing in-order, leverages templates to
handle sizing and variable numbers of arguments.

For now, I used it to update three ops, showing a relatively simple
case, and a more thorough refactor (of the CircleOp). I think this makes
a stronger case for the GP changes that make stride fast enough for
non-debug use -- most ops won't even need a struct anymore, they can ask
the GP for stride, then use the WriteVertexData utility to write out
data matching the attribute layout.

Bug: skia:
Change-Id: Iec649803181ec5064b4fb9692ae68e6424758944
Reviewed-on: https://skia-review.googlesource.com/c/169340
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 8c74f27..b897a1a 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -696,28 +696,18 @@
 // extract the result vertices and indices from the GrAAConvexTessellator
 static void extract_lines_only_verts(const GrAAConvexTessellator& tess,
                                      void* vertices,
-                                     size_t vertexStride,
                                      GrColor color,
                                      uint16_t* idxs,
                                      bool tweakAlphaForCoverage) {
-    intptr_t verts = reinterpret_cast<intptr_t>(vertices);
-
     for (int i = 0; i < tess.numPts(); ++i) {
-        *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i);
-    }
-
-    // Make 'verts' point to the colors
-    verts += sizeof(SkPoint);
-    for (int i = 0; i < tess.numPts(); ++i) {
+        vertices = GrMeshDrawOp::WriteVertexData(vertices, tess.point(i));
         if (tweakAlphaForCoverage) {
             SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255);
             unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i));
             GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
-            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
+            vertices = GrMeshDrawOp::WriteVertexData(vertices, scaledColor);
         } else {
-            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
-            *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) =
-                    tess.coverage(i);
+            vertices = GrMeshDrawOp::WriteVertexData(vertices, color, tess.coverage(i));
         }
     }
 
@@ -845,7 +835,7 @@
             }
 
             // TODO4F: Preserve float colors
-            extract_lines_only_verts(tess, verts, vertexStride, args.fColor.toBytes_RGBA(), idxs,
+            extract_lines_only_verts(tess, verts, args.fColor.toBytes_RGBA(), idxs,
                                      fHelper.compatibleWithAlphaAsCoverage());
 
             GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);