Merge from Chromium at DEPS revision 241094

This commit was generated by merge_to_master.py.

Change-Id: Idd43ea2a927fa7b7581a9c3ad66a4d5d2e86bb43
diff --git a/core/SkMallocPixelRef.h b/core/SkMallocPixelRef.h
index 100a15d..ba0b953 100644
--- a/core/SkMallocPixelRef.h
+++ b/core/SkMallocPixelRef.h
@@ -17,33 +17,54 @@
 */
 class SkMallocPixelRef : public SkPixelRef {
 public:
-    /** Allocate the specified buffer for pixels. The memory is freed when the
-        last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw()
-        is called to allocate it.
+    /**
+     *  Return a new SkMallocPixelRef with the provided pixel storage, rowBytes,
+     *  and optional colortable. The caller is responsible for managing the
+     *  lifetime of the pixel storage buffer, as this pixelref will not try
+     *  to delete it.
+     *
+     *  The pixelref will ref() the colortable (if not NULL).
+     *
+     *  Returns NULL on failure.
      */
-    SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable, bool ownPixels = true);
-    virtual ~SkMallocPixelRef();
+    static SkMallocPixelRef* NewDirect(const SkImageInfo&, void* addr,
+                                       size_t rowBytes, SkColorTable*);
 
+    /**
+     *  Return a new SkMallocPixelRef, automatically allocating storage for the
+     *  pixels.
+     *
+     *  If rowBytes is 0, an optimal value will be chosen automatically.
+     *  If rowBytes is > 0, then it will be used, unless it is invald for the
+     *  specified info, in which case NULL will be returned (failure).
+     *
+     *  This pixelref will ref() the specified colortable (if not NULL).
+     *
+     *  Returns NULL on failure.
+     */
+    static SkMallocPixelRef* NewAllocate(const SkImageInfo& info,
+                                         size_t rowBytes, SkColorTable*);
+    
     void* getAddr() const { return fStorage; }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
 
 protected:
-    // overrides from SkPixelRef
-    virtual void* onLockPixels(SkColorTable**);
-    virtual void onUnlockPixels();
-
+    SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
+                     bool ownPixels);
     SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
-    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+    virtual ~SkMallocPixelRef();
 
-    // Returns the allocation size for the pixels
-    virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE { return fSize; }
+    virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
+    virtual void onUnlockPixels() SK_OVERRIDE;
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+    virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
 
 private:
     void*           fStorage;
-    size_t          fSize;
     SkColorTable*   fCTable;
-    bool            fOwnPixels;
+    size_t          fRB;
+    const bool      fOwnPixels;
 
     typedef SkPixelRef INHERITED;
 };
diff --git a/core/SkPath.h b/core/SkPath.h
index 0b2ea61..9b3f281 100644
--- a/core/SkPath.h
+++ b/core/SkPath.h
@@ -83,7 +83,7 @@
      */
     void toggleInverseFillType() {
         fFillType ^= 2;
-     }
+    }
 
     enum Convexity {
         kUnknown_Convexity,
@@ -446,8 +446,8 @@
         @param dy3   The amount to add to the y-coordinate of the last point on
                      this contour, to specify the end point of a cubic curve
     */
-    void    rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
-                     SkScalar x3, SkScalar y3);
+    void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+                  SkScalar x3, SkScalar y3);
 
     /** Append the specified arc to the path as a new contour. If the start of
         the path is different from the path's current last point, then an
@@ -461,8 +461,8 @@
                           treated mod 360.
         @param forceMoveTo If true, always begin a new contour with the arc
     */
-    void    arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
-                  bool forceMoveTo);
+    void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
+               bool forceMoveTo);
 
     /** Append a line and arc to the current path. This is the same as the
         PostScript call "arct".
@@ -778,7 +778,7 @@
      *  set if the path contains 1 or more segments of that type.
      *  Returns 0 for an empty path (no segments).
      */
-    uint32_t getSegmentMasks() const { return fSegmentMask; }
+    uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
 
     enum Verb {
         kMove_Verb,     //!< iter.next returns 1 point
@@ -942,14 +942,15 @@
 #endif
         kConvexity_SerializationShift = 16, // requires 8 bits
         kFillType_SerializationShift = 8,   // requires 8 bits
-        kSegmentMask_SerializationShift = 0 // requires 4 bits
+#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
+        kOldSegmentMask_SerializationShift = 0 // requires 4 bits
+#endif
     };
 
     SkAutoTUnref<SkPathRef> fPathRef;
 
     int                 fLastMoveToIndex;
     uint8_t             fFillType;
-    uint8_t             fSegmentMask;
     mutable uint8_t     fConvexity;
     mutable uint8_t     fDirection;
 #ifdef SK_BUILD_FOR_ANDROID
@@ -1004,7 +1005,9 @@
 
     // 'rect' needs to be sorted
     void setBounds(const SkRect& rect) {
-        fPathRef->setBounds(rect);
+        SkPathRef::Editor ed(&fPathRef);
+
+        ed.setBounds(rect);
     }
 
 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
diff --git a/core/SkPathRef.h b/core/SkPathRef.h
index 5d55c72..c55f549 100644
--- a/core/SkPathRef.h
+++ b/core/SkPathRef.h
@@ -49,7 +49,8 @@
         /**
          * Returns the array of points.
          */
-        SkPoint* points() { return fPathRef->fPoints; }
+        SkPoint* points() { return fPathRef->getPoints(); }
+        const SkPoint* points() const { return fPathRef->points(); }
 
         /**
          * Gets the ith point. Shortcut for this->points() + i
@@ -58,34 +59,32 @@
             SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
             return this->points() + i;
         };
+        const SkPoint* atPoint(int i) const {
+            SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
+            return this->points() + i;
+        };
 
         /**
          * Adds the verb and allocates space for the number of points indicated by the verb. The
          * return value is a pointer to where the points for the verb should be written.
+         * 'weight' is only used if 'verb' is kConic_Verb
          */
-        SkPoint* growForVerb(int /*SkPath::Verb*/ verb) {
+        SkPoint* growForVerb(int /*SkPath::Verb*/ verb, SkScalar weight = 0) {
             SkDEBUGCODE(fPathRef->validate();)
-            return fPathRef->growForVerb(verb);
+            return fPathRef->growForVerb(verb, weight);
         }
 
-        SkPoint* growForConic(SkScalar w);
-
         /**
-         * Allocates space for additional verbs and points and returns pointers to the new verbs and
-         * points. verbs will point one beyond the first new verb (index it using [~<i>]). pts points
-         * at the first new point (indexed normally [<i>]).
+         * Allocates space for multiple instances of a particular verb and the
+         * requisite points & weights.
+         * The return pointer points at the first new point (indexed normally [<i>]).
+         * If 'verb' is kConic_Verb, 'weights' will return a pointer to the
+         * space for the conic weights (indexed normally). 
          */
-        void grow(int newVerbs, int newPts, uint8_t** verbs, SkPoint** pts) {
-            SkASSERT(NULL != verbs);
-            SkASSERT(NULL != pts);
-            SkDEBUGCODE(fPathRef->validate();)
-            int oldVerbCnt = fPathRef->fVerbCnt;
-            int oldPointCnt = fPathRef->fPointCnt;
-            SkASSERT(verbs && pts);
-            fPathRef->grow(newVerbs, newPts);
-            *verbs = fPathRef->fVerbs - oldVerbCnt;
-            *pts = fPathRef->fPoints + oldPointCnt;
-            SkDEBUGCODE(fPathRef->validate();)
+        SkPoint* growForRepeatedVerb(int /*SkPath::Verb*/ verb, 
+                                     int numVbs, 
+                                     SkScalar** weights = NULL) { 
+            return fPathRef->growForRepeatedVerb(verb, numVbs, weights); 
         }
 
         /**
@@ -95,6 +94,7 @@
         void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) {
             fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount);
         }
+
         /**
          * Gets the path ref that is wrapped in the Editor.
          */
@@ -102,6 +102,8 @@
 
         void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
 
+        void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); }
+
     private:
         SkPathRef* fPathRef;
     };
@@ -123,6 +125,13 @@
         return SkToBool(fIsFinite);
     }
 
+    /**
+     *  Returns a mask, where each bit corresponding to a SegmentMask is
+     *  set if the path contains 1 or more segments of that type.
+     *  Returns 0 for an empty path (no segments).
+     */
+    uint32_t getSegmentMasks() const { return fSegmentMask; }
+
     /** Returns true if the path is an oval.
      *
      * @param rect      returns the bounding rect of this oval. It's a circle
@@ -157,13 +166,6 @@
         return fBounds;
     }
 
-    void setBounds(const SkRect& rect) {
-        SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
-        fBounds = rect;
-        fBoundsIsDirty = false;
-        fIsFinite = fBounds.isFinite();
-    }
-
     /**
      * Transforms a path ref by a matrix, allocating a new one only if necessary.
      */
@@ -199,6 +201,7 @@
 
     int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; }
     int countVerbs() const { SkDEBUGCODE(this->validate();) return fVerbCnt; }
+    int countWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.count(); }
 
     /**
      * Returns a pointer one beyond the first logical verb (last verb in memory order).
@@ -226,7 +229,7 @@
     /**
      * Convenience methods for getting to a verb or point by index.
      */
-    uint8_t atVerb(int index) {
+    uint8_t atVerb(int index) const {
         SkASSERT((unsigned) index < (unsigned) fVerbCnt);
         return this->verbs()[~index];
     }
@@ -240,12 +243,12 @@
     /**
      * Writes the path points and verbs to a buffer.
      */
-    void writeToBuffer(SkWBuffer* buffer);
+    void writeToBuffer(SkWBuffer* buffer) const;
 
     /**
      * Gets the number of bytes that would be written in writeBuffer()
      */
-    uint32_t writeSize();
+    uint32_t writeSize() const;
 
     /**
      * Gets an ID that uniquely identifies the contents of the path ref. If two path refs have the
@@ -258,6 +261,7 @@
     enum SerializationOffsets {
         kIsFinite_SerializationShift = 25,  // requires 1 bit
         kIsOval_SerializationShift = 24,    // requires 1 bit
+        kSegmentMask_SerializationShift = 0 // requires 4 bits
     };
 
     SkPathRef() {
@@ -268,6 +272,7 @@
         fPoints = NULL;
         fFreeSpace = 0;
         fGenerationID = kEmptyGenID;
+        fSegmentMask = 0;
         fIsOval = false;
         SkDEBUGCODE(fEditorsAttached = 0;)
         SkDEBUGCODE(this->validate();)
@@ -295,6 +300,13 @@
         fBoundsIsDirty = false;
     }
 
+    void setBounds(const SkRect& rect) {
+        SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
+        fBounds = rect;
+        fBoundsIsDirty = false;
+        fIsFinite = fBounds.isFinite();
+    }
+
     /** Makes additional room but does not change the counts or change the genID */
     void incReserve(int additionalVerbs, int additionalPoints) {
         SkDEBUGCODE(this->validate();)
@@ -311,6 +323,7 @@
         fBoundsIsDirty = true;      // this also invalidates fIsFinite
         fGenerationID = 0;
 
+        fSegmentMask = 0;
         fIsOval = false;
 
         size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount;
@@ -340,26 +353,19 @@
     }
 
     /**
-     * Increases the verb count by newVerbs and the point count be newPoints. New verbs and points
-     * are uninitialized.
+     * 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 
+     * verb. If 'verb' is kConic_Verb, 'weights' will return a pointer to the
+     * uninitialized conic weights.
      */
-    void grow(int newVerbs, int newPoints) {
-        SkDEBUGCODE(this->validate();)
-        size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint);
-        this->makeSpace(space);
-        fVerbCnt += newVerbs;
-        fPointCnt += newPoints;
-        fFreeSpace -= space;
-        fBoundsIsDirty = true;  // this also invalidates fIsFinite
-        SkDEBUGCODE(this->validate();)
-    }
+    SkPoint* growForRepeatedVerb(int /*SkPath::Verb*/ verb, int numVbs, SkScalar** weights);
 
     /**
      * Increases the verb count 1, records the new verb, and creates room for the requisite number
      * of additional points. A pointer to the first point is returned. Any new points are
      * uninitialized.
      */
-    SkPoint* growForVerb(int /*SkPath::Verb*/ verb);
+    SkPoint* growForVerb(int /*SkPath::Verb*/ verb, SkScalar weight);
 
     /**
      * Ensures that the free space available in the path ref is >= size. The verb and point counts
@@ -420,11 +426,18 @@
 
     void setIsOval(bool isOval) { fIsOval = isOval; }
 
+    SkPoint* getPoints() { 
+        SkDEBUGCODE(this->validate();) 
+        fIsOval = false;
+        return fPoints; 
+    }
+
     enum {
         kMinSize = 256,
     };
 
     mutable SkRect      fBounds;
+    uint8_t             fSegmentMask;
     mutable uint8_t     fBoundsIsDirty;
     mutable SkBool8     fIsFinite;    // only meaningful if bounds are valid
     mutable SkBool8     fIsOval;
@@ -442,6 +455,7 @@
     mutable uint32_t    fGenerationID;
     SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time.
 
+    friend class PathRefTest_Private;
     typedef SkRefCnt INHERITED;
 };
 
diff --git a/core/SkPicture.h b/core/SkPicture.h
index bce343e..a1d7644 100644
--- a/core/SkPicture.h
+++ b/core/SkPicture.h
@@ -220,10 +220,11 @@
     // V14: Add flags word to PathRef serialization
     // V15: Remove A1 bitmpa config (and renumber remaining configs)
     // V16: Move SkPath's isOval flag to SkPathRef
+    // V17: SkPixelRef now writes SkImageInfo
 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
     static const uint32_t PRIOR_PICTURE_VERSION = 15;  // TODO: remove when .skps regenerated
 #endif
-    static const uint32_t PICTURE_VERSION = 16;
+    static const uint32_t PICTURE_VERSION = 17;
 
     // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
     // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
diff --git a/core/SkPixelRef.h b/core/SkPixelRef.h
index b87b0dc..4369e5d 100644
--- a/core/SkPixelRef.h
+++ b/core/SkPixelRef.h
@@ -16,7 +16,7 @@
 #include "SkFlattenable.h"
 #include "SkTDArray.h"
 
-#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
+//#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
 
 #ifdef SK_DEBUG
     /**
@@ -244,10 +244,15 @@
         acquire a mutex for thread safety, so this method need not do that.
     */
     virtual void* onLockPixels(SkColorTable**) = 0;
-    /** Called when the lock count goes from 1 to 0. The caller will have
-        already acquire a mutex for thread safety, so this method need not do
-        that.
-    */
+ 
+    /**
+     *  Called when the lock count goes from 1 to 0. The caller will have
+     *  already acquire a mutex for thread safety, so this method need not do
+     *  that.
+     *
+     *  If the previous call to onLockPixels failed (i.e. returned NULL), then
+     *  the onUnlockPixels will NOT be called.
+     */
     virtual void onUnlockPixels() = 0;
 
     /** Default impl returns true */
@@ -295,6 +300,8 @@
 
 private:
     SkBaseMutex*    fMutex; // must remain in scope for the life of this object
+    // FIXME: fInfo should be const once we remove old constructor that does
+    // not set it.
     SkImageInfo     fInfo;
 
     void*           fPixels;
diff --git a/effects/SkPictureImageFilter.h b/effects/SkPictureImageFilter.h
new file mode 100644
index 0000000..98d72d9
--- /dev/null
+++ b/effects/SkPictureImageFilter.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureImageFilter_DEFINED
+#define SkPictureImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+#include "SkPicture.h"
+
+class SK_API SkPictureImageFilter : public SkImageFilter {
+public:
+    /**
+     *  Refs the passed-in picture.
+     */
+    explicit SkPictureImageFilter(SkPicture* picture);
+
+    /**
+     *  Refs the passed-in picture. rect can be used to crop or expand the destination rect when
+     *  the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
+     */
+    SkPictureImageFilter(SkPicture* picture, const SkRect& rect);
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
+
+protected:
+    virtual ~SkPictureImageFilter();
+    explicit SkPictureImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
+                               SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+
+private:
+    SkPicture* fPicture;
+    SkRect     fRect;
+    typedef SkImageFilter INHERITED;
+};
+
+#endif
diff --git a/gpu/GrSurface.h b/gpu/GrSurface.h
index c401a90..15e44ab 100644
--- a/gpu/GrSurface.h
+++ b/gpu/GrSurface.h
@@ -15,6 +15,7 @@
 
 class GrTexture;
 class GrRenderTarget;
+struct SkImageInfo;
 
 class GrSurface : public GrResource {
 public:
@@ -58,6 +59,8 @@
      */
     const GrTextureDesc& desc() const { return fDesc; }
 
+    void asImageInfo(SkImageInfo*) const;
+
     /**
      * @return the texture associated with the surface, may be NULL.
      */
diff --git a/gpu/SkGr.h b/gpu/SkGr.h
index 5e5ca4b..db08548 100644
--- a/gpu/SkGr.h
+++ b/gpu/SkGr.h
@@ -50,6 +50,7 @@
  *  kUnknown_PixelConfig if the conversion cannot be done.
  */
 GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config);
+bool GrPixelConfig2ColorType(GrPixelConfig, SkColorType*);
 
 static inline GrColor SkColor2GrColor(SkColor c) {
     SkPMColor pm = SkPreMultiplyColor(c);
diff --git a/gpu/SkGrPixelRef.h b/gpu/SkGrPixelRef.h
index c29c27f..d893372 100644
--- a/gpu/SkGrPixelRef.h
+++ b/gpu/SkGrPixelRef.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2010 Google Inc.
  *
@@ -6,8 +5,6 @@
  * found in the LICENSE file.
  */
 
-
-
 #ifndef SkGrPixelRef_DEFINED
 #define SkGrPixelRef_DEFINED
 
@@ -23,7 +20,7 @@
  */
 class SK_API SkROLockPixelsPixelRef : public SkPixelRef {
 public:
-    SkROLockPixelsPixelRef();
+    SkROLockPixelsPixelRef(const SkImageInfo&);
     virtual ~SkROLockPixelsPixelRef();
 
 protected:
@@ -47,7 +44,6 @@
      * cache and would like the pixel ref to unlock it in its destructor then transferCacheLock
      * should be set to true.
      */
-    SkGrPixelRef(GrSurface*, bool transferCacheLock = false);
     SkGrPixelRef(const SkImageInfo&, GrSurface*, bool transferCacheLock = false);
     virtual ~SkGrPixelRef();
 
diff --git a/images/SkImageRef.h b/images/SkImageRef.h
index 0599a8d..30b1562 100644
--- a/images/SkImageRef.h
+++ b/images/SkImageRef.h
@@ -34,7 +34,7 @@
         @param config The preferred config of the decoded bitmap.
         @param sampleSize Requested sampleSize for decoding. Defaults to 1.
     */
-    SkImageRef(SkStreamRewindable*, SkBitmap::Config config, int sampleSize = 1,
+    SkImageRef(const SkImageInfo&, SkStreamRewindable*, int sampleSize = 1,
                SkBaseMutex* mutex = NULL);
     virtual ~SkImageRef();
 
@@ -89,7 +89,6 @@
 
     SkImageDecoderFactory*  fFactory;    // may be null
     SkStreamRewindable*     fStream;
-    SkBitmap::Config        fConfig;
     int                     fSampleSize;
     bool                    fDoDither;
     bool                    fErrorInDecoding;
diff --git a/images/SkImageRef_GlobalPool.h b/images/SkImageRef_GlobalPool.h
index 3adc0f6..caaf248 100644
--- a/images/SkImageRef_GlobalPool.h
+++ b/images/SkImageRef_GlobalPool.h
@@ -15,7 +15,7 @@
 class SkImageRef_GlobalPool : public SkImageRef {
 public:
     // if pool is null, use the global pool
-    SkImageRef_GlobalPool(SkStreamRewindable*, SkBitmap::Config,
+    SkImageRef_GlobalPool(const SkImageInfo&, SkStreamRewindable*,
                           int sampleSize = 1);
     virtual ~SkImageRef_GlobalPool();