Reimplement deserialization of SkImageFilter's uniqueID.

9fa60d ("Simplify flattening to just write enough ... ") simplified just
a tad too much. In particular, it disabled deserialization of
SkImageFilter's uniqueID, which in turn caused the failure of
SkImageFilter's cache, which caused a large regression in Chrome's SVG
filter performance.

The medium-term fix is to switch to the new SkRecordDraw SkPicture
backend, which will make the unique IDs unnecessary.

This change is an "in case of emergecy" CL, in the event that there are
problems switching on the new backend in Chrome. For that reason, it's
minimalist: only the filters used by Chrome are modified, and whitespace
changes are kept to a minimum. In this way, it should be easy to revert
once the new backend goes in.

R=reed@google.com

Author: senorblanco@chromium.org

Review URL: https://codereview.chromium.org/503833002
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index 85589f0..a92a426 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -237,7 +237,7 @@
         void allocInputs(int count);
     };
 
-    SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
+    SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL, uint32_t uniqueID = 0);
 
     virtual ~SkImageFilter();
 
diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h
index 6f06a89..cfa895a 100644
--- a/include/effects/SkBlurImageFilter.h
+++ b/include/effects/SkBlurImageFilter.h
@@ -16,8 +16,8 @@
     static SkBlurImageFilter* Create(SkScalar sigmaX,
                                      SkScalar sigmaY,
                                      SkImageFilter* input = NULL,
-                                     const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect));
+                                     const CropRect* cropRect = NULL, uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect, uniqueID));
     }
 
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
@@ -28,7 +28,8 @@
     SkBlurImageFilter(SkScalar sigmaX,
                       SkScalar sigmaY,
                       SkImageFilter* input,
-                      const CropRect* cropRect);
+                      const CropRect* cropRect,
+                      uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkBlurImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkColorFilterImageFilter.h b/include/effects/SkColorFilterImageFilter.h
index baaabb9..46f2d2a 100644
--- a/include/effects/SkColorFilterImageFilter.h
+++ b/include/effects/SkColorFilterImageFilter.h
@@ -16,7 +16,8 @@
 public:
     static SkColorFilterImageFilter* Create(SkColorFilter* cf,
                                             SkImageFilter* input = NULL,
-                                            const CropRect* cropRect = NULL);
+                                            const CropRect* cropRect = NULL,
+                                            uint32_t uniqueID = 0);
     virtual ~SkColorFilterImageFilter();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
@@ -35,7 +36,8 @@
 private:
     SkColorFilterImageFilter(SkColorFilter* cf,
                              SkImageFilter* input,
-                             const CropRect* cropRect);
+                             const CropRect* cropRect,
+                             uint32_t uniqueID);
     SkColorFilter*  fColorFilter;
 
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkDisplacementMapEffect.h b/include/effects/SkDisplacementMapEffect.h
index a26d5a2..0a658ac 100644
--- a/include/effects/SkDisplacementMapEffect.h
+++ b/include/effects/SkDisplacementMapEffect.h
@@ -27,7 +27,8 @@
                                            ChannelSelectorType yChannelSelector,
                                            SkScalar scale, SkImageFilter* displacement,
                                            SkImageFilter* color = NULL,
-                                           const CropRect* cropRect = NULL);
+                                           const CropRect* cropRect = NULL,
+                                           uint32_t uniqueID = 0);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
 
@@ -51,7 +52,8 @@
     SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
                             ChannelSelectorType yChannelSelector,
                             SkScalar scale, SkImageFilter* inputs[2],
-                            const CropRect* cropRect);
+                            const CropRect* cropRect,
+                            uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkDropShadowImageFilter.h b/include/effects/SkDropShadowImageFilter.h
index 85f4afd..0d6c24e 100644
--- a/include/effects/SkDropShadowImageFilter.h
+++ b/include/effects/SkDropShadowImageFilter.h
@@ -14,16 +14,17 @@
     static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
                                            SkScalar sigmaX, SkScalar sigmaY, SkColor color,
                                            SkImageFilter* input = NULL,
-                                           const CropRect* cropRect = NULL) {
+                                           const CropRect* cropRect = NULL,
+                                           uint32_t uniqueID = 0) {
         return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
-                                                    color, input, cropRect));
+                                                    color, input, cropRect, uniqueID));
     }
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
 
 protected:
     SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
-                            SkImageFilter* input, const CropRect* cropRect);
+                            SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDropShadowImageFilter(SkReadBuffer&);
 #endif
diff --git a/include/effects/SkLightingImageFilter.h b/include/effects/SkLightingImageFilter.h
index 3e055a8..5fb0822 100644
--- a/include/effects/SkLightingImageFilter.h
+++ b/include/effects/SkLightingImageFilter.h
@@ -73,7 +73,8 @@
     SkLightingImageFilter(SkLight* light,
                           SkScalar surfaceScale,
                           SkImageFilter* input,
-                          const CropRect* cropRect);
+                          const CropRect* cropRect,
+                          uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkLightingImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h
index d1ca052..e24d823 100644
--- a/include/effects/SkMatrixConvolutionImageFilter.h
+++ b/include/effects/SkMatrixConvolutionImageFilter.h
@@ -60,10 +60,11 @@
                                                   TileMode tileMode,
                                                   bool convolveAlpha,
                                                   SkImageFilter* input = NULL,
-                                                  const CropRect* cropRect = NULL) {
+                                                  const CropRect* cropRect = NULL,
+                                                  uint32_t uniqueID = 0) {
         return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias,
                                                            kernelOffset, tileMode, convolveAlpha,
-                                                           input, cropRect));
+                                                           input, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
@@ -77,7 +78,8 @@
                                    TileMode tileMode,
                                    bool convolveAlpha,
                                    SkImageFilter* input,
-                                   const CropRect* cropRect);
+                                   const CropRect* cropRect,
+                                   uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMatrixConvolutionImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkMatrixImageFilter.h b/include/effects/SkMatrixImageFilter.h
index 15f8243..ae6a0b7 100644
--- a/include/effects/SkMatrixImageFilter.h
+++ b/include/effects/SkMatrixImageFilter.h
@@ -30,7 +30,8 @@
 
     static SkMatrixImageFilter* Create(const SkMatrix& transform,
                                        SkPaint::FilterLevel,
-                                       SkImageFilter* input = NULL);
+                                       SkImageFilter* input = NULL,
+                                       uint32_t uniqueID = 0);
     virtual ~SkMatrixImageFilter();
 
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
@@ -40,7 +41,8 @@
 protected:
     SkMatrixImageFilter(const SkMatrix& transform,
                         SkPaint::FilterLevel,
-                        SkImageFilter* input);
+                        SkImageFilter* input,
+                        uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkMatrixImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkMergeImageFilter.h b/include/effects/SkMergeImageFilter.h
index a9a14a9..5e723aa 100644
--- a/include/effects/SkMergeImageFilter.h
+++ b/include/effects/SkMergeImageFilter.h
@@ -18,15 +18,17 @@
 
     static SkMergeImageFilter* Create(SkImageFilter* first, SkImageFilter* second,
                                       SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
-                                      const CropRect* cropRect = NULL) {
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
         SkImageFilter* inputs[2] = { first, second };
         SkXfermode::Mode modes[2] = { mode, mode };
-        return SkNEW_ARGS(SkMergeImageFilter, (inputs, 2, modes, cropRect));
+        return SkNEW_ARGS(SkMergeImageFilter, (inputs, 2, modes, cropRect, uniqueID));
     }
     static SkMergeImageFilter* Create(SkImageFilter* filters[], int count,
                                       const SkXfermode::Mode modes[] = NULL,
-                                      const CropRect* cropRect = NULL) {
-        return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect));
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
@@ -34,7 +36,8 @@
 protected:
     SkMergeImageFilter(SkImageFilter* filters[], int count,
                        const SkXfermode::Mode modes[],
-                       const CropRect* cropRect);
+                       const CropRect* cropRect,
+                       uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMergeImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h
index 499d6a8..3f2be45 100644
--- a/include/effects/SkMorphologyImageFilter.h
+++ b/include/effects/SkMorphologyImageFilter.h
@@ -30,7 +30,7 @@
 
 protected:
     SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input,
-                            const CropRect* cropRect);
+                            const CropRect* cropRect, uint32_t uniqueID);
     bool filterImageGeneric(Proc procX, Proc procY,
                             Proxy*, const SkBitmap& src, const Context&,
                             SkBitmap* result, SkIPoint* offset) const;
@@ -56,11 +56,12 @@
 public:
     static SkDilateImageFilter* Create(int radiusX, int radiusY,
                                        SkImageFilter* input = NULL,
-                                       const CropRect* cropRect = NULL) {
+                                       const CropRect* cropRect = NULL,
+                                       uint32_t uniqueID = 0) {
         if (radiusX < 0 || radiusY < 0) {
             return NULL;
         }
-        return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect));
+        return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
     }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -73,8 +74,8 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter)
 
 protected:
-    SkDilateImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect)
-        : INHERITED(radiusX, radiusY, input, cropRect) {}
+    SkDilateImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+        : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
 #endif
@@ -87,11 +88,12 @@
 public:
     static SkErodeImageFilter* Create(int radiusX, int radiusY,
                                       SkImageFilter* input = NULL,
-                                      const CropRect* cropRect = NULL) {
+                                      const CropRect* cropRect = NULL,
+                                      uint32_t uniqueID = 0) {
         if (radiusX < 0 || radiusY < 0) {
             return NULL;
         }
-        return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect));
+        return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect, uniqueID));
     }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -104,8 +106,8 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter)
 
 protected:
-    SkErodeImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect)
-        : INHERITED(radiusX, radiusY, input, cropRect) {}
+    SkErodeImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+        : INHERITED(radiusX, radiusY, input, cropRect, uniqueID) {}
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
 #endif
diff --git a/include/effects/SkOffsetImageFilter.h b/include/effects/SkOffsetImageFilter.h
index d18dcae..a870c0b 100644
--- a/include/effects/SkOffsetImageFilter.h
+++ b/include/effects/SkOffsetImageFilter.h
@@ -16,17 +16,18 @@
 
 public:
     static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
-                                       const CropRect* cropRect = NULL) {
+                                       const CropRect* cropRect = NULL,
+                                       uint32_t uniqueID = 0) {
         if (!SkScalarIsFinite(dx) || !SkScalarIsFinite(dy)) {
             return NULL;
         }
-        return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect));
+        return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect, uniqueID));
     }
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
 
 protected:
-    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect);
+    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkOffsetImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h
index 7826eb8..fbd04f0 100644
--- a/include/effects/SkPictureImageFilter.h
+++ b/include/effects/SkPictureImageFilter.h
@@ -16,23 +16,23 @@
     /**
      *  Refs the passed-in picture.
      */
-    static SkPictureImageFilter* Create(const SkPicture* picture) {
-        return SkNEW_ARGS(SkPictureImageFilter, (picture));
+    static SkPictureImageFilter* Create(const SkPicture* picture, int32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture, uniqueID));
     }
 
     /**
      *  Refs the passed-in picture. cropRect 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.)
      */
-    static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect) {
-        return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect));
+    static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID = 0) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
 
 protected:
-    explicit SkPictureImageFilter(const SkPicture* picture);
-    SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect);
+    explicit SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID);
+    SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID);
     virtual ~SkPictureImageFilter();
     /*  Constructs an SkPictureImageFilter object from an SkReadBuffer.
      *  Note: If the SkPictureImageFilter object construction requires bitmap
diff --git a/include/effects/SkRectShaderImageFilter.h b/include/effects/SkRectShaderImageFilter.h
index 1a6ee08..c4311db 100644
--- a/include/effects/SkRectShaderImageFilter.h
+++ b/include/effects/SkRectShaderImageFilter.h
@@ -28,7 +28,7 @@
     SK_ATTR_DEPRECATED("use Create(SkShader*, const CropRect*)")
     static SkRectShaderImageFilter* Create(SkShader* s, const SkRect& rect);
 
-    static SkRectShaderImageFilter* Create(SkShader* s, const CropRect* rect = NULL);
+    static SkRectShaderImageFilter* Create(SkShader* s, const CropRect* rect = NULL, uint32_t uniqueID = 0);
     virtual ~SkRectShaderImageFilter();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
@@ -43,7 +43,7 @@
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
 
 private:
-    SkRectShaderImageFilter(SkShader* s, const CropRect* rect);
+    SkRectShaderImageFilter(SkShader* s, const CropRect* rect, uint32_t uniqueID = 0);
     SkShader*  fShader;
 
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index 084f726..440337a 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -20,7 +20,7 @@
         @param input    Input from which the subregion defined by srcRect will be tiled
     */
     static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect,
-                                     SkImageFilter* input);
+                                     SkImageFilter* input, uint32_t uniqueID = 0);
 
     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE;
@@ -30,8 +30,8 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
 
 protected:
-    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
-        : INHERITED(1, &input), fSrcRect(srcRect), fDstRect(dstRect) {}
+    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input, uint32_t uniqueID)
+        : INHERITED(1, &input, NULL, uniqueID), fSrcRect(srcRect), fDstRect(dstRect) {}
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkTileImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h
index 7c29e28..6736889 100644
--- a/include/effects/SkXfermodeImageFilter.h
+++ b/include/effects/SkXfermodeImageFilter.h
@@ -25,9 +25,10 @@
 
     static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
                                          SkImageFilter* foreground = NULL,
-                                         const CropRect* cropRect = NULL) {
+                                         const CropRect* cropRect = NULL,
+                                         uint32_t uniqueID = 0) {
         SkImageFilter* inputs[2] = { background, foreground };
-        return SkNEW_ARGS(SkXfermodeImageFilter, (mode, inputs, cropRect));
+        return SkNEW_ARGS(SkXfermodeImageFilter, (mode, inputs, cropRect, uniqueID));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter)
@@ -45,7 +46,7 @@
 
 protected:
     SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* inputs[2],
-                          const CropRect* cropRect);
+                          const CropRect* cropRect, uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkXfermodeImageFilter(SkReadBuffer& buffer);
 #endif
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 20c7d57..e5be085 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -110,12 +110,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect)
+SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect, uint32_t uniqueID)
   : fInputCount(inputCount),
     fInputs(new SkImageFilter*[inputCount]),
     fUsesSrcInput(false),
     fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)),
-    fUniqueID(next_image_filter_unique_id()) {
+    fUniqueID(uniqueID ? uniqueID : next_image_filter_unique_id()) {
     for (int i = 0; i < inputCount; ++i) {
         if (NULL == inputs[i] || inputs[i]->usesSrcInput()) {
             fUsesSrcInput = true;
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 8787cce..d082098 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -38,16 +38,16 @@
 SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX,
                                      SkScalar sigmaY,
                                      SkImageFilter* input,
-                                     const CropRect* cropRect)
-    : INHERITED(1, &input, cropRect), fSigma(SkSize::Make(sigmaX, sigmaY)) {
-    SkASSERT(sigmaX >= 0 && sigmaY >= 0);
+                                     const CropRect* cropRect,
+                                     uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fSigma(SkSize::Make(sigmaX, sigmaY)) {
 }
 
 SkFlattenable* SkBlurImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     SkScalar sigmaX = buffer.readScalar();
     SkScalar sigmaY = buffer.readScalar();
-    return Create(sigmaX, sigmaY, common.getInput(0), &common.cropRect());
+    return Create(sigmaX, sigmaY, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkBlurImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index 0087627..7c3e9e8 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -58,7 +58,7 @@
 };
 
 SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
-        SkImageFilter* input, const CropRect* cropRect) {
+        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
     SkASSERT(cf);
     SkScalar colorMatrix[20], inputMatrix[20];
     SkColorFilter* inputColorFilter;
@@ -70,15 +70,15 @@
             SkScalar combinedMatrix[20];
             mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
             SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combinedMatrix));
-            return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect));
+            return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
         }
     }
-    return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect));
+    return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID));
 }
 
 SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf,
-        SkImageFilter* input, const CropRect* cropRect)
-    : INHERITED(1, &input, cropRect), fColorFilter(cf) {
+        SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fColorFilter(cf) {
     SkASSERT(cf);
     SkSafeRef(cf);
 }
@@ -93,7 +93,7 @@
 SkFlattenable* SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     SkAutoTUnref<SkColorFilter> cf(buffer.readColorFilter());
-    return Create(cf, common.getInput(0), &common.cropRect());
+    return Create(cf, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index a1d29bf..4054d55 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -164,7 +164,7 @@
                                                          SkScalar scale,
                                                          SkImageFilter* displacement,
                                                          SkImageFilter* color,
-                                                         const CropRect* cropRect) {
+                                                         const CropRect* cropRect, uint32_t uniqueID) {
     if (!channel_selector_type_is_valid(xChannelSelector) ||
         !channel_selector_type_is_valid(yChannelSelector)) {
         return NULL;
@@ -172,15 +172,16 @@
 
     SkImageFilter* inputs[2] = { displacement, color };
     return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
-                                                inputs, cropRect));
+                                                inputs, cropRect, uniqueID));
 }
 
 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
                                                  ChannelSelectorType yChannelSelector,
                                                  SkScalar scale,
                                                  SkImageFilter* inputs[2],
-                                                 const CropRect* cropRect)
-  : INHERITED(2, inputs, cropRect)
+                                                 const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+  : INHERITED(2, inputs, cropRect, uniqueID)
   , fXChannelSelector(xChannelSelector)
   , fYChannelSelector(yChannelSelector)
   , fScale(scale)
@@ -208,7 +209,7 @@
     ChannelSelectorType xsel = (ChannelSelectorType)buffer.readInt();
     ChannelSelectorType ysel = (ChannelSelectorType)buffer.readInt();
     SkScalar scale = buffer.readScalar();
-    return Create(xsel, ysel, scale, common.getInput(0), common.getInput(1), &common.cropRect());
+    return Create(xsel, ysel, scale, common.getInput(0), common.getInput(1), &common.cropRect(), common.uniqueID());
 }
 
 void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 29d685b..339e955 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -17,8 +17,9 @@
 
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy,
                                                  SkScalar sigmaX, SkScalar sigmaY, SkColor color,
-                                                 SkImageFilter* input, const CropRect* cropRect)
-    : INHERITED(1, &input, cropRect)
+                                                 SkImageFilter* input, const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID)
     , fDx(dx)
     , fDy(dy)
     , fSigmaX(sigmaX)
@@ -49,7 +50,7 @@
     SkScalar sigmaX = buffer.readScalar();
     SkScalar sigmaY = buffer.readScalar();
     SkColor color = buffer.readColor();
-    return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect());
+    return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index c3834c6..bf2298c 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -265,14 +265,15 @@
 class SkDiffuseLightingImageFilter : public SkLightingImageFilter {
 public:
     static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter*,
-                                 const CropRect*);
+                                 const CropRect*, uint32_t uniqueID = 0);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter)
     SkScalar kd() const { return fKD; }
 
 protected:
     SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale,
-                                 SkScalar kd, SkImageFilter* input, const CropRect* cropRect);
+                                 SkScalar kd, SkImageFilter* input, const CropRect* cropRect,
+                                 uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDiffuseLightingImageFilter(SkReadBuffer& buffer);
 #endif
@@ -293,7 +294,7 @@
 class SkSpecularLightingImageFilter : public SkLightingImageFilter {
 public:
     static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale,
-                                 SkScalar ks, SkScalar shininess, SkImageFilter*, const CropRect*);
+                                 SkScalar ks, SkScalar shininess, SkImageFilter*, const CropRect*, uint32_t uniqueID = 0);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
 
@@ -302,7 +303,8 @@
 
 protected:
     SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks,
-                                  SkScalar shininess, SkImageFilter* input, const CropRect*);
+                                  SkScalar shininess, SkImageFilter* input, const CropRect*,
+                                  uint32_t uniqueID);
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkSpecularLightingImageFilter(SkReadBuffer& buffer);
 #endif
@@ -844,8 +846,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale,
-                                             SkImageFilter* input, const CropRect* cropRect)
-  : INHERITED(1, &input, cropRect)
+                                             SkImageFilter* input, const CropRect* cropRect,
+                                             uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID)
   , fLight(SkRef(light))
   , fSurfaceScale(surfaceScale / 255)
 {}
@@ -941,7 +944,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 SkImageFilter* SkDiffuseLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
-                                    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
+                                    SkScalar kd, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
     if (NULL == light) {
         return NULL;
     }
@@ -953,11 +956,11 @@
     if (kd < 0) {
         return NULL;
     }
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter, (light, surfaceScale, kd, input, cropRect));
+    return SkNEW_ARGS(SkDiffuseLightingImageFilter, (light, surfaceScale, kd, input, cropRect, uniqueID));
 }
 
-SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect = NULL)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect, uniqueID),
     fKD(kd)
 {
 }
@@ -976,7 +979,7 @@
     SkAutoTUnref<SkLight> light(SkLight::UnflattenLight(buffer));
     SkScalar surfaceScale = buffer.readScalar();
     SkScalar kd = buffer.readScalar();
-    return Create(light, surfaceScale, kd, common.getInput(0), &common.cropRect());
+    return Create(light, surfaceScale, kd, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
@@ -1052,7 +1055,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 SkImageFilter* SkSpecularLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
-                SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
+                SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
     if (NULL == light) {
         return NULL;
     }
@@ -1065,11 +1068,11 @@
         return NULL;
     }
     return SkNEW_ARGS(SkSpecularLightingImageFilter,
-                      (light, surfaceScale, ks, shininess, input, cropRect));
+                      (light, surfaceScale, ks, shininess, input, cropRect, uniqueID));
 }
 
-SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect, uniqueID),
     fKS(ks),
     fShininess(shininess)
 {
@@ -1092,7 +1095,7 @@
     SkScalar surfaceScale = buffer.readScalar();
     SkScalar ks = buffer.readScalar();
     SkScalar shine = buffer.readScalar();
-    return Create(light, surfaceScale, ks, shine, common.getInput(0), &common.cropRect());
+    return Create(light, surfaceScale, ks, shine, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index e01b640..aa8b804 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -26,8 +26,9 @@
     TileMode tileMode,
     bool convolveAlpha,
     SkImageFilter* input,
-    const CropRect* cropRect)
-  : INHERITED(1, &input, cropRect),
+    const CropRect* cropRect,
+    uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID),
     fKernelSize(kernelSize),
     fGain(gain),
     fBias(bias),
@@ -112,7 +113,7 @@
     TileMode tileMode = (TileMode)buffer.readInt();
     bool convolveAlpha = buffer.readBool();
     return Create(kernelSize, kernel.get(), gain, bias, kernelOffset, tileMode, convolveAlpha,
-                  common.getInput(0), &common.cropRect());
+                  common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkMatrixConvolutionImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkMatrixImageFilter.cpp b/src/effects/SkMatrixImageFilter.cpp
index 2b7786a..34231ba 100644
--- a/src/effects/SkMatrixImageFilter.cpp
+++ b/src/effects/SkMatrixImageFilter.cpp
@@ -17,16 +17,18 @@
 
 SkMatrixImageFilter::SkMatrixImageFilter(const SkMatrix& transform,
                                          SkPaint::FilterLevel filterLevel,
-                                         SkImageFilter* input)
-  : INHERITED(1, &input),
+                                         SkImageFilter* input,
+                                         uint32_t uniqueID)
+  : INHERITED(1, &input, NULL, uniqueID),
     fTransform(transform),
     fFilterLevel(filterLevel) {
 }
 
 SkMatrixImageFilter* SkMatrixImageFilter::Create(const SkMatrix& transform,
                                                  SkPaint::FilterLevel filterLevel,
-                                                 SkImageFilter* input) {
-    return SkNEW_ARGS(SkMatrixImageFilter, (transform, filterLevel, input));
+                                                 SkImageFilter* input,
+                                                 uint32_t uniqueID) {
+    return SkNEW_ARGS(SkMatrixImageFilter, (transform, filterLevel, input, uniqueID));
 }
 
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
@@ -42,7 +44,7 @@
     SkMatrix matrix;
     buffer.readMatrix(&matrix);
     SkPaint::FilterLevel level = static_cast<SkPaint::FilterLevel>(buffer.readInt());
-    return Create(matrix, level, common.getInput(0));
+    return Create(matrix, level, common.getInput(0), common.uniqueID());
 }
 
 void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index a76702f..9e7f4e5 100755
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -42,7 +42,9 @@
 
 SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* filters[], int count,
                                        const SkXfermode::Mode modes[],
-                                       const CropRect* cropRect) : INHERITED(count, filters, cropRect) {
+                                       const CropRect* cropRect,
+                                       uint32_t uniqueID)
+  : INHERITED(count, filters, cropRect, uniqueID) {
     SkASSERT(count >= 0);
     this->initModes(modes);
 }
@@ -126,9 +128,9 @@
         if (!buffer.isValid()) {
             return NULL;
         }
-        return Create(common.inputs(), count, modes.get(), &common.cropRect());
+        return Create(common.inputs(), count, modes.get(), &common.cropRect(), common.uniqueID());
     }
-    return Create(common.inputs(), count, NULL, &common.cropRect());
+    return Create(common.inputs(), count, NULL, &common.cropRect(), common.uniqueID());
 }
 
 void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 6a6dd4d..2b9c91e 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -34,8 +34,9 @@
 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX,
                                                  int radiusY,
                                                  SkImageFilter* input,
-                                                 const CropRect* cropRect)
-    : INHERITED(1, &input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) {
+                                                 const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+    : INHERITED(1, &input, cropRect, uniqueID), fRadius(SkISize::Make(radiusX, radiusY)) {
 }
 
 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const {
@@ -263,14 +264,14 @@
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     const int width = buffer.readInt();
     const int height = buffer.readInt();
-    return Create(width, height, common.getInput(0), &common.cropRect());
+    return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 SkFlattenable* SkDilateImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     const int width = buffer.readInt();
     const int height = buffer.readInt();
-    return Create(width, height, common.getInput(0), &common.cropRect());
+    return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 #if SK_SUPPORT_GPU
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index fcf09cc..90528c6 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -95,7 +95,7 @@
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     SkPoint offset;
     buffer.readPoint(&offset);
-    return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect());
+    return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect(), common.uniqueID());
 }
 
 void SkOffsetImageFilter::flatten(SkWriteBuffer& buffer) const {
@@ -104,8 +104,8 @@
 }
 
 SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input,
-                                         const CropRect* cropRect)
-  : INHERITED(1, &input, cropRect) {
+                                         const CropRect* cropRect, uint32_t uniqueID)
+  : INHERITED(1, &input, cropRect, uniqueID) {
     fOffset.set(dx, dy);
 }
 
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
index a1958f3..c28175a 100644
--- a/src/effects/SkPictureImageFilter.cpp
+++ b/src/effects/SkPictureImageFilter.cpp
@@ -12,16 +12,17 @@
 #include "SkWriteBuffer.h"
 #include "SkValidationUtils.h"
 
-SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture)
-  : INHERITED(0, 0),
+SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID)
+  : INHERITED(0, 0, NULL, uniqueID),
     fPicture(picture),
     fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
                              picture ? SkIntToScalar(picture->height()) : 0)) {
     SkSafeRef(fPicture);
 }
 
-SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect)
-  : INHERITED(0, 0),
+SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
+                                           uint32_t uniqueID)
+  : INHERITED(0, 0, NULL, uniqueID),
     fPicture(picture),
     fCropRect(cropRect) {
     SkSafeRef(fPicture);
diff --git a/src/effects/SkRectShaderImageFilter.cpp b/src/effects/SkRectShaderImageFilter.cpp
index be3c23c..fb34ed0 100644
--- a/src/effects/SkRectShaderImageFilter.cpp
+++ b/src/effects/SkRectShaderImageFilter.cpp
@@ -23,13 +23,14 @@
     return SkNEW_ARGS(SkRectShaderImageFilter, (s, &cropRect));
 }
 
-SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect) {
+SkRectShaderImageFilter* SkRectShaderImageFilter::Create(SkShader* s, const CropRect* cropRect, uint32_t uniqueID) {
     SkASSERT(s);
-    return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect));
+    return SkNEW_ARGS(SkRectShaderImageFilter, (s, cropRect, uniqueID));
 }
 
-SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect)
-  : INHERITED(0, NULL, cropRect)
+SkRectShaderImageFilter::SkRectShaderImageFilter(SkShader* s, const CropRect* cropRect,
+                                                 uint32_t uniqueID)
+  : INHERITED(0, NULL, cropRect, uniqueID)
   , fShader(s) {
     SkASSERT(s);
     s->ref();
@@ -45,7 +46,7 @@
 SkFlattenable* SkRectShaderImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
     SkAutoTUnref<SkShader> shader(buffer.readShader());
-    return Create(shader.get(), &common.cropRect());
+    return Create(shader.get(), &common.cropRect(), common.uniqueID());
 }
 
 void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index 64492e2..bebf8f0 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -17,11 +17,11 @@
 #include "SkValidationUtils.h"
 
 SkTileImageFilter* SkTileImageFilter::Create(const SkRect& srcRect, const SkRect& dstRect,
-                                             SkImageFilter* input) {
+                                             SkImageFilter* input, uint32_t uniqueID) {
     if (!SkIsValidRect(srcRect) || !SkIsValidRect(dstRect)) {
         return NULL;
     }
-    return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input));
+    return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input, uniqueID));
 }
 
 bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
@@ -108,7 +108,7 @@
     SkRect src, dst;
     buffer.readRect(&src);
     buffer.readRect(&dst);
-    return Create(src, dst, common.getInput(0));
+    return Create(src, dst, common.getInput(0), common.uniqueID());
 }
 
 void SkTileImageFilter::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 15ff92a..88ea3f8 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -22,8 +22,9 @@
 
 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode,
                                              SkImageFilter* inputs[2],
-                                             const CropRect* cropRect)
-  : INHERITED(2, inputs, cropRect), fMode(mode) {
+                                             const CropRect* cropRect,
+                                             uint32_t uniqueID)
+  : INHERITED(2, inputs, cropRect, uniqueID), fMode(mode) {
     SkSafeRef(fMode);
 }
 
@@ -41,7 +42,7 @@
 SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) {
     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
     SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
-    return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect());
+    return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect(), common.uniqueID());
 }
 
 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {