ccpr: Fix crash on zero-length fan tessellations

Hardens the path parser to handle zero-length fan tessellations. In this
case the vertex pointer returned by the tessellator will be null, so we
need to indicate whether a tessellation exists in a different way.

Bug: skia:7642
Change-Id: If29df9d08565ff613059f2d3b49ab4eb79908495
Reviewed-on: https://skia-review.googlesource.com/113362
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp
index 43f5e6b..fd0b71d 100644
--- a/src/gpu/ccpr/GrCCPathParser.cpp
+++ b/src/gpu/ccpr/GrCCPathParser.cpp
@@ -240,8 +240,7 @@
             }
         }
 
-        fPathsInfo.back().fFanTessellation.reset(vertices);
-        fPathsInfo.back().fFanTessellationCount = count;
+        fPathsInfo.back().adoptFanTessellation(vertices, count);
     }
 
     fTotalPrimitiveCounts[(int)scissorMode] += fCurrPathPrimitiveCounts;
@@ -408,14 +407,14 @@
         switch (verb) {
             case GrCCGeometry::Verb::kBeginPath:
                 SkASSERT(currFan.empty());
-                currIndices = &instanceIndices[(int)nextPathInfo->fScissorMode];
-                atlasOffsetX = static_cast<float>(nextPathInfo->fAtlasOffsetX);
-                atlasOffsetY = static_cast<float>(nextPathInfo->fAtlasOffsetY);
+                currIndices = &instanceIndices[(int)nextPathInfo->scissorMode()];
+                atlasOffsetX = static_cast<float>(nextPathInfo->atlasOffsetX());
+                atlasOffsetY = static_cast<float>(nextPathInfo->atlasOffsetY());
                 atlasOffset = {atlasOffsetX, atlasOffsetY};
-                currFanIsTessellated = nextPathInfo->fFanTessellation.get();
+                currFanIsTessellated = nextPathInfo->hasFanTessellation();
                 if (currFanIsTessellated) {
-                    emit_tessellated_fan(nextPathInfo->fFanTessellation.get(),
-                                         nextPathInfo->fFanTessellationCount, atlasOffset,
+                    emit_tessellated_fan(nextPathInfo->fanTessellation(),
+                                         nextPathInfo->fanTessellationCount(), atlasOffset,
                                          triPointInstanceData, quadPointInstanceData, currIndices);
                 }
                 ++nextPathInfo;
diff --git a/src/gpu/ccpr/GrCCPathParser.h b/src/gpu/ccpr/GrCCPathParser.h
index d8d897f..b1a1ee5 100644
--- a/src/gpu/ccpr/GrCCPathParser.h
+++ b/src/gpu/ccpr/GrCCPathParser.h
@@ -76,14 +76,37 @@
     using PrimitiveTallies = GrCCGeometry::PrimitiveTallies;
 
     // Every kBeginPath verb has a corresponding PathInfo entry.
-    struct PathInfo {
+    class PathInfo {
+    public:
         PathInfo(ScissorMode scissorMode, int16_t offsetX, int16_t offsetY)
                 : fScissorMode(scissorMode), fAtlasOffsetX(offsetX), fAtlasOffsetY(offsetY) {}
 
+        ScissorMode scissorMode() const { return fScissorMode; }
+        int16_t atlasOffsetX() const { return fAtlasOffsetX; }
+        int16_t atlasOffsetY() const { return fAtlasOffsetY; }
+
+        // An empty tessellation fan is also valid; we use negative count to denote not tessellated.
+        bool hasFanTessellation() const { return fFanTessellationCount >= 0; }
+        int fanTessellationCount() const {
+            SkASSERT(this->hasFanTessellation());
+            return fFanTessellationCount;
+        }
+        const GrTessellator::WindingVertex* fanTessellation() const {
+            SkASSERT(this->hasFanTessellation());
+            return fFanTessellation.get();
+        }
+
+        void adoptFanTessellation(const GrTessellator::WindingVertex* vertices, int count) {
+            SkASSERT(count >= 0);
+            fFanTessellation.reset(vertices);
+            fFanTessellationCount = count;
+        }
+
+    private:
         ScissorMode fScissorMode;
         int16_t fAtlasOffsetX, fAtlasOffsetY;
-        std::unique_ptr<GrTessellator::WindingVertex[]> fFanTessellation;
-        int fFanTessellationCount = 0;
+        int fFanTessellationCount = -1;
+        std::unique_ptr<const GrTessellator::WindingVertex[]> fFanTessellation;
     };
 
     // Defines a batch of CCPR primitives. Start indices are deduced by looking at the previous