Specialize vertex writing function for common quad VertexSpecs

Change-Id: I204f04596809e1e33f20b67b454cdd0e1f269630
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255303
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.h b/src/gpu/ops/GrQuadPerEdgeAA.h
index 1e5675b..c15c840 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.h
+++ b/src/gpu/ops/GrQuadPerEdgeAA.h
@@ -15,12 +15,14 @@
 #include "src/gpu/GrGeometryProcessor.h"
 #include "src/gpu/GrSamplerState.h"
 #include "src/gpu/geometry/GrQuad.h"
+#include "src/gpu/geometry/GrQuadUtils.h"
 #include "src/gpu/ops/GrMeshDrawOp.h"
 #include "src/gpu/ops/GrTextureOp.h"
 
 class GrCaps;
 class GrColorSpaceXform;
 class GrShaderCaps;
+struct GrVertexWriter;
 
 namespace GrQuadPerEdgeAA {
     using Saturate = GrTextureOp::Saturate;
@@ -127,6 +129,35 @@
         unsigned fRequiresGeometryDomain: 1;
     };
 
+    // A Tessellator is responsible for processing a series of device+local GrQuads into a VBO,
+    // as specified by a VertexSpec. This vertex data can then be processed by a GP created with
+    // MakeProcessor and/or MakeTexturedProcessor.
+    class Tessellator {
+    public:
+        explicit Tessellator(const VertexSpec& spec);
+
+        // Calculates (as needed) inset and outset geometry for anti-aliasing, and writes all
+        // necessary position and vertex attributes required by this Tessellator's VertexSpec.
+        // After appending, this will return the pointer to the next vertex in the VBO.
+        void* append(void* vertices, const GrQuad& deviceQuad, const GrQuad& localQuad,
+                    const SkPMColor4f& color, const SkRect& uvDomain, GrQuadAAFlags aaFlags);
+
+    private:
+        // VertexSpec defines many unique ways to write vertex attributes, which can be handled
+        // generically by branching per-quad based on the VertexSpec. However, there are several
+        // specs that appear in the wild far more frequently, so they use explicit WriteQuadProcs
+        // that have no branches.
+        typedef void (*WriteQuadProc)(GrVertexWriter* vertices, const VertexSpec& spec,
+                                      const GrQuad& deviceQuad, const GrQuad& localQuad,
+                                      const float coverage[4], const SkPMColor4f& color,
+                                      const SkRect& geomDomain, const SkRect& texDomain);
+        static WriteQuadProc GetWriteQuadProc(const VertexSpec& spec);
+
+        GrQuadUtils::TessellationHelper fAAHelper;
+        VertexSpec                      fVertexSpec;
+        WriteQuadProc                   fWriteProc;
+    };
+
     sk_sp<GrGeometryProcessor> MakeProcessor(const VertexSpec& spec);
 
     sk_sp<GrGeometryProcessor> MakeTexturedProcessor(
@@ -134,19 +165,6 @@
             const GrSamplerState& samplerState, const GrSwizzle& swizzle,
             sk_sp<GrColorSpaceXform> textureColorSpaceXform, Saturate saturate);
 
-    // Fill vertices with the vertex data needed to represent the given quad. The device position,
-    // local coords, vertex color, domain, and edge coefficients will be written and/or computed
-    // based on the configuration in the vertex spec; if that attribute is disabled in the spec,
-    // then its corresponding function argument is ignored.
-    //
-    // Tessellation is based on the quad type of the vertex spec, not the provided GrQuad's
-    // so that all quads in a batch are tessellated the same.
-    //
-    // Returns the advanced pointer in vertices.
-    void* Tessellate(void* vertices, const VertexSpec& spec, const GrQuad& deviceQuad,
-                     const SkPMColor4f& color, const GrQuad& localQuad, const SkRect& domain,
-                     GrQuadAAFlags aa);
-
     // This method will return the correct index buffer for the specified indexBufferOption.
     // It will, correctly, return nullptr if the indexBufferOption is kTriStrips.
     sk_sp<const GrBuffer> GetIndexBuffer(GrMeshDrawOp::Target*, IndexBufferOption);