Include conic weights in GrPath cache kSimpleVolatilePathDomain keys

Include conic weights in the keys when caching GrPath in
kSimpleVolatilePathDomain.

BUG=skia:4580

Review URL: https://codereview.chromium.org/1472733002
diff --git a/src/gpu/GrPath.cpp b/src/gpu/GrPath.cpp
index 8ac356d..71c13af 100644
--- a/src/gpu/GrPath.cpp
+++ b/src/gpu/GrPath.cpp
@@ -78,6 +78,19 @@
         SkASSERT(false);
         return false;
     }
+    SkSTArray<16, SkScalar, true> conicWeights(16);
+    if ((path.getSegmentMasks() & SkPath::kConic_SegmentMask) != 0) {
+        SkPath::RawIter iter(path);
+        SkPath::Verb verb;
+        SkPoint points[4];
+        while ((verb = iter.next(points)) != SkPath::kDone_Verb) {
+            if (verb == SkPath::kConic_Verb) {
+                conicWeights.push_back(iter.conicWeight());
+            }
+        }
+    }
+
+    const int conicWeightCnt = conicWeights.count();
 
     // Construct counts that align as uint32_t counts.
 #define ARRAY_DATA32_COUNT(array_type, count) \
@@ -85,16 +98,17 @@
 
     const int verbData32Cnt = ARRAY_DATA32_COUNT(uint8_t, verbCnt);
     const int pointData32Cnt = ARRAY_DATA32_COUNT(SkPoint, pointCnt);
+    const int conicWeightData32Cnt = ARRAY_DATA32_COUNT(SkScalar, conicWeightCnt);
 
 #undef ARRAY_DATA32_COUNT
 
     // The unique key data is a "message" with following fragments:
     // 0) domain, key length, uint32_t for fill type and uint32_t for verbCnt
     //   (fragment 0, fixed size)
-    // 1) verb and point data (varying size)
+    // 1) verb, point data and conic weights (varying size)
     // 2) stroke data (varying size)
 
-    const int baseData32Cnt = 2 + verbData32Cnt + pointData32Cnt;
+    const int baseData32Cnt = 2 + verbData32Cnt + pointData32Cnt + conicWeightData32Cnt;
     const int strokeDataCnt = stroke.computeUniqueKeyFragmentData32Cnt();
     static const GrUniqueKey::Domain kSimpleVolatilePathDomain = GrUniqueKey::GenerateDomain();
     GrUniqueKey::Builder builder(key, kSimpleVolatilePathDomain, baseData32Cnt + strokeDataCnt);
@@ -103,11 +117,12 @@
 
     // Serialize the verbCnt to make the whole message unambiguous.
     // We serialize two variable length fragments to the message:
-    // * verb and point data (fragment 1)
+    // * verbs, point data and conic weights (fragment 1)
     // * stroke data (fragment 2)
     // "Proof:"
     // Verb count establishes unambiguous verb data.
-    // Unambiguous verb data establishes unambiguous point data, making fragment 1 unambiguous.
+    // Verbs encode also point data size and conic weight size.
+    // Thus the fragment 1 is unambiguous.
     // Unambiguous fragment 1 establishes unambiguous fragment 2, since the length of the message
     // has been established.
 
@@ -127,8 +142,16 @@
 
     // Here we assume getPoints does a memcpy, so that we do not need to worry about the alignment.
     path.getPoints(reinterpret_cast<SkPoint*>(&builder[i]), pointCnt);
-    SkDEBUGCODE(i += pointData32Cnt);
+    i += pointData32Cnt;
 
+    if (conicWeightCnt > 0) {
+        if (conicWeightData32Cnt != static_cast<int>(
+                (conicWeightCnt * sizeof(SkScalar) / sizeof(uint32_t)))) {
+            builder[i + conicWeightData32Cnt - 1] = 0;
+        }
+        memcpy(&builder[i], conicWeights.begin(), conicWeightCnt * sizeof(SkScalar));
+        SkDEBUGCODE(i += conicWeightData32Cnt);
+    }
     SkASSERT(i == baseData32Cnt);
     if (strokeDataCnt > 0) {
         stroke.asUniqueKeyFragment(&builder[baseData32Cnt]);
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index 42083fe..7a6be6d 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -128,9 +128,7 @@
     GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
     GrPath::ComputeKey(path1, stroke, &key1, &isVolatile);
     GrPath::ComputeKey(path2, stroke, &key2, &isVolatile);
-
-    // https://bugs.chromium.org/p/skia/issues/detail?id=4580
-    // REPORTER_ASSERT(reporter, key1 != key2);
+    REPORTER_ASSERT(reporter, key1 != key2);
 }
 
 #endif