Revert "Reland "Reland "Use conics with w=Inf to describe triangles for the tessellator"""

This reverts commit 99e6f0fcfb44ab9de58d927b30dd6ddd16dd861e.

Reason for revert: Perf regressions

Original change's description:
> Reland "Reland "Use conics with w=Inf to describe triangles for the tessellator""
>
> This is a reland of ff515df5b4549673b4c7f04e41c62f2bd1d4ddc3
>
> Original change's description:
> > Reland "Use conics with w=Inf to describe triangles for the tessellator"
> >
> > This is a reland of 84f70136abfb0af3cddf2ec7e8e2405f154916b0
> >
> > Original change's description:
> > > Use conics with w=Inf to describe triangles for the tessellator
> > >
> > > Previously, only the indirect tessellator could draw triangles, and
> > > only with special index data. Using conics with w=Inf will allow us to
> > > draw triangles with the hardware tessellator as well, in addition to
> > > being able to wean the indirect tessellator off an index buffer.
> > >
> > > Bug: skia:10419
> > > Bug: chromium:1202607
> > > Change-Id: I180af9cb5410c0e0bb25a2edcfb01e17d4a2f590
> > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/406977
> > > Commit-Queue: Chris Dalton <csmartdalton@google.com>
> > > Reviewed-by: Michael Ludwig <michaelludwig@google.com>
> >
> > Bug: skia:10419
> > Bug: chromium:1202607
> > Change-Id: Ic12b10eaa60fddd212c66757bf7100749ee58d49
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408096
> > Reviewed-by: Robert Phillips <robertphillips@google.com>
> > Commit-Queue: Chris Dalton <csmartdalton@google.com>
>
> TBR=robertphillips@google.com
>
> Bug: skia:10419
> Bug: chromium:1202607
> Change-Id: Id1f8dfa133f446b9f30f2bf8493a3a7b99072e59
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408616
> Reviewed-by: Chris Dalton <csmartdalton@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>

TBR=robertphillips@google.com,csmartdalton@google.com,michaelludwig@google.com

Change-Id: I8a4c85bc6863fbe62ed34dc3110370662bacab67
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10419
Bug: chromium:1202607
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408677
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/tessellate/GrFillPathShader.cpp b/src/gpu/tessellate/GrFillPathShader.cpp
index 71fd72d..6274845 100644
--- a/src/gpu/tessellate/GrFillPathShader.cpp
+++ b/src/gpu/tessellate/GrFillPathShader.cpp
@@ -72,20 +72,16 @@
                                            GrGLSLUniformHandler* uniformHandler) const {
     v->codeAppend(R"(
     float4x2 P = float4x2(input_points_0_1, input_points_2_3);
-    if (isinf(P[3].y)) {  // Is the curve a conic?
+    if (isinf(P[3].y)) {
+        // This curve is actually a conic. Convert the control points to a trapeziodal hull
+        // that circumcscribes the conic.
         float w = P[3].x;
-        if (isinf(w)) {
-            // A conic with w=Inf is an exact triangle.
-            P = float4x2(P[0], P[1], P[2], P[2]);
-        } else {
-            // Convert the control points to a trapeziodal hull that circumcscribes the conic.
-            float2 p1w = P[1] * w;
-            float T = .51;  // Bias outward a bit to ensure we cover the outermost samples.
-            float2 c1 = mix(P[0], p1w, T);
-            float2 c2 = mix(P[2], p1w, T);
-            float iw = 1 / mix(1, w, T);
-            P = float4x2(P[0], c1 * iw, c2 * iw, P[2]);
-        }
+        float2 p1w = P[1] * w;
+        float T = .51;  // Bias outward a bit to ensure we cover the outermost samples.
+        float2 c1 = mix(P[0], p1w, T);
+        float2 c2 = mix(P[2], p1w, T);
+        float iw = 1 / mix(1, w, T);
+        P = float4x2(P[0], c1 * iw, c2 * iw, P[2]);
     }
 
     // Translate the points to v0..3 where v0=0.
diff --git a/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h b/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
index fb17db1..b960ab5 100644
--- a/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
+++ b/src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h
@@ -13,7 +13,6 @@
 #include "include/private/SkTemplates.h"
 #include "src/core/SkMathPriv.h"
 #include "src/core/SkPathPriv.h"
-#include <limits>
 
 // This class emits a polygon triangulation with a "middle-out" topology. Conceptually, middle-out
 // emits one large triangle with vertices on both endpoints and a middle point, then recurses on
@@ -41,12 +40,6 @@
 // This class is designed to not know or store all the vertices in the polygon at once. The caller
 // pushes each vertex in linear order (perhaps while parsing a path), then rather than relying on
 // recursion, we manipulate an O(log N) stack to determine the correct middle-out triangulation.
-//
-// perTriangleVertexAdvance controls how much padding to put after triangles (namely, we append
-// "perTriangleVertexAdvance - 3" vertices of padding after each triangle, including the final one).
-// Padding vertices are filled with infinity. This has the effect, when perTriangleVertexAdvance is
-// 4, of defining a conic with w=Inf for tessellation shaders, which comes out to be an exact
-// triangle.
 class GrMiddleOutPolygonTriangulator {
 public:
     GrMiddleOutPolygonTriangulator(SkPoint* vertexData, int perTriangleVertexAdvance,
@@ -173,10 +166,6 @@
         fVertexData[0] = fTop[0].fPoint;
         fVertexData[1] = fTop[1].fPoint;
         fVertexData[2] = lastPt;
-        for (int i = 3; i < fPerTriangleVertexAdvance; ++i) {
-            fVertexData[i].set(std::numeric_limits<float>::infinity(),
-                               std::numeric_limits<float>::infinity());
-        }
         fVertexData += fPerTriangleVertexAdvance;
     }
 
diff --git a/src/gpu/tessellate/GrPathTessellator.cpp b/src/gpu/tessellate/GrPathTessellator.cpp
index 7fe80ae..24db640 100644
--- a/src/gpu/tessellate/GrPathTessellator.cpp
+++ b/src/gpu/tessellate/GrPathTessellator.cpp
@@ -14,7 +14,6 @@
 #include "src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h"
 #include "src/gpu/tessellate/GrMidpointContourParser.h"
 #include "src/gpu/tessellate/GrStencilPathShader.h"
-#include <limits>
 
 GrPathIndirectTessellator::GrPathIndirectTessellator(const SkMatrix& viewMatrix, const SkPath& path,
                                                      DrawInnerFan drawInnerFan)
@@ -93,9 +92,8 @@
             }
             SkPoint* breadcrumbData = instanceData + numTrianglesAtBeginningOfData * 4;
             memcpy(breadcrumbData, p, sizeof(SkPoint) * 3);
-            // Mark this instance as a triangle by setting it to a conic with w=Inf.
-            breadcrumbData[3].set(std::numeric_limits<float>::infinity(),
-                                  std::numeric_limits<float>::infinity());
+            // Duplicate the final point since it will also be used by the convex hull shader.
+            breadcrumbData[3] = p[2];
             ++numTrianglesAtBeginningOfData;
         }
         SkASSERT(count == breadcrumbTriangleList->count());
@@ -124,24 +122,29 @@
     // location at each resolve level.
     SkPoint* instanceLocations[kMaxResolveLevel + 1];
     int runningInstanceCount = 0;
+    if (numTrianglesAtBeginningOfData) {
+        // The caller has already packed "triangleInstanceCount" triangles into 4-point instances
+        // at the beginning of the instance buffer. Add a special-case indirect draw here that will
+        // emit the triangles [P0, P1, P2] from these 4-point instances.
+        SkASSERT(fIndirectDrawCount < indirectLockCnt);
+        GrMiddleOutCubicShader::WriteDrawTrianglesIndirectCmd(&indirectWriter,
+                                                              numTrianglesAtBeginningOfData,
+                                                              fBaseInstance);
+        ++fIndirectDrawCount;
+        runningInstanceCount = numTrianglesAtBeginningOfData;
+    }
     SkASSERT(fResolveLevelCounts[0] == 0);
     for (int resolveLevel = 1; resolveLevel <= kMaxResolveLevel; ++resolveLevel) {
         int instanceCountAtCurrLevel = fResolveLevelCounts[resolveLevel];
-        if (resolveLevel == 1) {
-            instanceCountAtCurrLevel += numTrianglesAtBeginningOfData;
-        }
         if (!instanceCountAtCurrLevel) {
             SkDEBUGCODE(instanceLocations[resolveLevel] = nullptr;)
             continue;
         }
         instanceLocations[resolveLevel] = instanceData + runningInstanceCount * 4;
-        if (resolveLevel == 1) {
-            instanceLocations[resolveLevel] += numTrianglesAtBeginningOfData * 4;
-        }
         SkASSERT(fIndirectDrawCount < indirectLockCnt);
-        GrMiddleOutCubicShader::WriteDrawIndirectCmd(&indirectWriter, resolveLevel,
-                                                     instanceCountAtCurrLevel,
-                                                     fBaseInstance + runningInstanceCount);
+        GrMiddleOutCubicShader::WriteDrawCubicsIndirectCmd(&indirectWriter, resolveLevel,
+                                                           instanceCountAtCurrLevel,
+                                                           fBaseInstance + runningInstanceCount);
         ++fIndirectDrawCount;
         runningInstanceCount += instanceCountAtCurrLevel;
     }
diff --git a/src/gpu/tessellate/GrStencilPathShader.cpp b/src/gpu/tessellate/GrStencilPathShader.cpp
index d5643a2..85b1f42 100644
--- a/src/gpu/tessellate/GrStencilPathShader.cpp
+++ b/src/gpu/tessellate/GrStencilPathShader.cpp
@@ -367,25 +367,24 @@
     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
         const auto& shader = args.fGeomProc.cast<GrMiddleOutCubicShader>();
         args.fVaryingHandler->emitAttributes(shader);
-        args.fVertBuilder->defineConstantf("float", "kInverseMaxVertexID", "(1.0 / float(%d))",
-                                           1 << kMaxResolveLevel);
+        args.fVertBuilder->defineConstantf("int", "kMaxVertexID", "%i", 1 << kMaxResolveLevel);
+        args.fVertBuilder->defineConstantf("float", "kInverseMaxVertexID",
+                                           "(1.0 / float(kMaxVertexID))");
         args.fVertBuilder->insertFunction(kUnpackRationalCubicFn);
         args.fVertBuilder->insertFunction(kEvalRationalCubicFn);
-        args.fVertBuilder->codeAppendf(R"(
+        args.fVertBuilder->codeAppend(R"(
         float2 pos;
-        if (isinf(inputPoints_2_3.z)) {
-            // A conic with w=Inf is an exact triangle.
-            int idx = sk_VertexID >> %d/*kMaxResolveLevel - 1*/;
-            pos = (idx <  1) ? inputPoints_0_1.xy
-                : (idx == 1) ? inputPoints_0_1.zw
-                             : inputPoints_2_3.xy;
+        if (sk_VertexID > kMaxVertexID) {
+            // This is a special index value that instructs us to emit a specific point.
+            pos = ((sk_VertexID & 3) == 0) ? inputPoints_0_1.xy :
+                  ((sk_VertexID & 2) == 0) ? inputPoints_0_1.zw : inputPoints_2_3.xy;
         } else {
             // Evaluate the cubic at T = (sk_VertexID / 2^kMaxResolveLevel).
             float T = float(sk_VertexID) * kInverseMaxVertexID;
             float4x3 P = unpack_rational_cubic(inputPoints_0_1.xy, inputPoints_0_1.zw,
                                                inputPoints_2_3.xy, inputPoints_2_3.zw);
             pos = eval_rational_cubic(P, T);
-        })", kMaxResolveLevel - 1);
+        })");
 
         GrShaderVar vertexPos("pos", kFloat2_GrSLType);
         if (!shader.viewMatrix().isIdentity()) {
diff --git a/src/gpu/tessellate/GrStencilPathShader.h b/src/gpu/tessellate/GrStencilPathShader.h
index 203a184..7236dea 100644
--- a/src/gpu/tessellate/GrStencilPathShader.h
+++ b/src/gpu/tessellate/GrStencilPathShader.h
@@ -152,8 +152,9 @@
 
     // Configures an indirect draw to render cubic instances with 2^resolveLevel evenly-spaced (in
     // the parametric sense) line segments.
-    static void WriteDrawIndirectCmd(GrDrawIndexedIndirectWriter* indirectWriter, int resolveLevel,
-                                     uint32_t instanceCount, uint32_t baseInstance) {
+    static void WriteDrawCubicsIndirectCmd(GrDrawIndexedIndirectWriter* indirectWriter,
+                                           int resolveLevel, uint32_t instanceCount,
+                                           uint32_t baseInstance) {
         SkASSERT(resolveLevel > 0 && resolveLevel <= GrTessellationPathRenderer::kMaxResolveLevel);
         // Starting at baseIndex=3, the index buffer triangulates a cubic with 2^kMaxResolveLevel
         // line segments. Each index value corresponds to a parametric T value on the curve. Since
@@ -163,6 +164,15 @@
         indirectWriter->writeIndexed(indexCount, 3, instanceCount, baseInstance, 0);
     }
 
+    // For performance reasons we can often express triangles as an indirect cubic draw and sneak
+    // them in alongside the other indirect draws. This method configures an indirect draw to emit
+    // the triangle [P0, P1, P2] from a 4-point instance.
+    static void WriteDrawTrianglesIndirectCmd(GrDrawIndexedIndirectWriter* indirectWriter,
+                                              uint32_t instanceCount, uint32_t baseInstance) {
+        // Indices 0,1,2 have special index values that emit points P0, P1, and P2 respectively.
+        indirectWriter->writeIndexed(3, 0, instanceCount, baseInstance, 0);
+    }
+
     // Returns the index buffer that should be bound when drawing with this shader.
     // (Our vertex shader uses raw index values directly, so there is no vertex buffer.)
     static sk_sp<const GrGpuBuffer> FindOrMakeMiddleOutIndexBuffer(GrResourceProvider*);