Revert of r13379 (Move fLastMoveToIndex from SkPath to SkPathRef - https://codereview.chromium.org/146913002/) due to image quality regression in Chromium. See crbug.com/343123 (Regression - UI issue observed for any "Notification infobars" in Chrome browser)

R=bsalomon@google.com
TBR=bsalomon@google.com

Author: robertphillips@google.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk@13421 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 0f43fe8..d78cd88 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -978,6 +978,7 @@
 
     SkAutoTUnref<SkPathRef> fPathRef;
 
+    int                 fLastMoveToIndex;
     uint8_t             fFillType;
     mutable uint8_t     fConvexity;
     mutable uint8_t     fDirection;
@@ -1013,10 +1014,7 @@
     //  SkPath path; path.lineTo(...);   <--- need a leading moveTo(0, 0)
     // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
     //
-    void injectMoveToIfNeeded() {
-        SkPathRef::Editor ed(&fPathRef);
-        ed.injectMoveToIfNeeded();
-    }
+    inline void injectMoveToIfNeeded();
 
     inline bool hasOnlyMoveTos() const;
 
diff --git a/include/core/SkPathRef.h b/include/core/SkPathRef.h
index 2e8c547..8802714 100644
--- a/include/core/SkPathRef.h
+++ b/include/core/SkPathRef.h
@@ -104,13 +104,6 @@
 
         void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); }
 
-        // In some cases we need to inject a leading moveTo before we add points
-        // for lineTo, quadTo, conicTo, cubicTo
-        //
-        // SkPath path; path.lineTo(...);   <--- need a leading moveTo(0, 0)
-        // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
-        void injectMoveToIfNeeded() { fPathRef->injectMoveToIfNeeded(); }
-
     private:
         SkPathRef* fPathRef;
     };
@@ -261,9 +254,6 @@
     uint32_t genID() const;
 
 private:
-    // flag to require a moveTo if we begin with something else, like lineTo etc.
-    static const int kINITIAL_LASTMOVETOINDEX_VALUE = ~0;
-
     enum SerializationOffsets {
         kIsFinite_SerializationShift = 25,  // requires 1 bit
         kIsOval_SerializationShift = 24,    // requires 1 bit
@@ -271,7 +261,6 @@
     };
 
     SkPathRef() {
-        fLastMoveToIndex = kINITIAL_LASTMOVETOINDEX_VALUE;
         fBoundsIsDirty = true;    // this also invalidates fIsFinite
         fPointCnt = 0;
         fVerbCnt = 0;
@@ -359,8 +348,6 @@
         SkDEBUGCODE(this->validate();)
     }
 
-    void injectMoveToIfNeeded();
-
     /**
      * Increases the verb count by numVbs and point count by the required amount.
      * The new points are uninitialized. All the new verbs are set to the specified
@@ -446,7 +433,6 @@
     };
 
     mutable SkRect      fBounds;
-    int                 fLastMoveToIndex;
     uint8_t             fSegmentMask;
     mutable uint8_t     fBoundsIsDirty;
     mutable SkBool8     fIsFinite;    // only meaningful if bounds are valid
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index ea93963..9f94b72 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -122,6 +122,9 @@
 
 ////////////////////////////////////////////////////////////////////////////
 
+// flag to require a moveTo if we begin with something else, like lineTo etc.
+#define INITIAL_LASTMOVETOINDEX_VALUE   ~0
+
 SkPath::SkPath()
     : fPathRef(SkPathRef::CreateEmpty())
 #ifdef SK_BUILD_FOR_ANDROID
@@ -133,6 +136,7 @@
 
 void SkPath::resetFields() {
     //fPathRef is assumed to have been emptied by the caller.
+    fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
     fFillType = kWinding_FillType;
     fConvexity = kUnknown_Convexity;
     fDirection = kUnknown_Direction;
@@ -170,6 +174,7 @@
 
 void SkPath::copyFields(const SkPath& that) {
     //fPathRef is assumed to have been set by the caller.
+    fLastMoveToIndex = that.fLastMoveToIndex;
     fFillType        = that.fFillType;
     fConvexity       = that.fConvexity;
     fDirection       = that.fDirection;
@@ -187,6 +192,7 @@
 
     if (this != &that) {
         fPathRef.swap(&that.fPathRef);
+        SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
         SkTSwap<uint8_t>(fFillType, that.fFillType);
         SkTSwap<uint8_t>(fConvexity, that.fConvexity);
         SkTSwap<uint8_t>(fDirection, that.fDirection);
@@ -661,6 +667,9 @@
 
     SkPathRef::Editor ed(&fPathRef);
 
+    // remember our index
+    fLastMoveToIndex = fPathRef->countPoints();
+
     ed.growForVerb(kMove_Verb)->set(x, y);
 }
 
@@ -670,11 +679,26 @@
     this->moveTo(pt.fX + x, pt.fY + y);
 }
 
+void SkPath::injectMoveToIfNeeded() {
+    if (fLastMoveToIndex < 0) {
+        SkScalar x, y;
+        if (fPathRef->countVerbs() == 0) {
+            x = y = 0;
+        } else {
+            const SkPoint& pt = fPathRef->atPoint(~fLastMoveToIndex);
+            x = pt.fX;
+            y = pt.fY;
+        }
+        this->moveTo(x, y);
+    }
+}
+
 void SkPath::lineTo(SkScalar x, SkScalar y) {
     SkDEBUGCODE(this->validate();)
 
+    this->injectMoveToIfNeeded();
+
     SkPathRef::Editor ed(&fPathRef);
-    ed.injectMoveToIfNeeded();
     ed.growForVerb(kLine_Verb)->set(x, y);
 
     DIRTY_AFTER_EDIT;
@@ -690,8 +714,9 @@
 void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
     SkDEBUGCODE(this->validate();)
 
+    this->injectMoveToIfNeeded();
+
     SkPathRef::Editor ed(&fPathRef);
-    ed.injectMoveToIfNeeded();
     SkPoint* pts = ed.growForVerb(kQuad_Verb);
     pts[0].set(x1, y1);
     pts[1].set(x2, y2);
@@ -719,8 +744,9 @@
     } else {
         SkDEBUGCODE(this->validate();)
 
+        this->injectMoveToIfNeeded();
+
         SkPathRef::Editor ed(&fPathRef);
-        ed.injectMoveToIfNeeded();
         SkPoint* pts = ed.growForVerb(kConic_Verb, w);
         pts[0].set(x1, y1);
         pts[1].set(x2, y2);
@@ -741,8 +767,9 @@
                      SkScalar x3, SkScalar y3) {
     SkDEBUGCODE(this->validate();)
 
+    this->injectMoveToIfNeeded();
+
     SkPathRef::Editor ed(&fPathRef);
-    ed.injectMoveToIfNeeded();
     SkPoint* pts = ed.growForVerb(kCubic_Verb);
     pts[0].set(x1, y1);
     pts[1].set(x2, y2);
@@ -783,6 +810,15 @@
                 break;
         }
     }
+
+    // signal that we need a moveTo to follow us (unless we're done)
+#if 0
+    if (fLastMoveToIndex >= 0) {
+        fLastMoveToIndex = ~fLastMoveToIndex;
+    }
+#else
+    fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1);
+#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -824,6 +860,8 @@
         return;
     }
 
+    fLastMoveToIndex = fPathRef->countPoints();
+
     // +close makes room for the extra kClose_Verb
     SkPathRef::Editor ed(&fPathRef, count+close, count);
 
@@ -1320,6 +1358,8 @@
     SkDEBUGCODE(this->validate();)
     SkASSERT(count & 1);
 
+    fLastMoveToIndex = fPathRef->countPoints();
+
     SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count);
 
     ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY);
diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp
index 1272cf2..161eb80 100644
--- a/src/core/SkPathRef.cpp
+++ b/src/core/SkPathRef.cpp
@@ -154,7 +154,6 @@
 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) {
     if ((*pathRef)->unique()) {
         SkDEBUGCODE((*pathRef)->validate();)
-        (*pathRef)->fLastMoveToIndex = kINITIAL_LASTMOVETOINDEX_VALUE;
         (*pathRef)->fBoundsIsDirty = true;  // this also invalidates fIsFinite
         (*pathRef)->fVerbCnt = 0;
         (*pathRef)->fPointCnt = 0;
@@ -277,20 +276,6 @@
     SkDEBUGCODE(this->validate();)
 }
 
-void SkPathRef::injectMoveToIfNeeded() {
-    if (fLastMoveToIndex < 0) {
-        SkScalar x, y;
-        if (this->countVerbs() == 0) {
-            x = y = 0;
-        } else {
-            const SkPoint& pt = this->atPoint(~fLastMoveToIndex);
-            x = pt.fX;
-            y = pt.fY;
-        }
-        this->growForVerb(SkPath::kMove_Verb, 0)->set(x, y);
-    }
-}
-
 SkPoint* SkPathRef::growForRepeatedVerb(int /*SkPath::Verb*/ verb,
                                         int numVbs,
                                         SkScalar** weights) {
@@ -299,16 +284,11 @@
     // future this will appear to have been a fluke...
     static const unsigned int kMIN_COUNT_FOR_MEMSET_TO_BE_FAST = 16;
 
-    if (numVbs <= 0) {
-        return NULL;
-    }
-
     SkDEBUGCODE(this->validate();)
     int pCnt;
     bool dirtyAfterEdit = true;
     switch (verb) {
         case SkPath::kMove_Verb:
-            fLastMoveToIndex = fPointCnt + numVbs - 1;
             pCnt = numVbs;
             dirtyAfterEdit = false;
             break;
@@ -330,8 +310,6 @@
             break;
         case SkPath::kClose_Verb:
             SkDEBUGFAIL("growForRepeatedVerb called for kClose_Verb");
-            // signal that we need a moveTo to follow us (unless we're done)
-            fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1);
             pCnt = 0;
             dirtyAfterEdit = false;
             break;
@@ -383,8 +361,6 @@
     bool dirtyAfterEdit = true;
     switch (verb) {
         case SkPath::kMove_Verb:
-            // remember our index
-            fLastMoveToIndex = fPointCnt;
             pCnt = 1;
             dirtyAfterEdit = false;
             break;
@@ -405,8 +381,6 @@
             pCnt = 3;
             break;
         case SkPath::kClose_Verb:
-            // signal that we need a moveTo to follow us (unless we're done)
-            fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1);
             pCnt = 0;
             dirtyAfterEdit = false;
             break;
@@ -486,34 +460,23 @@
 
 #ifdef SK_DEBUG_PATH
     uint32_t mask = 0;
-    int lastMoveToIndex = kINITIAL_LASTMOVETOINDEX_VALUE;
-    int pointCnt = 0;
     for (int i = 0; i < fVerbCnt; ++i) {
         switch (fVerbs[~i]) {
             case SkPath::kMove_Verb:
-                lastMoveToIndex = pointCnt;
-                ++pointCnt;
                 break;
             case SkPath::kLine_Verb:
                 mask |= SkPath::kLine_SegmentMask;
-                ++pointCnt;
                 break;
             case SkPath::kQuad_Verb:
                 mask |= SkPath::kQuad_SegmentMask;
-                pointCnt += 2;
                 break;
             case SkPath::kConic_Verb:
                 mask |= SkPath::kConic_SegmentMask;
-                pointCnt += 2;
                 break;
             case SkPath::kCubic_Verb:
                 mask |= SkPath::kCubic_SegmentMask;
-                pointCnt += 3;
                 break;
             case SkPath::kClose_Verb:
-                if (lastMoveToIndex >= 0) {
-                    lastMoveToIndex = ~lastMoveToIndex;
-                }
                 break;
             case SkPath::kDone_Verb:
                 SkDEBUGFAIL("Done verb shouldn't be recorded.");
@@ -524,8 +487,6 @@
         }
     }
     SkASSERT(mask == fSegmentMask);
-    SkASSERT(lastMoveToIndex == fLastMoveToIndex);
-    SkASSERT(pointCnt == fPointCnt);
 #endif // SK_DEBUG_PATH
 }
 #endif