Move fIsOval from SkPath to SkPathRef

https://codereview.chromium.org/89123002/



git-svn-id: http://skia.googlecode.com/svn/trunk/include@12450 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkPath.h b/core/SkPath.h
index ac4dd3b..5c4860e 100644
--- a/core/SkPath.h
+++ b/core/SkPath.h
@@ -151,7 +151,7 @@
      *              optimization for performance and so some paths that are in
      *              fact ovals can report false.
      */
-    bool isOval(SkRect* rect) const;
+    bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); }
 
     /** Clear any lines and curves from the path, making it empty. This frees up
         internal storage associated with those segments.
@@ -938,8 +938,8 @@
 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
         // rename to kUnused_SerializationShift
         kOldIsFinite_SerializationShift = 25,    // 1 bit
+        kOldIsOval_SerializationShift = 24,    // requires 1 bit
 #endif
-        kIsOval_SerializationShift = 24,    // requires 1 bit
         kConvexity_SerializationShift = 16, // requires 8 bits
         kFillType_SerializationShift = 8,   // requires 8 bits
         kSegmentMask_SerializationShift = 0 // requires 4 bits
@@ -952,7 +952,6 @@
     uint8_t             fSegmentMask;
     mutable uint8_t     fConvexity;
     mutable uint8_t     fDirection;
-    mutable SkBool8     fIsOval;
 #ifdef SK_BUILD_FOR_ANDROID
     const SkPath*       fSourcePath;
 #endif
diff --git a/core/SkPathRef.h b/core/SkPathRef.h
index aea0a91..1b3251e 100644
--- a/core/SkPathRef.h
+++ b/core/SkPathRef.h
@@ -23,7 +23,7 @@
  * Holds the path verbs and points. It is versioned by a generation ID. None of its public methods
  * modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an
  * SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs
- * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller passes the Editor's
+ * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's
  * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's
  * constructor returns.
  *
@@ -100,6 +100,8 @@
          */
         SkPathRef* pathRef() { return fPathRef; }
 
+        void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
+
     private:
         SkPathRef* fPathRef;
     };
@@ -121,6 +123,24 @@
         return SkToBool(fIsFinite);
     }
 
+    /** Returns true if the path is an oval.
+     *
+     * @param rect      returns the bounding rect of this oval. It's a circle
+     *                  if the height and width are the same.
+     *
+     * @return true if this path is an oval.
+     *              Tracking whether a path is an oval is considered an
+     *              optimization for performance and so some paths that are in
+     *              fact ovals can report false.
+     */
+    bool isOval(SkRect* rect) const { 
+        if (fIsOval && NULL != rect) {
+            *rect = getBounds();
+        }
+
+        return SkToBool(fIsOval);
+    }
+
     bool hasComputedBounds() const {
         return !fBoundsIsDirty;
     }
@@ -237,6 +257,7 @@
 private:
     enum SerializationOffsets {
         kIsFinite_SerializationShift = 25,  // requires 1 bit
+        kIsOval_SerializationShift = 24,    // requires 1 bit
     };
 
     SkPathRef() {
@@ -247,6 +268,7 @@
         fPoints = NULL;
         fFreeSpace = 0;
         fGenerationID = kEmptyGenID;
+        fIsOval = false;
         SkDEBUGCODE(fEditorsAttached = 0;)
         SkDEBUGCODE(this->validate();)
     }
@@ -289,6 +311,8 @@
         fBoundsIsDirty = true;      // this also invalidates fIsFinite
         fGenerationID = 0;
 
+        fIsOval = false;
+
         size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount;
         size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints;
         size_t minSize = newSize + newReserve;
@@ -394,6 +418,8 @@
      */
     static void CreateEmptyImpl(SkPathRef** empty);
 
+    void setIsOval(bool isOval) { fIsOval = isOval; }
+
     enum {
         kMinSize = 256,
     };
@@ -401,6 +427,7 @@
     mutable SkRect      fBounds;
     mutable uint8_t     fBoundsIsDirty;
     mutable SkBool8     fIsFinite;    // only meaningful if bounds are valid
+    mutable SkBool8     fIsOval;
 
     SkPoint*            fPoints; // points to begining of the allocation
     uint8_t*            fVerbs; // points just past the end of the allocation (verbs grow backwards)
diff --git a/core/SkPicture.h b/core/SkPicture.h
index 42566ed..42d9d93 100644
--- a/core/SkPicture.h
+++ b/core/SkPicture.h
@@ -219,13 +219,14 @@
     //      parameterize blurs by sigma rather than radius
     // V14: Add flags word to PathRef serialization
     // V15: Remove A1 bitmpa config (and renumber remaining configs)
+    // V16: Move SkPath's isOval flag to SkPathRef
 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO
     static const uint32_t PRIOR_PRIOR_PICTURE_VERSION = 12;  // TODO: remove when .skps regenerated
 #endif
 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
     static const uint32_t PRIOR_PICTURE_VERSION2 = 13;  // TODO: remove when .skps regenerated
 #endif
-    static const uint32_t PICTURE_VERSION = 15;
+    static const uint32_t PICTURE_VERSION = 16;
 
     // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
     // install their own SkPicturePlayback-derived players,SkPictureRecord-derived