Use SkPathRef gen id for SkPath::getGenerationID

R=mtklein@google.com, robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/49693002

git-svn-id: http://skia.googlecode.com/svn/trunk/src@12029 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkPath.cpp b/core/SkPath.cpp
index 8f79fbe..83f481a 100644
--- a/core/SkPath.cpp
+++ b/core/SkPath.cpp
@@ -147,7 +147,7 @@
 SkPath::SkPath()
     : fPathRef(SkPathRef::CreateEmpty())
 #ifdef SK_BUILD_FOR_ANDROID
-    , fGenerationID(0)
+    , fSourcePath(NULL)
 #endif
 {
     this->resetFields();
@@ -161,18 +161,15 @@
     fConvexity = kUnknown_Convexity;
     fDirection = kUnknown_Direction;
     fIsOval = false;
-#ifdef SK_BUILD_FOR_ANDROID
-    GEN_ID_INC;
-    // We don't touch fSourcePath.  It's used to track texture garbage collection, so we don't
-    // want to muck with it if it's been set to something non-NULL.
-#endif
+
+    // We don't touch Android's fSourcePath.  It's used to track texture garbage collection, so we
+    // don't want to muck with it if it's been set to something non-NULL.
 }
 
 SkPath::SkPath(const SkPath& that)
     : fPathRef(SkRef(that.fPathRef.get())) {
     this->copyFields(that);
 #ifdef SK_BUILD_FOR_ANDROID
-    fGenerationID = that.fGenerationID;
     fSourcePath   = that.fSourcePath;
 #endif
     SkDEBUGCODE(that.validate();)
@@ -189,7 +186,6 @@
         fPathRef.reset(SkRef(that.fPathRef.get()));
         this->copyFields(that);
 #ifdef SK_BUILD_FOR_ANDROID
-        GEN_ID_INC;  // Similar to swap, we can't just copy this or it could go back in time.
         fSourcePath = that.fSourcePath;
 #endif
     }
@@ -232,10 +228,6 @@
         SkTSwap<uint8_t>(fDirection, that.fDirection);
         SkTSwap<SkBool8>(fIsOval, that.fIsOval);
 #ifdef SK_BUILD_FOR_ANDROID
-        // It doesn't really make sense to swap the generation IDs here, because they might go
-        // backwards.  To be safe we increment both to mark them both as changed.
-        GEN_ID_INC;
-        GEN_ID_PTR_INC(&that);
         SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath);
 #endif
     }
@@ -328,11 +320,16 @@
     return check_edge_against_rect(prevPt, firstPt, rect, direction);
 }
 
-#ifdef SK_BUILD_FOR_ANDROID
 uint32_t SkPath::getGenerationID() const {
-    return fGenerationID;
+    uint32_t genID = fPathRef->genID();
+#ifdef SK_BUILD_FOR_ANDROID
+    SkASSERT((unsigned)fFillType < (1 << (32 - kPathRefGenIDBitCnt)));
+    genID |= static_cast<uint32_t>(fFillType) << kPathRefGenIDBitCnt;
+#endif
+    return genID;
 }
 
+#ifdef SK_BUILD_FOR_ANDROID
 const SkPath* SkPath::getSourcePath() const {
     return fSourcePath;
 }
@@ -633,14 +630,12 @@
         fIsOval = false;
         SkPathRef::Editor ed(&fPathRef);
         ed.atPoint(count-1)->set(x, y);
-        GEN_ID_INC;
     }
 }
 
 void SkPath::setConvexity(Convexity c) {
     if (fConvexity != c) {
         fConvexity = c;
-        GEN_ID_INC;
     }
 }
 
@@ -669,8 +664,6 @@
     fLastMoveToIndex = ed.pathRef()->countPoints();
 
     ed.growForVerb(kMove_Verb)->set(x, y);
-
-    GEN_ID_INC;
 }
 
 void SkPath::rMoveTo(SkScalar x, SkScalar y) {
@@ -702,7 +695,6 @@
     ed.growForVerb(kLine_Verb)->set(x, y);
     fSegmentMask |= kLine_SegmentMask;
 
-    GEN_ID_INC;
     DIRTY_AFTER_EDIT;
 }
 
@@ -724,7 +716,6 @@
     pts[1].set(x2, y2);
     fSegmentMask |= kQuad_SegmentMask;
 
-    GEN_ID_INC;
     DIRTY_AFTER_EDIT;
 }
 
@@ -756,7 +747,6 @@
         pts[1].set(x2, y2);
         fSegmentMask |= kConic_SegmentMask;
 
-        GEN_ID_INC;
         DIRTY_AFTER_EDIT;
     }
 }
@@ -782,7 +772,6 @@
     pts[2].set(x3, y3);
     fSegmentMask |= kCubic_SegmentMask;
 
-    GEN_ID_INC;
     DIRTY_AFTER_EDIT;
 }
 
@@ -808,7 +797,6 @@
             case kMove_Verb: {
                 SkPathRef::Editor ed(&fPathRef);
                 ed.growForVerb(kClose_Verb);
-                GEN_ID_INC;
                 break;
             }
             case kClose_Verb:
@@ -894,7 +882,6 @@
         vb[~count] = kClose_Verb;
     }
 
-    GEN_ID_INC;
     DIRTY_AFTER_EDIT;
     SkDEBUGCODE(this->validate();)
 }
@@ -1720,12 +1707,6 @@
             dst->fConvexity = fConvexity;
         }
 
-#ifdef SK_BUILD_FOR_ANDROID
-        if (!matrix.isIdentity() && !dst->hasComputedBounds()) {
-            GEN_ID_PTR_INC(dst);
-        }
-#endif
-
         if (kUnknown_Direction == fDirection) {
             dst->fDirection = kUnknown_Direction;
         } else {
@@ -2134,8 +2115,6 @@
 
     buffer.skipToAlign4();
 
-    GEN_ID_INC;
-
     SkDEBUGCODE(this->validate();)
     return SkToU32(buffer.pos());
 }
diff --git a/core/SkPathRef.cpp b/core/SkPathRef.cpp
index f635c2a..f811b24 100644
--- a/core/SkPathRef.cpp
+++ b/core/SkPathRef.cpp
@@ -289,8 +289,9 @@
     return ret;
 }
 
-int32_t SkPathRef::genID() const {
+uint32_t SkPathRef::genID() const {
     SkASSERT(!fEditorsAttached);
+    static const uint32_t kMask = (static_cast<int64_t>(1) << SkPath::kPathRefGenIDBitCnt) - 1;
     if (!fGenerationID) {
         if (0 == fPointCnt && 0 == fVerbCnt) {
             fGenerationID = kEmptyGenID;
@@ -299,7 +300,7 @@
             // do a loop in case our global wraps around, as we never want to return a 0 or the
             // empty ID
             do {
-                fGenerationID = sk_atomic_inc(&gPathRefGenerationID) + 1;
+                fGenerationID = (sk_atomic_inc(&gPathRefGenerationID) + 1) & kMask;
             } while (fGenerationID <= kEmptyGenID);
         }
     }