Simplify flattening to just write enough to call the factory/public-constructor for the class. We want to *not* rely on private constructors, and not rely on calling through the inheritance hierarchy for either flattening or unflattening(CreateProc).

Refactoring pattern:

1. guard the existing constructor(readbuffer) with the legacy build-flag
2. If you are a instancable subclass, implement CreateProc(readbuffer) to create a new instances from the buffer params (or return NULL).

If you're a shader subclass
1. You must read/write the local matrix if your class accepts that in its factory/constructor, else ignore it.

R=robertphillips@google.com, mtklein@google.com, senorblanco@google.com, senorblanco@chromium.org, sugoi@chromium.org

Author: reed@google.com

Review URL: https://codereview.chromium.org/395603002
diff --git a/gm/imagefiltersbase.cpp b/gm/imagefiltersbase.cpp
index bbcb7ce..5472f2d 100644
--- a/gm/imagefiltersbase.cpp
+++ b/gm/imagefiltersbase.cpp
@@ -23,24 +23,34 @@
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
+
 protected:
-    FailImageFilter() : INHERITED(0, NULL) {}
+    FailImageFilter() : INHERITED(0, NULL) {
+        static bool gOnce;
+        if (!gOnce) {
+            gOnce = true;
+            SkFlattenable::Register("FailImageFilter", this->getFactory(),
+                                    this->GetFlattenableType());
+        }
+    }
+
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
         return false;
     }
 
-    FailImageFilter(SkReadBuffer& buffer)
-      : INHERITED(0, buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    FailImageFilter(SkReadBuffer& buffer) : INHERITED(0, buffer) {}
+#endif
 
 private:
     typedef SkImageFilter INHERITED;
 };
 
-// register the filter with the flattenable registry
-static SkFlattenable::Registrar gFailImageFilterReg("FailImageFilter",
-                                                    FailImageFilter::CreateProc,
-                                                    FailImageFilter::GetFlattenableType());
+SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    return FailImageFilter::Create();
+}
 
 class IdentityImageFilter : public SkImageFilter {
 public:
@@ -50,7 +60,15 @@
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
 protected:
-    IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
+    IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {
+        static bool gOnce;
+        if (!gOnce) {
+            gOnce = true;
+            SkFlattenable::Register("IdentityImageFilter", this->getFactory(),
+                                    this->GetFlattenableType());
+        }
+    }
+
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
         *result = src;
@@ -58,18 +76,18 @@
         return true;
     }
 
-    IdentityImageFilter(SkReadBuffer& buffer)
-      : INHERITED(1, buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    IdentityImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) {}
+#endif
 
 private:
     typedef SkImageFilter INHERITED;
 };
 
-// register the filter with the flattenable registry
-static SkFlattenable::Registrar gIdentityImageFilterReg("IdentityImageFilter",
-                                                        IdentityImageFilter::CreateProc,
-                                                        IdentityImageFilter::GetFlattenableType());
-
+SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    return IdentityImageFilter::Create(common.getInput(0));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp
index 6500824..bd6af3f 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -57,28 +57,42 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SimpleOffsetFilter(SkReadBuffer& buffer)
     : SkImageFilter(1, buffer) {
         fDX = buffer.readScalar();
         fDY = buffer.readScalar();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->SkImageFilter::flatten(buffer);
+        this->INHERITED::flatten(buffer);
         buffer.writeScalar(fDX);
         buffer.writeScalar(fDY);
     }
 
 private:
     SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
-    : SkImageFilter(1, &input), fDX(dx), fDY(dy) {}
+    : SkImageFilter(1, &input), fDX(dx), fDY(dy) {
+        static bool gOnce;
+        if (!gOnce) {
+            gOnce = true;
+            SkFlattenable::Register("SimpleOffsetFilter", this->getFactory(),
+                                    this->GetFlattenableType());
+        }
+    }
 
     SkScalar fDX, fDY;
+
+    typedef SkImageFilter INHERITED;
 };
 
-SkFlattenable::Registrar registrar("SimpleOffsetFilter",
-                                   SimpleOffsetFilter::CreateProc,
-                                   SimpleOffsetFilter::GetFlattenableType());
+SkFlattenable* SimpleOffsetFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar dx = buffer.readScalar();
+    SkScalar dy = buffer.readScalar();
+    return Create(dx, dy, common.getInput(0));
+}
 
 class ImageFiltersGraphGM : public skiagm::GM {
 public:
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 25e6bbe..5ddd6af 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -135,7 +135,9 @@
 
 protected:
     SkColorFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
+#endif
 
 private:
     typedef SkFlattenable INHERITED;
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
index b92bacc..f771d01 100644
--- a/include/core/SkDrawLooper.h
+++ b/include/core/SkDrawLooper.h
@@ -114,7 +114,9 @@
 
 protected:
     SkDrawLooper() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkFlattenable INHERITED;
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h
index f6d377a..679f640 100644
--- a/include/core/SkFlattenable.h
+++ b/include/core/SkFlattenable.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006 The Android Open Source Project
  *
@@ -6,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-
 #ifndef SkFlattenable_DEFINED
 #define SkFlattenable_DEFINED
 
@@ -15,9 +13,26 @@
 class SkReadBuffer;
 class SkWriteBuffer;
 
-#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
-        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
-                                 flattenable::GetFlattenableType());
+#define SK_SUPPORT_LEGACY_DEEPFLATTENING
+
+/*
+ *  Flattening is straight-forward:
+ *      1. call getFactory() so we have a function-ptr to recreate the subclass
+ *      2. call flatten(buffer) to write out enough data for the factory to read
+ *
+ *  Unflattening is easy for the caller: new_instance = factory(buffer)
+ *
+ *  The complexity of supporting this is as follows.
+ *
+ *  If your subclass wants to control unflattening, use this macro in your declaration:
+ *      SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS
+ *  This will provide a getFactory(), and require that the subclass implements CreateProc.
+ *
+ *  For older buffers (before the DEEPFLATTENING change, the macros below declare
+ *  a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep,
+ *  then it calls through to a (usually protected) constructor, passing the buffer.
+ *  If the buffer is newer, then it directly calls the "real" factory: CreateProc.
+ */
 
 #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
 
@@ -30,11 +45,39 @@
 #define SK_DECLARE_UNFLATTENABLE_OBJECT() \
     virtual Factory getFactory() const SK_OVERRIDE { return NULL; }
 
-#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
-    virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \
-    static SkFlattenable* CreateProc(SkReadBuffer& buffer) { \
-        return SkNEW_ARGS(flattenable, (buffer)); \
-    }
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+    SkFlattenable::Registrar(#flattenable, flattenable::DeepCreateProc, \
+                             flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
+    private:                                                                \
+    static SkFlattenable* CreateProc(SkReadBuffer&);                        \
+    static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) {            \
+        if (NeedsDeepUnflatten(buffer)) {                                   \
+            return SkNEW_ARGS(flattenable, (buffer));                       \
+        }                                                                   \
+        return CreateProc(buffer);                                          \
+    }                                                                       \
+    friend class SkPrivateEffectInitializer;                                \
+    public:                                                                 \
+    virtual Factory getFactory() const SK_OVERRIDE {return DeepCreateProc;}
+#else
+#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
+    SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
+                             flattenable::GetFlattenableType());
+
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable)    \
+    private:                                                                \
+    static SkFlattenable* CreateProc(SkReadBuffer&);                        \
+    friend class SkPrivateEffectInitializer;                                \
+    public:                                                                 \
+    virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
+
+// If your subclass will *never* need to be unflattened, declare this.
+#define SK_DECLARE_NOT_FLATTENABLE_PROCS(flattenable)   \
+    virtual Factory getFactory() const SK_OVERRIDE { return ReturnNullCreateProc; }
 
 /** For SkFlattenable derived objects with a valid type
     This macro should only be used in base class objects in core
@@ -94,14 +137,21 @@
         }
     };
 
-    /** Override this to write data specific to your subclass into the buffer,
-     being sure to call your super-class' version first. This data will later
-     be passed to your Factory function, returned by getFactory().
+    /**
+     *  Override this if your subclass needs to record data that it will need to recreate itself
+     *  from its CreateProc (returned by getFactory()).
      */
-    virtual void flatten(SkWriteBuffer&) const;
+    virtual void flatten(SkWriteBuffer&) const {}
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    static bool NeedsDeepUnflatten(const SkReadBuffer&);
     SkFlattenable(SkReadBuffer&) {}
+#endif
+
+    static SkFlattenable* ReturnNullCreateProc(SkReadBuffer&) {
+        return NULL;
+    }
 
 private:
     static void InitializeFlattenablesIfNeeded();
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index d4930c4..85589f0 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -205,13 +205,23 @@
         Common() {}
         ~Common();
 
-        bool unflatten(SkReadBuffer&, int expectedInputs = -1);
+        /**
+         *  Attempt to unflatten the cropRect and the expected number of input filters.
+         *  If any number of input filters is valid, pass -1.
+         *  If this fails (i.e. corrupt buffer or contents) then return false and common will
+         *  be left uninitialized.
+         *  If this returns true, then inputCount() is the number of found input filters, each
+         *  of which may be NULL or a valid imagefilter.
+         */
+        bool unflatten(SkReadBuffer&, int expectedInputs);
 
-        CropRect        cropRect() const { return fCropRect; }
+        const CropRect& cropRect() const { return fCropRect; }
         int             inputCount() const { return fInputs.count(); }
         SkImageFilter** inputs() const { return fInputs.get(); }
         uint32_t        uniqueID() const { return fUniqueID; }
 
+        SkImageFilter*  getInput(int index) const { return fInputs[index]; }
+
         // If the caller wants a copy of the inputs, call this and it will transfer ownership
         // of the unflattened input filters to the caller. This is just a short-cut for copying
         // the inputs, calling ref() on each, and then waiting for Common's destructor to call
@@ -240,7 +250,7 @@
      */
     explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
 
-    virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE;
+    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     /**
      *  This is the virtual which should be overridden by the derived class
@@ -320,4 +330,15 @@
     uint32_t fUniqueID; // Globally unique
 };
 
+/**
+ *  Helper to unflatten the common data, and return NULL if we fail.
+ */
+#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)    \
+    Common localVar;                                                \
+    do {                                                            \
+        if (!localVar.unflatten(buffer, expectedCount)) {           \
+            return NULL;                                            \
+        }                                                           \
+    } while (0)
+
 #endif
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index 3992512..51ede4b 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -155,8 +155,10 @@
 
 protected:
     SkMaskFilter() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     // empty for now, but lets get our subclass to remember to init us for the future
     SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     enum FilterReturn {
         kFalse_FilterReturn,
diff --git a/include/core/SkPathEffect.h b/include/core/SkPathEffect.h
index 5620253..454614a 100644
--- a/include/core/SkPathEffect.h
+++ b/include/core/SkPathEffect.h
@@ -135,7 +135,9 @@
 
 protected:
     SkPathEffect() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
@@ -157,7 +159,10 @@
 
 protected:
     SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPairPathEffect(SkReadBuffer&);
+#endif
+
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // these are visible to our subclasses
@@ -191,7 +196,10 @@
 protected:
     SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
         : INHERITED(outer, inner) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
@@ -225,7 +233,10 @@
 protected:
     SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
         : INHERITED(first, second) {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     // illegal
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 79923a6..cfc82cb 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -248,7 +248,7 @@
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t MIN_PICTURE_VERSION = 19;
-    static const uint32_t CURRENT_PICTURE_VERSION = 32;
+    static const uint32_t CURRENT_PICTURE_VERSION = 33;
 
     mutable uint32_t      fUniqueID;
 
diff --git a/include/core/SkRasterizer.h b/include/core/SkRasterizer.h
index d6e514c..3280f42 100644
--- a/include/core/SkRasterizer.h
+++ b/include/core/SkRasterizer.h
@@ -32,7 +32,9 @@
 
 protected:
     SkRasterizer() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
                              const SkIRect* clipBounds,
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 4f3fd29..1e71577 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -461,7 +461,9 @@
     SK_DEFINE_FLATTENABLE_TYPE(SkShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkShader(SkReadBuffer& );
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 74fd9f8..3fb3ab5 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -217,7 +217,9 @@
 
 protected:
     SkXfermode() {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
+#endif
 
     /** The default implementation of xfer32/xfer16/xferA8 in turn call this
         method, 1 color at a time (upscaled to a SkPMColor). The default
diff --git a/include/effects/Sk1DPathEffect.h b/include/effects/Sk1DPathEffect.h
index 85f8ea2..87047e4 100644
--- a/include/effects/Sk1DPathEffect.h
+++ b/include/effects/Sk1DPathEffect.h
@@ -64,7 +64,9 @@
 
 protected:
     SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPath1DPathEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // overrides from Sk1DPathEffect
diff --git a/include/effects/Sk2DPathEffect.h b/include/effects/Sk2DPathEffect.h
index d9eec72..80a27a3 100644
--- a/include/effects/Sk2DPathEffect.h
+++ b/include/effects/Sk2DPathEffect.h
@@ -39,7 +39,9 @@
 
     // protected so that subclasses can call this during unflattening
     explicit Sk2DPathEffect(const SkMatrix& mat);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit Sk2DPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
@@ -68,7 +70,9 @@
 protected:
     SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
         : Sk2DPathEffect(matrix), fWidth(width) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkLine2DPathEffect(SkReadBuffer&);
+#endif
 
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
@@ -94,7 +98,9 @@
 
 protected:
     SkPath2DPathEffect(const SkMatrix&, const SkPath&);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPath2DPathEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual void next(const SkPoint&, int u, int v, SkPath*) const SK_OVERRIDE;
diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h
index a2599a8..53ce708 100644
--- a/include/effects/SkAvoidXfermode.h
+++ b/include/effects/SkAvoidXfermode.h
@@ -54,12 +54,15 @@
 
 protected:
     SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkAvoidXfermode(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
     SkColor     fOpColor;
-    uint32_t    fDistMul;   // x.14
+    uint32_t    fDistMul;   // x.14 cached from fTolerance
+    uint8_t     fTolerance;
     Mode        fMode;
 
     typedef SkXfermode INHERITED;
diff --git a/include/effects/SkBitmapSource.h b/include/effects/SkBitmapSource.h
index 2aa8fe9..9004a46 100644
--- a/include/effects/SkBitmapSource.h
+++ b/include/effects/SkBitmapSource.h
@@ -27,7 +27,9 @@
 protected:
     explicit SkBitmapSource(const SkBitmap& bitmap);
     SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkBitmapSource(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkBlurDrawLooper.h b/include/effects/SkBlurDrawLooper.h
index 507ec8b..9db9f0d 100644
--- a/include/effects/SkBlurDrawLooper.h
+++ b/include/effects/SkBlurDrawLooper.h
@@ -53,7 +53,9 @@
     SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
                      uint32_t flags);
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkBlurDrawLooper(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool asABlurShadow(BlurShadowRec*) const SK_OVERRIDE;
diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h
index 732af8f..6f06a89 100644
--- a/include/effects/SkBlurImageFilter.h
+++ b/include/effects/SkBlurImageFilter.h
@@ -29,7 +29,9 @@
                       SkScalar sigmaY,
                       SkImageFilter* input,
                       const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkBlurImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkColorFilterImageFilter.h b/include/effects/SkColorFilterImageFilter.h
index b915e88..baaabb9 100644
--- a/include/effects/SkColorFilterImageFilter.h
+++ b/include/effects/SkColorFilterImageFilter.h
@@ -22,7 +22,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterImageFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkColorFilterImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
index edbe07d..b846463 100644
--- a/include/effects/SkColorMatrixFilter.h
+++ b/include/effects/SkColorMatrixFilter.h
@@ -41,7 +41,9 @@
 protected:
     explicit SkColorMatrixFilter(const SkColorMatrix&);
     explicit SkColorMatrixFilter(const SkScalar array[20]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkColorMatrixFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkComposeImageFilter.h b/include/effects/SkComposeImageFilter.h
index 068bcab..26eed37 100644
--- a/include/effects/SkComposeImageFilter.h
+++ b/include/effects/SkComposeImageFilter.h
@@ -14,7 +14,13 @@
 public:
     virtual ~SkComposeImageFilter();
 
-    static SkComposeImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
+    static SkImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
+        if (NULL == outer) {
+            return SkSafeRef(inner);
+        }
+        if (NULL == inner) {
+            return SkRef(outer);
+        }
         SkImageFilter* inputs[2] = { outer, inner };
         return SkNEW_ARGS(SkComposeImageFilter, (inputs));
     }
@@ -22,8 +28,13 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
 
 protected:
-    explicit SkComposeImageFilter(SkImageFilter* inputs[2]) : INHERITED(2, inputs) {}
+    explicit SkComposeImageFilter(SkImageFilter* inputs[2]) : INHERITED(2, inputs) {
+        SkASSERT(inputs[0]);
+        SkASSERT(inputs[1]);
+    }
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkComposeImageFilter(SkReadBuffer& buffer);
+#endif
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
index 8bb7a50..e61d494 100644
--- a/include/effects/SkCornerPathEffect.h
+++ b/include/effects/SkCornerPathEffect.h
@@ -32,7 +32,9 @@
 
 protected:
     explicit SkCornerPathEffect(SkScalar radius);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkCornerPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDashPathEffect.h b/include/effects/SkDashPathEffect.h
index 6fab962..3946224 100644
--- a/include/effects/SkDashPathEffect.h
+++ b/include/effects/SkDashPathEffect.h
@@ -51,13 +51,13 @@
 
     virtual DashType asADash(DashInfo* info) const SK_OVERRIDE;
 
-    virtual Factory getFactory() const SK_OVERRIDE;
-
-    static SkFlattenable* CreateProc(SkReadBuffer&);
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDashPathEffect)
 
 protected:
     SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDashPathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDiscretePathEffect.h b/include/effects/SkDiscretePathEffect.h
index cbee20f..8f1082c 100644
--- a/include/effects/SkDiscretePathEffect.h
+++ b/include/effects/SkDiscretePathEffect.h
@@ -45,7 +45,9 @@
     SkDiscretePathEffect(SkScalar segLength,
                          SkScalar deviation,
                          uint32_t seedAssist);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDiscretePathEffect(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDisplacementMapEffect.h b/include/effects/SkDisplacementMapEffect.h
index 07f8ee9..a26d5a2 100644
--- a/include/effects/SkDisplacementMapEffect.h
+++ b/include/effects/SkDisplacementMapEffect.h
@@ -27,11 +27,7 @@
                                            ChannelSelectorType yChannelSelector,
                                            SkScalar scale, SkImageFilter* displacement,
                                            SkImageFilter* color = NULL,
-                                           const CropRect* cropRect = NULL) {
-        SkImageFilter* inputs[2] = { displacement, color };
-        return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
-                                                    inputs, cropRect));
-    }
+                                           const CropRect* cropRect = NULL);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
 
@@ -56,7 +52,9 @@
                             ChannelSelectorType yChannelSelector,
                             SkScalar scale, SkImageFilter* inputs[2],
                             const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkDropShadowImageFilter.h b/include/effects/SkDropShadowImageFilter.h
index efd9032..85f4afd 100644
--- a/include/effects/SkDropShadowImageFilter.h
+++ b/include/effects/SkDropShadowImageFilter.h
@@ -24,7 +24,9 @@
 protected:
     SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
                             SkImageFilter* input, const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDropShadowImageFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
diff --git a/include/effects/SkEmbossMaskFilter.h b/include/effects/SkEmbossMaskFilter.h
index a1e2af4..74895fb 100644
--- a/include/effects/SkEmbossMaskFilter.h
+++ b/include/effects/SkEmbossMaskFilter.h
@@ -37,7 +37,9 @@
 
 protected:
     SkEmbossMaskFilter(SkScalar blurSigma, const Light& light);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkEmbossMaskFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h
index ac56e28..5bb8b66 100644
--- a/include/effects/SkLayerDrawLooper.h
+++ b/include/effects/SkLayerDrawLooper.h
@@ -81,8 +81,14 @@
 
     SK_TO_STRING_OVERRIDE()
 
-    /// Implements Flattenable.
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    static SkFlattenable* DeepCreateProc(SkReadBuffer& buffer) {
+        return CreateProc(buffer);
+    }
+    virtual Factory getFactory() const SK_OVERRIDE { return DeepCreateProc; }
+#else
     virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; }
+#endif
     static SkFlattenable* CreateProc(SkReadBuffer& buffer);
 
 protected:
diff --git a/include/effects/SkLayerRasterizer.h b/include/effects/SkLayerRasterizer.h
index 44cbfa0..60b3f20 100644
--- a/include/effects/SkLayerRasterizer.h
+++ b/include/effects/SkLayerRasterizer.h
@@ -69,7 +69,9 @@
 protected:
     SkLayerRasterizer();
     SkLayerRasterizer(SkDeque* layers);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLayerRasterizer(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkRasterizer
diff --git a/include/effects/SkLerpXfermode.h b/include/effects/SkLerpXfermode.h
index d9186d9..d779f16 100644
--- a/include/effects/SkLerpXfermode.h
+++ b/include/effects/SkLerpXfermode.h
@@ -32,7 +32,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLerpXfermode)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLerpXfermode(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkLightingImageFilter.h b/include/effects/SkLightingImageFilter.h
index 81e8f43..3e055a8 100644
--- a/include/effects/SkLightingImageFilter.h
+++ b/include/effects/SkLightingImageFilter.h
@@ -74,14 +74,16 @@
                           SkScalar surfaceScale,
                           SkImageFilter* input,
                           const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
-    const SkLight* light() const { return fLight; }
+    const SkLight* light() const { return fLight.get(); }
     SkScalar surfaceScale() const { return fSurfaceScale; }
 
 private:
     typedef SkImageFilter INHERITED;
-    SkLight* fLight;
+    SkAutoTUnref<SkLight> fLight;
     SkScalar fSurfaceScale;
 };
 
diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h
index 06eb01a..38bab92 100644
--- a/include/effects/SkLumaColorFilter.h
+++ b/include/effects/SkLumaColorFilter.h
@@ -35,7 +35,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLumaColorFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkMagnifierImageFilter.h b/include/effects/SkMagnifierImageFilter.h
index 3f799d6..9ea4b37 100644
--- a/include/effects/SkMagnifierImageFilter.h
+++ b/include/effects/SkMagnifierImageFilter.h
@@ -14,16 +14,15 @@
 
 class SK_API SkMagnifierImageFilter : public SkImageFilter {
 public:
-    static SkMagnifierImageFilter* Create(const SkRect& srcRect, SkScalar inset,
-                                          SkImageFilter* input = NULL) {
-        return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset, input));
-    }
+    static SkImageFilter* Create(const SkRect& src, SkScalar inset, SkImageFilter* input = NULL);
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter)
 
 protected:
     SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset, SkImageFilter* input);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMagnifierImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h
index 0cb848b..d1ca052 100644
--- a/include/effects/SkMatrixConvolutionImageFilter.h
+++ b/include/effects/SkMatrixConvolutionImageFilter.h
@@ -78,7 +78,9 @@
                                    bool convolveAlpha,
                                    SkImageFilter* input,
                                    const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMatrixConvolutionImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMatrixImageFilter.h b/include/effects/SkMatrixImageFilter.h
index 14b0b8e..15f8243 100644
--- a/include/effects/SkMatrixImageFilter.h
+++ b/include/effects/SkMatrixImageFilter.h
@@ -41,7 +41,9 @@
     SkMatrixImageFilter(const SkMatrix& transform,
                         SkPaint::FilterLevel,
                         SkImageFilter* input);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkMatrixImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMergeImageFilter.h b/include/effects/SkMergeImageFilter.h
index ed316d7..a9a14a9 100644
--- a/include/effects/SkMergeImageFilter.h
+++ b/include/effects/SkMergeImageFilter.h
@@ -35,7 +35,9 @@
     SkMergeImageFilter(SkImageFilter* filters[], int count,
                        const SkXfermode::Mode modes[],
                        const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkMergeImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h
index 75551b6..499d6a8 100644
--- a/include/effects/SkMorphologyImageFilter.h
+++ b/include/effects/SkMorphologyImageFilter.h
@@ -34,7 +34,9 @@
     bool filterImageGeneric(Proc procX, Proc procY,
                             Proxy*, const SkBitmap& src, const Context&,
                             SkBitmap* result, SkIPoint* offset) const;
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkMorphologyImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 #if SK_SUPPORT_GPU
     virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
@@ -55,6 +57,9 @@
     static SkDilateImageFilter* Create(int radiusX, int radiusY,
                                        SkImageFilter* input = NULL,
                                        const CropRect* cropRect = NULL) {
+        if (radiusX < 0 || radiusY < 0) {
+            return NULL;
+        }
         return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect));
     }
 
@@ -70,7 +75,9 @@
 protected:
     SkDilateImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect)
         : INHERITED(radiusX, radiusY, input, cropRect) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkMorphologyImageFilter INHERITED;
@@ -81,6 +88,9 @@
     static SkErodeImageFilter* Create(int radiusX, int radiusY,
                                       SkImageFilter* input = NULL,
                                       const CropRect* cropRect = NULL) {
+        if (radiusX < 0 || radiusY < 0) {
+            return NULL;
+        }
         return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect));
     }
 
@@ -96,7 +106,9 @@
 protected:
     SkErodeImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect)
         : INHERITED(radiusX, radiusY, input, cropRect) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
 private:
     typedef SkMorphologyImageFilter INHERITED;
diff --git a/include/effects/SkOffsetImageFilter.h b/include/effects/SkOffsetImageFilter.h
index 7f17e85..d18dcae 100644
--- a/include/effects/SkOffsetImageFilter.h
+++ b/include/effects/SkOffsetImageFilter.h
@@ -17,6 +17,9 @@
 public:
     static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
                                        const CropRect* cropRect = NULL) {
+        if (!SkScalarIsFinite(dx) || !SkScalarIsFinite(dy)) {
+            return NULL;
+        }
         return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect));
     }
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
@@ -24,7 +27,9 @@
 
 protected:
     SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkOffsetImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h
index 3355925..f5f1af0 100644
--- a/include/effects/SkPerlinNoiseShader.h
+++ b/include/effects/SkPerlinNoiseShader.h
@@ -103,7 +103,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkPerlinNoiseShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h
index 84d0c10..7826eb8 100644
--- a/include/effects/SkPictureImageFilter.h
+++ b/include/effects/SkPictureImageFilter.h
@@ -40,7 +40,9 @@
      *  SkReadBuffer::setBitmapDecoder() before calling this constructor.
      *  @param SkReadBuffer Serialized picture data.
      */
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPictureImageFilter(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
diff --git a/include/effects/SkPixelXorXfermode.h b/include/effects/SkPixelXorXfermode.h
index 6464845..eb485b4 100644
--- a/include/effects/SkPixelXorXfermode.h
+++ b/include/effects/SkPixelXorXfermode.h
@@ -26,7 +26,9 @@
 
 protected:
     explicit SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkPixelXorXfermode(SkReadBuffer& rb);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     // override from SkXfermode
diff --git a/include/effects/SkRectShaderImageFilter.h b/include/effects/SkRectShaderImageFilter.h
index 817c44e..1a6ee08 100644
--- a/include/effects/SkRectShaderImageFilter.h
+++ b/include/effects/SkRectShaderImageFilter.h
@@ -34,7 +34,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkRectShaderImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkTableMaskFilter.h b/include/effects/SkTableMaskFilter.h
index eda1a1e..8b94179 100644
--- a/include/effects/SkTableMaskFilter.h
+++ b/include/effects/SkTableMaskFilter.h
@@ -55,7 +55,9 @@
 protected:
     SkTableMaskFilter();
     explicit SkTableMaskFilter(const uint8_t table[256]);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkTableMaskFilter(SkReadBuffer& rb);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/include/effects/SkTestImageFilters.h b/include/effects/SkTestImageFilters.h
index 2836040..a8186e0 100644
--- a/include/effects/SkTestImageFilters.h
+++ b/include/effects/SkTestImageFilters.h
@@ -8,6 +8,13 @@
 class SK_API SkDownSampleImageFilter : public SkImageFilter {
 public:
     static SkDownSampleImageFilter* Create(SkScalar scale, SkImageFilter* input = NULL) {
+        if (!SkScalarIsFinite(scale)) {
+            return NULL;
+        }
+        // we don't support scale in this range
+        if (scale > SK_Scalar1 || scale <= 0) {
+            return NULL;
+        }
         return SkNEW_ARGS(SkDownSampleImageFilter, (scale, input));
     }
 
@@ -16,7 +23,9 @@
 protected:
     SkDownSampleImageFilter(SkScalar scale, SkImageFilter* input)
       : INHERITED(1, &input), fScale(scale) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDownSampleImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index 29e3ca5..084f726 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -20,9 +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) {
-        return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input));
-    }
+                                     SkImageFilter* input);
 
     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE;
@@ -34,7 +32,9 @@
 protected:
     SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
         : INHERITED(1, &input), fSrcRect(srcRect), fDstRect(dstRect) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkTileImageFilter(SkReadBuffer& buffer);
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
 
diff --git a/include/effects/SkTransparentShader.h b/include/effects/SkTransparentShader.h
index d9a3e5d..e23687c 100644
--- a/include/effects/SkTransparentShader.h
+++ b/include/effects/SkTransparentShader.h
@@ -37,8 +37,13 @@
 protected:
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
+    // we don't need to flatten anything at all
+    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE {}
+
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkTransparentShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkShader INHERITED;
 };
diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h
index 05f96c4..7c29e28 100644
--- a/include/effects/SkXfermodeImageFilter.h
+++ b/include/effects/SkXfermodeImageFilter.h
@@ -46,7 +46,9 @@
 protected:
     SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* inputs[2],
                           const CropRect* cropRect);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkXfermodeImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
diff --git a/samplecode/ClockFaceView.cpp b/samplecode/ClockFaceView.cpp
index a887cc6..46d4120 100644
--- a/samplecode/ClockFaceView.cpp
+++ b/samplecode/ClockFaceView.cpp
@@ -90,13 +90,15 @@
         dst->addCircle(loc.fX, loc.fY, fRadius);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
         fRadius = buffer.readScalar();
         fPts = NULL;
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
+        buffer.writeMatrix(this->getMatrix());
         buffer.writeScalar(fRadius);
     }
 
@@ -107,6 +109,12 @@
     typedef Sk2DPathEffect INHERITED;
 };
 
+SkFlattenable* Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    return SkNEW_ARGS(Dot2DPathEffect, (buffer.readScalar(), matrix, NULL));
+}
+
 class InverseFillPE : public SkPathEffect {
 public:
     InverseFillPE() {}
@@ -119,12 +127,19 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(InverseFillPE)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     InverseFillPE(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
 private:
 
     typedef SkPathEffect INHERITED;
 };
 
+SkFlattenable* InverseFillPE::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW(InverseFillPE);
+}
+
 static SkPathEffect* makepe(float interp, SkTDArray<SkPoint>* pts) {
     SkMatrix    lattice;
     SkScalar    rad = 3 + SkIntToScalar(4) * (1 - interp);
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index 92fe258..395314c 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -172,9 +172,11 @@
         dst->addCircle(loc.fX, loc.fY, fRadius);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
         fRadius = buffer.readScalar();
     }
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
         this->INHERITED::flatten(buffer);
         buffer.writeScalar(fRadius);
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index e7cc035..6e2a7ca 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -39,13 +39,14 @@
     fTileModeY = (uint8_t)tmy;
 }
 
-SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     buffer.readBitmap(&fRawBitmap);
     fRawBitmap.setImmutable();
     fTileModeX = buffer.readUInt();
     fTileModeY = buffer.readUInt();
 }
+#endif
 
 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
                                                    SkMatrix* texM,
@@ -63,9 +64,21 @@
     return kDefault_BitmapType;
 }
 
-void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+SkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    SkBitmap bm;
+    if (!buffer.readBitmap(&bm)) {
+        return NULL;
+    }
+    bm.setImmutable();
+    TileMode mx = (TileMode)buffer.readUInt();
+    TileMode my = (TileMode)buffer.readUInt();
+    return SkShader::CreateBitmapShader(bm, mx, my, &lm);
+}
 
+void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.writeBitmap(fRawBitmap);
     buffer.writeUInt(fTileModeX);
     buffer.writeUInt(fTileModeY);
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 550d1d2..d445f56 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -55,7 +55,9 @@
     };
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkBitmapProcShader(SkReadBuffer& );
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index cb84ec7..b2da6ae 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -714,19 +714,17 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
         fProxy = buffer.readShader();
         // Leaving this here until we bump the picture version, though this
         // shader should never be recorded.
         buffer.readColor();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
         buffer.writeFlattenable(fProxy);
-        // Leaving this here until we bump the picture version, though this
-        // shader should never be recorded.
-        buffer.writeColor(SkColor());
     }
 
 private:
@@ -735,6 +733,11 @@
     typedef SkShader INHERITED;
 };
 
+SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    return SkNEW_ARGS(Sk3DShader, (shader));
+}
+
 class Sk3DBlitter : public SkBlitter {
 public:
     Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext)
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index f7de73b..3c5b55a 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -26,8 +26,8 @@
     SkSafeRef(mode);
 }
 
-SkComposeShader::SkComposeShader(SkReadBuffer& buffer) :
-    INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkComposeShader::SkComposeShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fShaderA = buffer.readShader();
     if (NULL == fShaderA) {
         fShaderA = SkNEW_ARGS(SkColorShader, ((SkColor)0));
@@ -38,6 +38,7 @@
     }
     fMode = buffer.readXfermode();
 }
+#endif
 
 SkComposeShader::~SkComposeShader() {
     SkSafeUnref(fMode);
@@ -66,8 +67,17 @@
 };
 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
 
+SkFlattenable* SkComposeShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shaderA(buffer.readShader());
+    SkAutoTUnref<SkShader> shaderB(buffer.readShader());
+    SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
+    if (!shaderA.get() || !shaderB.get()) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkComposeShader, (shaderA, shaderB, mode));
+}
+
 void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fShaderA);
     buffer.writeFlattenable(fShaderB);
     buffer.writeFlattenable(fMode);
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 9bc29b3..d0d4f07 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2019,11 +2019,9 @@
     };
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader)
+    SK_DECLARE_NOT_FLATTENABLE_PROCS(SkTriColorShader)
 
 protected:
-    SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {}
-
     virtual Context* onCreateContext(const ContextRec& rec, void* storage) const SK_OVERRIDE {
         return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
     }
diff --git a/src/core/SkEmptyShader.h b/src/core/SkEmptyShader.h
index 7de3bc1..250e37a 100644
--- a/src/core/SkEmptyShader.h
+++ b/src/core/SkEmptyShader.h
@@ -30,7 +30,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkEmptyShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     virtual SkShader::Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE {
         return NULL;
diff --git a/src/core/SkFilterShader.cpp b/src/core/SkFilterShader.cpp
index 0c92d4c..cb042e6 100644
--- a/src/core/SkFilterShader.cpp
+++ b/src/core/SkFilterShader.cpp
@@ -21,19 +21,28 @@
     filter->ref();
 }
 
-SkFilterShader::SkFilterShader(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkFilterShader::SkFilterShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fShader = buffer.readShader();
     fFilter = buffer.readColorFilter();
 }
+#endif
 
 SkFilterShader::~SkFilterShader() {
     fFilter->unref();
     fShader->unref();
 }
 
+SkFlattenable* SkFilterShader::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    SkAutoTUnref<SkColorFilter> filter(buffer.readColorFilter());
+    if (!shader.get() || !filter.get()) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkFilterShader, (shader, filter));
+}
+
 void SkFilterShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fShader);
     buffer.writeFlattenable(fFilter);
 }
diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h
index 1a4b71f..2ff6cda 100644
--- a/src/core/SkFilterShader.h
+++ b/src/core/SkFilterShader.h
@@ -40,7 +40,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader)
 
 protected:
-    SkFilterShader(SkReadBuffer& );
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkFilterShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
diff --git a/src/core/SkFlattenable.cpp b/src/core/SkFlattenable.cpp
index 410fe0d..ae17be5 100644
--- a/src/core/SkFlattenable.cpp
+++ b/src/core/SkFlattenable.cpp
@@ -1,22 +1,21 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #include "SkFlattenable.h"
 #include "SkPtrRecorder.h"
+#include "SkReadBuffer.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkFlattenable::flatten(SkWriteBuffer&) const
-{
-    /*  we don't write anything at the moment, but this allows our subclasses
-        to not know that, since we want them to always call INHERITED::flatten()
-        in their code.
-    */
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+bool SkFlattenable::NeedsDeepUnflatten(const SkReadBuffer& buffer) {
+    return buffer.isVersionLT(SkReadBuffer::kFlattenCreateProc_Version);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 4a9a22e..20c7d57 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -75,11 +75,11 @@
 }
 
 bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) {
-    int count = buffer.readInt();
-    if (expectedCount < 0) {    // means the caller doesn't care how many
-        expectedCount = count;
+    const int count = buffer.readInt();
+    if (!buffer.validate(count >= 0)) {
+        return false;
     }
-    if (!buffer.validate((count == expectedCount) && (count >= 0))) {
+    if (!buffer.validate(expectedCount < 0 || count == expectedCount)) {
         return false;
     }
 
diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp
index e5d9248..62840dd 100644
--- a/src/core/SkLocalMatrixShader.cpp
+++ b/src/core/SkLocalMatrixShader.cpp
@@ -7,6 +7,7 @@
 
 #include "SkLocalMatrixShader.h"
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLocalMatrixShader::SkLocalMatrixShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     if (buffer.isVersionLT(SkReadBuffer::kSimplifyLocalMatrix_Version)) {
         buffer.readMatrix(&(INHERITED::fLocalMatrix));
@@ -16,9 +17,20 @@
         sk_throw();
     }
 }
+#endif
+
+SkFlattenable* SkLocalMatrixShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    SkAutoTUnref<SkShader> shader(buffer.readShader());
+    if (!shader.get()) {
+        return NULL;
+    }
+    return SkShader::CreateLocalMatrixShader(shader, lm);
+}
 
 void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.writeFlattenable(fProxyShader.get());
 }
 
diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h
index 7eb7c13..352c1e3 100644
--- a/src/core/SkLocalMatrixShader.h
+++ b/src/core/SkLocalMatrixShader.h
@@ -64,7 +64,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixShader)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkLocalMatrixShader(SkReadBuffer&);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
 
diff --git a/src/core/SkPathEffect.cpp b/src/core/SkPathEffect.cpp
index 01d5d6f..d074867 100644
--- a/src/core/SkPathEffect.cpp
+++ b/src/core/SkPathEffect.cpp
@@ -45,19 +45,26 @@
     Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data]
 */
 void SkPairPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeFlattenable(fPE0);
     buffer.writeFlattenable(fPE1);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPairPathEffect::SkPairPathEffect(SkReadBuffer& buffer) {
     fPE0 = buffer.readPathEffect();
     fPE1 = buffer.readPathEffect();
     // either of these may fail, so we have to check for nulls later on
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkComposePathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPathEffect> pe0(buffer.readPathEffect());
+    SkAutoTUnref<SkPathEffect> pe1(buffer.readPathEffect());
+    return SkComposePathEffect::Create(pe0, pe1);
+}
+
 bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src,
                              SkStrokeRec* rec, const SkRect* cullRect) const {
     // we may have failed to unflatten these, so we have to check
@@ -76,6 +83,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkSumPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPathEffect> pe0(buffer.readPathEffect());
+    SkAutoTUnref<SkPathEffect> pe1(buffer.readPathEffect());
+    return SkSumPathEffect::Create(pe0, pe1);
+}
+
 bool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src,
                              SkStrokeRec* rec, const SkRect* cullRect) const {
     // use bit-or so that we always call both, even if the first one succeeds
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 65a2cd3..3e0eb65 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -28,13 +28,14 @@
                                           SkIntToScalar(picture->height()));
 }
 
-SkPictureShader::SkPictureShader(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPictureShader::SkPictureShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fTmx = static_cast<SkShader::TileMode>(buffer.read32());
     fTmy = static_cast<SkShader::TileMode>(buffer.read32());
     buffer.readRect(&fTile);
     fPicture = SkPicture::CreateFromBuffer(buffer);
 }
+#endif
 
 SkPictureShader::~SkPictureShader() {
     fPicture->unref();
@@ -49,9 +50,19 @@
     return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix, tile));
 }
 
-void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix lm;
+    buffer.readMatrix(&lm);
+    TileMode mx = (TileMode)buffer.read32();
+    TileMode my = (TileMode)buffer.read32();
+    SkRect tile;
+    buffer.readRect(&tile);
+    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromBuffer(buffer));
+    return SkPictureShader::Create(picture, mx, my, &lm, &tile);
+}
 
+void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeMatrix(this->getLocalMatrix());
     buffer.write32(fTmx);
     buffer.write32(fTmy);
     buffer.writeRect(fTile);
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index cd34686..a5b9830 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -48,6 +48,7 @@
         kSimplifyLocalMatrix_Version       = 30,
         kImageFilterUniqueID_Version       = 31,
         kRemoveAndroidPaintOpts_Version    = 32,
+        kFlattenCreateProc_Version         = 33,
     };
 
     /**
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 305cf06..85707d7 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -45,6 +45,7 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkShader::SkShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     inc_shader_counter();
     if (buffer.readBool()) {
@@ -53,6 +54,7 @@
         fLocalMatrix.reset();
     }
 }
+#endif
 
 SkShader::~SkShader() {
     dec_shader_counter();
@@ -254,6 +256,7 @@
     return SkColorGetA(fColor) == 255;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) {
     // V25_COMPATIBILITY_CODE We had a boolean to make the color shader inherit the paint's
     // color. We don't support that any more.
@@ -266,9 +269,13 @@
     }
     fColor = b.readColor();
 }
+#endif
+
+SkFlattenable* SkColorShader::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkColorShader, (buffer.readColor()));
+}
 
 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeColor(fColor);
 }
 
@@ -383,6 +390,10 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkFlattenable* SkEmptyShader::CreateProc(SkReadBuffer&) {
+    return SkShader::CreateEmptyShader();
+}
+
 #ifndef SK_IGNORE_TO_STRING
 #include "SkEmptyShader.h"
 
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 0811808..7608b79 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1240,6 +1240,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs);
     if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) {
@@ -1254,6 +1255,19 @@
     fSrcCoeff = rec.fSC;
     fDstCoeff = rec.fDC;
 }
+#endif
+
+SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) {
+    uint32_t mode32 = buffer.read32();
+    if (!buffer.validate(mode32 >= SK_ARRAY_COUNT(gProcCoeffs))) {
+        return NULL;
+    }
+    return SkXfermode::Create((SkXfermode::Mode)mode32);
+}
+
+void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
+    buffer.write32(fMode);
+}
 
 bool SkProcCoeffXfermode::asMode(Mode* mode) const {
     if (mode) {
@@ -1376,11 +1390,6 @@
 }
 #endif
 
-void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.write32(fMode);
-}
-
 const char* SkXfermode::ModeName(Mode mode) {
     SkASSERT((unsigned) mode <= (unsigned)kLastMode);
     const char* gModeStrings[] = {
@@ -1433,12 +1442,12 @@
     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode)
 
 private:
     SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
-    SkClearXfermode(SkReadBuffer& buffer)
-        : SkProcCoeffXfermode(buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1498,13 +1507,12 @@
     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode)
 
 private:
     SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
-    SkSrcXfermode(SkReadBuffer& buffer)
-        : SkProcCoeffXfermode(buffer) {}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
+#endif
     typedef SkProcCoeffXfermode INHERITED;
 };
 
@@ -1567,11 +1575,12 @@
     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode)
 
 private:
     SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1613,12 +1622,12 @@
     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode)
 
 private:
     SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
-    SkDstOutXfermode(SkReadBuffer& buffer)
-        : INHERITED(buffer) {}
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+    SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
 
     typedef SkProcCoeffXfermode INHERITED;
 };
@@ -1692,7 +1701,7 @@
                 break;
             default:
                 // no special-case, just rely in the rec and its function-ptrs
-                xfer = SkProcCoeffXfermode::Create(rec, mode);
+                xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
                 break;
         }
     }
@@ -1952,14 +1961,4 @@
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
-#if !SK_ARM_NEON_IS_NONE
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode)
-#endif
-#if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSSE2ProcCoeffXfermode)
-#endif
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h
index b777f62..47472e6 100644
--- a/src/core/SkXfermode_proccoeff.h
+++ b/src/core/SkXfermode_proccoeff.h
@@ -15,10 +15,14 @@
 
 class SK_API SkProcCoeffXfermode : public SkXfermode {
 public:
-    static SkProcCoeffXfermode* Create(const ProcCoeff& rec, Mode mode) {
-        return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
+    SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) {
+        fMode = mode;
+        fProc = rec.fProc;
+        // these may be valid, or may be CANNOT_USE_COEFF
+        fSrcCoeff = rec.fSC;
+        fDstCoeff = rec.fDC;
     }
-
+    
     virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                         const SkAlpha aa[]) const SK_OVERRIDE;
     virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
@@ -39,15 +43,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode)
 
 protected:
-    SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) {
-        fMode = mode;
-        fProc = rec.fProc;
-        // these may be valid, or may be CANNOT_USE_COEFF
-        fSrcCoeff = rec.fSC;
-        fDstCoeff = rec.fDC;
-    }
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
 
@@ -60,6 +58,8 @@
     Mode            fMode;
     Coeff           fSrcCoeff, fDstCoeff;
 
+    friend class SkXfermode;
+
     typedef SkXfermode INHERITED;
 };
 
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 7354cda..47824fd 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -147,6 +147,7 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPath1DPathEffect::SkPath1DPathEffect(SkReadBuffer& buffer) {
     fAdvance = buffer.readScalar();
     if (fAdvance > 0) {
@@ -160,13 +161,25 @@
         fStyle = kStyleCount;
     }
 }
+#endif
 
 SkScalar SkPath1DPathEffect::begin(SkScalar contourLength) const {
     return fInitialOffset;
 }
 
+SkFlattenable* SkPath1DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkScalar advance = buffer.readScalar();
+    if (advance > 0) {
+        SkPath path;
+        buffer.readPath(&path);
+        SkScalar phase = buffer.readScalar();
+        Style style = (Style)buffer.readUInt();
+        return SkPath1DPathEffect::Create(path, advance, phase, style);
+    }
+    return NULL;
+}
+
 void SkPath1DPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fAdvance);
     if (fAdvance > 0) {
         buffer.writePath(fPath);
diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp
index 252866c..cef2266 100644
--- a/src/effects/Sk2DPathEffect.cpp
+++ b/src/effects/Sk2DPathEffect.cpp
@@ -73,10 +73,12 @@
     buffer.writeMatrix(fMatrix);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 Sk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) {
     buffer.readMatrix(&fMatrix);
     fMatrixIsInvertible = fMatrix.invert(&fInverse);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -102,12 +104,21 @@
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
     fWidth = buffer.readScalar();
 }
+#endif
+
+SkFlattenable* SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkScalar width = buffer.readScalar();
+    return SkLine2DPathEffect::Create(width, matrix);
+}
 
 void SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeMatrix(this->getMatrix());
     buffer.writeScalar(fWidth);
 }
 
@@ -117,13 +128,22 @@
     : INHERITED(m), fPath(p) {
 }
 
-SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
     buffer.readPath(&fPath);
 }
+#endif
+
+SkFlattenable* SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkPath path;
+    buffer.readPath(&path);
+    return SkPath2DPathEffect::Create(matrix, path);
+}
 
 void SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeMatrix(this->getMatrix());
     buffer.writePath(fPath);
 }
 
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 39a319b..9c59347 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -19,7 +19,9 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterImpl)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkAlphaThresholdFilterImpl(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
@@ -233,12 +235,23 @@
 
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fInnerThreshold = buffer.readScalar();
     fOuterThreshold = buffer.readScalar();
     buffer.readRegion(&fRegion);
 }
+#endif
+
+SkFlattenable* SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar inner = buffer.readScalar();
+    SkScalar outer = buffer.readScalar();
+    SkRegion rgn;
+    buffer.readRegion(&rgn);
+    return SkAlphaThresholdFilter::Create(rgn, inner, outer, common.getInput(0));
+}
 
 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
                                                        SkScalar innerThreshold,
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index 7d9997a..d3be826 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -47,6 +47,7 @@
         fEnforcePMColor = enforcePMColor;
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) {
         fK[0] = buffer.readScalar();
         fK[1] = buffer.readScalar();
@@ -54,9 +55,9 @@
         fK[3] = buffer.readScalar();
         fEnforcePMColor = buffer.readBool();
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        INHERITED::flatten(buffer);
         buffer.writeScalar(fK[0]);
         buffer.writeScalar(fK[1]);
         buffer.writeScalar(fK[2]);
@@ -66,9 +67,20 @@
     SkScalar fK[4];
     bool fEnforcePMColor;
 
+    friend class SkArithmeticMode;
+
     typedef SkXfermode INHERITED;
 };
 
+SkFlattenable* SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) {
+    const SkScalar k1 = buffer.readScalar();
+    const SkScalar k2 = buffer.readScalar();
+    const SkScalar k3 = buffer.readScalar();
+    const SkScalar k4 = buffer.readScalar();
+    const bool enforcePMColor = buffer.readBool();
+    return Create(k1, k2, k3, k4, enforcePMColor);
+}
+
 static int pinToByte(int value) {
     if (value < 0) {
         value = 0;
diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp
index ffe6a21..aae6ba5 100644
--- a/src/effects/SkAvoidXfermode.cpp
+++ b/src/effects/SkAvoidXfermode.cpp
@@ -15,24 +15,30 @@
     if (tolerance > 255) {
         tolerance = 255;
     }
-
+    fTolerance = SkToU8(tolerance);
     fOpColor = opColor;
     fDistMul = (256 << 14) / (tolerance + 1);
     fMode = mode;
 }
 
-SkAvoidXfermode::SkAvoidXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkAvoidXfermode::SkAvoidXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fOpColor = buffer.readColor();
     fDistMul = buffer.readUInt();
     fMode = (Mode)buffer.readUInt();
 }
+#endif
+
+SkFlattenable* SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) {
+    const SkColor color = buffer.readColor();
+    const unsigned tolerance = buffer.readUInt();
+    const unsigned mode = buffer.readUInt();
+    return Create(color, tolerance, (Mode)mode);
+}
 
 void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     buffer.writeColor(fOpColor);
-    buffer.writeUInt(fDistMul);
+    buffer.writeUInt(fTolerance);
     buffer.writeUInt(fMode);
 }
 
diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp
index d8d4329..aee4a36 100644
--- a/src/effects/SkBitmapSource.cpp
+++ b/src/effects/SkBitmapSource.cpp
@@ -13,12 +13,12 @@
 #include "SkValidationUtils.h"
 
 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap)
-  : INHERITED(0, 0),
-    fBitmap(bitmap),
-    fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
-                            SkIntToScalar(bitmap.height()))),
-    fDstRect(fSrcRect) {
-}
+  : INHERITED(0, 0)
+  , fBitmap(bitmap)
+  , fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
+                            SkIntToScalar(bitmap.height())))
+  , fDstRect(fSrcRect)
+{}
 
 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect)
   : INHERITED(0, 0)
@@ -26,6 +26,7 @@
   , fSrcRect(srcRect)
   , fDstRect(dstRect) {}
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBitmapSource::SkBitmapSource(SkReadBuffer& buffer) : INHERITED(0, buffer) {
     if (buffer.isVersionLT(SkReadBuffer::kNoMoreBitmapFlatten_Version)) {
         fBitmap.legacyUnflatten(buffer);
@@ -36,12 +37,23 @@
     buffer.readRect(&fDstRect);
     buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
 }
+#endif
+
+SkFlattenable* SkBitmapSource::CreateProc(SkReadBuffer& buffer) {
+    SkRect src, dst;
+    buffer.readRect(&src);
+    buffer.readRect(&dst);
+    SkBitmap bitmap;
+    if (!buffer.readBitmap(&bitmap)) {
+        return NULL;
+    }
+    return SkBitmapSource::Create(bitmap, src, dst);
+}
 
 void SkBitmapSource::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeBitmap(fBitmap);
     buffer.writeRect(fSrcRect);
     buffer.writeRect(fDstRect);
+    buffer.writeBitmap(fBitmap);
 }
 
 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
diff --git a/src/effects/SkBlurDrawLooper.cpp b/src/effects/SkBlurDrawLooper.cpp
index c3b843f..fc9e47b 100644
--- a/src/effects/SkBlurDrawLooper.cpp
+++ b/src/effects/SkBlurDrawLooper.cpp
@@ -62,6 +62,7 @@
     this->initEffects();
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBlurDrawLooper::SkBlurDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {
 
     fSigma = buffer.readScalar();
@@ -72,13 +73,22 @@
 
     this->initEffects();
 }
+#endif
+
+SkFlattenable* SkBlurDrawLooper::CreateProc(SkReadBuffer& buffer) {
+    const SkColor color = buffer.readColor();
+    const SkScalar sigma = buffer.readScalar();
+    const SkScalar dx = buffer.readScalar();
+    const SkScalar dy = buffer.readScalar();
+    const uint32_t flags = buffer.read32();
+    return Create(color, sigma, dx, dy, flags);
+}
 
 void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
+    buffer.writeColor(fBlurColor);
     buffer.writeScalar(fSigma);
     buffer.writeScalar(fDx);
     buffer.writeScalar(fDy);
-    buffer.writeColor(fBlurColor);
     buffer.write32(fBlurFlags);
 }
 
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index 5c3ff49..71bc811 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -23,6 +23,7 @@
 // raster paths.
 #define MAX_SIGMA SkIntToScalar(532)
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkBlurImageFilter::SkBlurImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fSigma.fWidth = buffer.readScalar();
@@ -32,6 +33,7 @@
                     (fSigma.fWidth >= 0) &&
                     (fSigma.fHeight >= 0));
 }
+#endif
 
 SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX,
                                      SkScalar sigmaY,
@@ -41,6 +43,13 @@
     SkASSERT(sigmaX >= 0 && sigmaY >= 0);
 }
 
+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());
+}
+
 void SkBlurImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeScalar(fSigma.fWidth);
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 9330c59..4e469bc 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -108,6 +108,8 @@
         return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA);
     }
 
+    friend class SkBlurMaskFilter;
+
     typedef SkMaskFilter INHERITED;
 };
 
@@ -522,19 +524,29 @@
              src.fRight + pad, src.fBottom + pad);
 }
 
-SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer)
-        : SkMaskFilter(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer) : SkMaskFilter(buffer) {
     fSigma = buffer.readScalar();
     fBlurStyle = (SkBlurStyle)buffer.readInt();
     fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag;
     SkASSERT(fSigma > 0);
     SkASSERT((unsigned)fBlurStyle <= kLastEnum_SkBlurStyle);
 }
+#endif
+
+SkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
+    const SkScalar sigma = buffer.readScalar();
+    const unsigned style = buffer.readUInt();
+    const unsigned flags = buffer.readUInt();
+    if (style <= kLastEnum_SkBlurStyle) {
+        return SkBlurMaskFilter::Create((SkBlurStyle)style, sigma, flags);
+    }
+    return NULL;
+}
 
 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fSigma);
-    buffer.writeInt(fBlurStyle);
+    buffer.writeUInt(fBlurStyle);
     buffer.writeUInt(fBlurFlags);
 }
 
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index 2c37067..2a7cc31 100755
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -83,14 +83,20 @@
     SkSafeRef(cf);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkColorFilterImageFilter::SkColorFilterImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fColorFilter = buffer.readColorFilter();
 }
+#endif
+
+SkFlattenable* SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    return Create(buffer.readColorFilter(), common.getInput(0), &common.cropRect());
+}
 
 void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeFlattenable(fColorFilter);
 }
 
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 43df5e9..bcaabf6 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -15,17 +15,9 @@
 #include "SkValidationUtils.h"
 #include "SkColorMatrixFilter.h"
 
-#define ILLEGAL_XFERMODE_MODE   ((SkXfermode::Mode)-1)
-
 // baseclass for filters that store a color and mode
 class SkModeColorFilter : public SkColorFilter {
 public:
-    SkModeColorFilter(SkColor color) {
-        fColor = color;
-        fMode = ILLEGAL_XFERMODE_MODE;
-        this->updateCache();
-    }
-
     SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
         fColor = color;
         fMode = mode;
@@ -34,14 +26,9 @@
 
     SkColor getColor() const { return fColor; }
     SkXfermode::Mode getMode() const { return fMode; }
-    bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; }
     SkPMColor getPMColor() const { return fPMColor; }
 
     virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const SK_OVERRIDE {
-        if (ILLEGAL_XFERMODE_MODE == fMode) {
-            return false;
-        }
-
         if (color) {
             *color = fColor;
         }
@@ -93,11 +80,11 @@
 
 protected:
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
-        this->INHERITED::flatten(buffer);
         buffer.writeColor(fColor);
         buffer.writeUInt(fMode);
     }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkModeColorFilter(SkReadBuffer& buffer) {
         fColor = buffer.readColor();
         fMode = (SkXfermode::Mode)buffer.readUInt();
@@ -106,6 +93,7 @@
             buffer.validate(SkIsValidMode(fMode));
         }
     }
+#endif
 
 private:
     SkColor             fColor;
@@ -121,9 +109,17 @@
         fProc16 = SkXfermode::GetProc16(fMode, fColor);
     }
 
+    friend class SkColorFilter;
+
     typedef SkColorFilter INHERITED;
 };
 
+SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
+    SkColor color = buffer.readColor();
+    SkXfermode::Mode mode = (SkXfermode::Mode)buffer.readUInt();
+    return SkColorFilter::CreateModeFilter(color, mode);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 #if SK_SUPPORT_GPU
 #include "GrBlend.h"
@@ -443,12 +439,6 @@
         sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
     }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Src_SkModeColorFilter)
-
-protected:
-    Src_SkModeColorFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {}
-
 private:
     typedef SkModeColorFilter INHERITED;
 };
@@ -479,14 +469,6 @@
         sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count);
     }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SrcOver_SkModeColorFilter)
-
-protected:
-    SrcOver_SkModeColorFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
-            fColor32Proc = SkBlitRow::ColorProcFactory();
-        }
-
 private:
 
     SkBlitRow::ColorProc fColor32Proc;
@@ -496,8 +478,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
-                                               SkXfermode::Mode mode) {
+SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, SkXfermode::Mode mode) {
+    if (!SkIsValidMode(mode)) {
+        return NULL;
+    }
+
     unsigned alpha = SkColorGetA(color);
 
     // first collaps some modes if possible
@@ -562,6 +547,4 @@
 
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index d76502e..f62e0f1 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -303,18 +303,26 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20);
     buffer.writeScalarArray(fMatrix.fMat, 20);
 }
 
-SkColorMatrixFilter::SkColorMatrixFilter(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkColorMatrixFilter::SkColorMatrixFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
     SkASSERT(buffer.getArrayCount() == 20);
     if (buffer.readScalarArray(fMatrix.fMat, 20)) {
         this->initState(fMatrix.fMat);
     }
 }
+#endif
+
+SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) {
+    SkColorMatrix matrix;
+    if (buffer.readScalarArray(matrix.fMat, 20)) {
+        return Create(matrix);
+    }
+    return NULL;
+}
 
 bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const {
     if (matrix) {
diff --git a/src/effects/SkComposeImageFilter.cpp b/src/effects/SkComposeImageFilter.cpp
index 645d633..c055674 100644
--- a/src/effects/SkComposeImageFilter.cpp
+++ b/src/effects/SkComposeImageFilter.cpp
@@ -21,14 +21,6 @@
     SkImageFilter* outer = getInput(0);
     SkImageFilter* inner = getInput(1);
 
-    if (!outer && !inner) {
-        return false;
-    }
-
-    if (!outer || !inner) {
-        return (outer ? outer : inner)->filterImage(proxy, src, ctx, result, offset);
-    }
-
     SkBitmap tmp;
     return inner->filterImage(proxy, src, ctx, &tmp, offset) &&
            outer->filterImage(proxy, tmp, ctx, result, offset);
@@ -40,19 +32,17 @@
     SkImageFilter* outer = getInput(0);
     SkImageFilter* inner = getInput(1);
 
-    if (!outer && !inner) {
-        return false;
-    }
-
-    if (!outer || !inner) {
-        return (outer ? outer : inner)->filterBounds(src, ctm, dst);
-    }
-
     SkIRect tmp;
-    return inner->filterBounds(src, ctm, &tmp) &&
-           outer->filterBounds(tmp, ctm, dst);
+    return inner->filterBounds(src, ctm, &tmp) && outer->filterBounds(tmp, ctm, dst);
 }
 
+SkFlattenable* SkComposeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
+    return SkComposeImageFilter::Create(common.getInput(0), common.getInput(1));
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkComposeImageFilter::SkComposeImageFilter(SkReadBuffer& buffer)
   : INHERITED(2, buffer) {
 }
+#endif
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index 5b61e06..0655882 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -128,11 +128,16 @@
     return true;
 }
 
+SkFlattenable* SkCornerPathEffect::CreateProc(SkReadBuffer& buffer) {
+    return SkCornerPathEffect::Create(buffer.readScalar());
+}
+
 void SkCornerPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fRadius);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkCornerPathEffect::SkCornerPathEffect(SkReadBuffer& buffer) {
     fRadius = buffer.readScalar();
 }
+#endif
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index d91e7be..66462af 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -238,20 +238,22 @@
     return kDash_DashType;
 }
 
-SkFlattenable::Factory SkDashPathEffect::getFactory() const {
-    return CreateProc;
-}
-
 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fPhase);
     buffer.writeScalarArray(fIntervals, fCount);
 }
 
 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) {
-    return SkNEW_ARGS(SkDashPathEffect, (buffer));
+    const SkScalar phase = buffer.readScalar();
+    uint32_t count = buffer.getArrayCount();
+    SkAutoSTArray<32, SkScalar> intervals(count);
+    if (buffer.readScalarArray(intervals.get(), count)) {
+        return Create(intervals.get(), SkToInt(count), phase);
+    }
+    return NULL;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer)
         : INHERITED(buffer)
         , fPhase(0)
@@ -292,3 +294,5 @@
                 &fInitialDashLength, &fInitialDashIndex, &fIntervalLength);
     }
 }
+#endif
+
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index f6f9112..e8cc6a2 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -75,15 +75,24 @@
     return true;
 }
 
+SkFlattenable* SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
+    SkScalar segLength = buffer.readScalar();
+    SkScalar perterb = buffer.readScalar();
+    uint32_t seed = buffer.readUInt();
+    return Create(segLength, perterb, seed);
+}
+
 void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeScalar(fSegLength);
     buffer.writeScalar(fPerterb);
     buffer.writeUInt(fSeedAssist);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) {
     fSegLength = buffer.readScalar();
     fPerterb = buffer.readScalar();
     fSeedAssist = buffer.readUInt();
 }
+#endif
+
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index bae7ac0..27fc0d3 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -159,6 +159,22 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+SkDisplacementMapEffect* SkDisplacementMapEffect::Create(ChannelSelectorType xChannelSelector,
+                                                         ChannelSelectorType yChannelSelector,
+                                                         SkScalar scale,
+                                                         SkImageFilter* displacement,
+                                                         SkImageFilter* color,
+                                                         const CropRect* cropRect) {
+    if (!channel_selector_type_is_valid(xChannelSelector) ||
+        !channel_selector_type_is_valid(yChannelSelector)) {
+        return NULL;
+    }
+
+    SkImageFilter* inputs[2] = { displacement, color };
+    return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
+                                                inputs, cropRect));
+}
+
 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
                                                  ChannelSelectorType yChannelSelector,
                                                  SkScalar scale,
@@ -174,6 +190,7 @@
 SkDisplacementMapEffect::~SkDisplacementMapEffect() {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDisplacementMapEffect::SkDisplacementMapEffect(SkReadBuffer& buffer)
   : INHERITED(2, buffer)
 {
@@ -184,6 +201,15 @@
                     channel_selector_type_is_valid(fYChannelSelector) &&
                     SkScalarIsFinite(fScale));
 }
+#endif
+
+SkFlattenable* SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
+    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());
+}
 
 void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 1d22bbd..f1ebae8 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -27,6 +27,7 @@
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDropShadowImageFilter::SkDropShadowImageFilter(SkReadBuffer& buffer)
  : INHERITED(1, buffer) {
     fDx = buffer.readScalar();
@@ -39,9 +40,19 @@
                     SkScalarIsFinite(fSigmaX) &&
                     SkScalarIsFinite(fSigmaY));
 }
+#endif
 
-void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const
-{
+SkFlattenable* SkDropShadowImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkScalar dx = buffer.readScalar();
+    SkScalar dy = buffer.readScalar();
+    SkScalar sigmaX = buffer.readScalar();
+    SkScalar sigmaY = buffer.readScalar();
+    SkColor color = buffer.readColor();
+    return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect());
+}
+
+void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeScalar(fDx);
     buffer.writeScalar(fDy);
diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp
index cdd55fc..4841b92 100644
--- a/src/effects/SkEmbossMaskFilter.cpp
+++ b/src/effects/SkEmbossMaskFilter.cpp
@@ -124,17 +124,26 @@
     return true;
 }
 
-SkEmbossMaskFilter::SkEmbossMaskFilter(SkReadBuffer& buffer)
-        : SkMaskFilter(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkEmbossMaskFilter::SkEmbossMaskFilter(SkReadBuffer& buffer) : SkMaskFilter(buffer) {
     SkASSERT(buffer.getArrayCount() == sizeof(Light));
     buffer.readByteArray(&fLight, sizeof(Light));
     SkASSERT(fLight.fPad == 0); // for the font-cache lookup to be clean
     fBlurSigma = buffer.readScalar();
 }
+#endif
+
+SkFlattenable* SkEmbossMaskFilter::CreateProc(SkReadBuffer& buffer) {
+    Light light;
+    if (buffer.readByteArray(&light, sizeof(Light))) {
+        light.fPad = 0; // for the font-cache lookup to be clean
+        const SkScalar sigma = buffer.readScalar();
+        return Create(sigma, light);
+    }
+    return NULL;
+}
 
 void SkEmbossMaskFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     Light tmpLight = fLight;
     tmpLight.fPad = 0;    // for the font-cache lookup to be clean
     buffer.writeByteArray(&tmpLight, sizeof(tmpLight));
diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp
index aed2c9b..19525ec 100644
--- a/src/effects/SkLayerDrawLooper.cpp
+++ b/src/effects/SkLayerDrawLooper.cpp
@@ -200,20 +200,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
-#ifdef SK_DEBUG
-    {
-        Rec* rec = fRecs;
-        int count = 0;
-        while (rec) {
-            rec = rec->fNext;
-            count += 1;
-        }
-        SkASSERT(count == fCount);
-    }
-#endif
-
     buffer.writeInt(fCount);
 
     Rec* rec = fRecs;
@@ -245,22 +231,7 @@
         info.fPostTranslate = buffer.readBool();
         buffer.readPaint(builder.addLayerOnTop(info));
     }
-    SkLayerDrawLooper* looper = builder.detachLooper();
-    SkASSERT(count == looper->fCount);
-
-#ifdef SK_DEBUG
-    {
-        Rec* rec = looper->fRecs;
-        int n = 0;
-        while (rec) {
-            rec = rec->fNext;
-            n += 1;
-        }
-        SkASSERT(count == n);
-    }
-#endif
-
-    return looper;
+    return builder.detachLooper();
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/src/effects/SkLayerRasterizer.cpp b/src/effects/SkLayerRasterizer.cpp
index 9b7bdca..b331a03 100644
--- a/src/effects/SkLayerRasterizer.cpp
+++ b/src/effects/SkLayerRasterizer.cpp
@@ -148,12 +148,18 @@
     return true;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLayerRasterizer::SkLayerRasterizer(SkReadBuffer& buffer)
     : SkRasterizer(buffer), fLayers(ReadLayers(buffer)) {}
+#endif
+
+SkFlattenable* SkLayerRasterizer::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkLayerRasterizer, (ReadLayers(buffer)));
+}
 
 SkDeque* SkLayerRasterizer::ReadLayers(SkReadBuffer& buffer) {
     int count = buffer.readInt();
-
+    
     SkDeque* layers = SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec)));
     for (int i = 0; i < count; i++) {
         SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)layers->push_back();
diff --git a/src/effects/SkLerpXfermode.cpp b/src/effects/SkLerpXfermode.cpp
index c8389fe..0376a57 100644
--- a/src/effects/SkLerpXfermode.cpp
+++ b/src/effects/SkLerpXfermode.cpp
@@ -23,16 +23,20 @@
 
 SkLerpXfermode::SkLerpXfermode(unsigned scale256) : fScale256(scale256) {}
 
-SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fScale256 = buffer.readUInt();
 }
+#endif
 
 void SkLerpXfermode::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeUInt(fScale256);
 }
 
+SkFlattenable* SkLerpXfermode::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW_ARGS(SkLerpXfermode, (buffer.readUInt()));
+}
+
 void SkLerpXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                              const SkAlpha aa[]) const {
     const int scale = fScale256;
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index ebb9390..d93f4cc 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -264,13 +264,18 @@
 
 class SkDiffuseLightingImageFilter : public SkLightingImageFilter {
 public:
-    SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale,
-                                 SkScalar kd, SkImageFilter* input, const CropRect* cropRect);
+    static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter*,
+                                 const CropRect*);
+
     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);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkDiffuseLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
@@ -280,20 +285,27 @@
 #endif
 
 private:
+    friend class SkLightingImageFilter;
     typedef SkLightingImageFilter INHERITED;
     SkScalar fKD;
 };
 
 class SkSpecularLightingImageFilter : public SkLightingImageFilter {
 public:
-    SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect);
+    static SkImageFilter* Create(SkLight* light, SkScalar surfaceScale,
+                                 SkScalar ks, SkScalar shininess, SkImageFilter*, const CropRect*);
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
 
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
 
 protected:
+    SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks,
+                                  SkScalar shininess, SkImageFilter* input, const CropRect*);
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit SkSpecularLightingImageFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
@@ -303,9 +315,10 @@
 #endif
 
 private:
-    typedef SkLightingImageFilter INHERITED;
     SkScalar fKS;
     SkScalar fShininess;
+    friend class SkLightingImageFilter;
+    typedef SkLightingImageFilter INHERITED;
 };
 
 #if SK_SUPPORT_GPU
@@ -832,101 +845,139 @@
 
 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceScale,
                                              SkImageFilter* input, const CropRect* cropRect)
-  : INHERITED(1, &input, cropRect),
-    fLight(light),
-    fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255)))
-{
-    SkASSERT(fLight);
-    // our caller knows that we take ownership of the light, so we don't
-    // need to call ref() here.
+  : INHERITED(1, &input, cropRect)
+  , fLight(SkRef(light))
+  , fSurfaceScale(surfaceScale / 255)
+{}
+
+SkImageFilter* SkLightingImageFilter::CreateDistantLitDiffuse(const SkPoint3& direction,
+                                                              SkColor lightColor,
+                                                              SkScalar surfaceScale,
+                                                              SkScalar kd,
+                                                              SkImageFilter* input,
+                                                              const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkDistantLight, (direction, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateDistantLitDiffuse(
-    const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkDistantLight, (direction, lightColor)), surfaceScale, kd,
-        input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreatePointLitDiffuse(const SkPoint3& location,
+                                                            SkColor lightColor,
+                                                            SkScalar surfaceScale,
+                                                            SkScalar kd,
+                                                            SkImageFilter* input,
+                                                            const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkPointLight, (location, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreatePointLitDiffuse(
-    const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkPointLight, (location, lightColor)), surfaceScale, kd,
-        input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateSpotLitDiffuse(const SkPoint3& location,
+                                                           const SkPoint3& target,
+                                                           SkScalar specularExponent,
+                                                           SkScalar cutoffAngle,
+                                                           SkColor lightColor,
+                                                           SkScalar surfaceScale,
+                                                           SkScalar kd,
+                                                           SkImageFilter* input,
+                                                           const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
+                                                         cutoffAngle, lightColor)));
+    return SkDiffuseLightingImageFilter::Create(light, surfaceScale, kd, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateSpotLitDiffuse(
-    const SkPoint3& location, const SkPoint3& target,
-    SkScalar specularExponent, SkScalar cutoffAngle,
-    SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
-    SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkDiffuseLightingImageFilter,
-        (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
-                                  cutoffAngle, lightColor)),
-                    surfaceScale, kd, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateDistantLitSpecular(const SkPoint3& direction,
+                                                               SkColor lightColor,
+                                                               SkScalar surfaceScale,
+                                                               SkScalar ks,
+                                                               SkScalar shine,
+                                                               SkImageFilter* input,
+                                                               const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkDistantLight, (direction, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateDistantLitSpecular(
-    const SkPoint3& direction, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkDistantLight, (direction, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreatePointLitSpecular(const SkPoint3& location,
+                                                             SkColor lightColor,
+                                                             SkScalar surfaceScale,
+                                                             SkScalar ks,
+                                                             SkScalar shine,
+                                                             SkImageFilter* input,
+                                                             const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkPointLight, (location, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreatePointLitSpecular(
-    const SkPoint3& location, SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkPointLight, (location, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
+SkImageFilter* SkLightingImageFilter::CreateSpotLitSpecular(const SkPoint3& location,
+                                                            const SkPoint3& target,
+                                                            SkScalar specularExponent,
+                                                            SkScalar cutoffAngle,
+                                                            SkColor lightColor,
+                                                            SkScalar surfaceScale,
+                                                            SkScalar ks,
+                                                            SkScalar shine,
+                                                            SkImageFilter* input,
+                                                            const CropRect* cropRect) {
+    SkAutoTUnref<SkLight> light(SkNEW_ARGS(SkSpotLight, (location, target, specularExponent,
+                                                         cutoffAngle, lightColor)));
+    return SkSpecularLightingImageFilter::Create(light, surfaceScale, ks, shine, input, cropRect);
 }
 
-SkImageFilter* SkLightingImageFilter::CreateSpotLitSpecular(
-    const SkPoint3& location, const SkPoint3& target,
-    SkScalar specularExponent, SkScalar cutoffAngle,
-    SkColor lightColor, SkScalar surfaceScale,
-    SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
-    return SkNEW_ARGS(SkSpecularLightingImageFilter,
-        (SkNEW_ARGS(SkSpotLight, (location, target, specularExponent, cutoffAngle, lightColor)),
-        surfaceScale, ks, shininess, input, cropRect));
-}
+SkLightingImageFilter::~SkLightingImageFilter() {}
 
-SkLightingImageFilter::~SkLightingImageFilter() {
-    SkSafeUnref(fLight);
-}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLightingImageFilter::SkLightingImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
-    fLight = SkLight::UnflattenLight(buffer);
+    fLight.reset(SkLight::UnflattenLight(buffer));
     fSurfaceScale = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fSurfaceScale));
 }
+#endif
 
 void SkLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     fLight->flattenLight(buffer);
-    buffer.writeScalar(fSurfaceScale);
+    buffer.writeScalar(fSurfaceScale * 255);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect = NULL)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkImageFilter* SkDiffuseLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
+                                    SkScalar kd, SkImageFilter* input, const CropRect* cropRect) {
+    if (NULL == light) {
+        return NULL;
+    }
+    if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(kd)) {
+        return NULL;
+    }
     // According to the spec, kd can be any non-negative number :
     // http://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement
-    fKD(kd < 0 ? 0 : kd)
+    if (kd < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkDiffuseLightingImageFilter, (light, surfaceScale, kd, input, cropRect));
+}
+
+SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar kd, SkImageFilter* input, const CropRect* cropRect = NULL)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+    fKD(kd)
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(SkReadBuffer& buffer)
   : INHERITED(buffer)
 {
     fKD = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fKD) && (fKD >= 0));
 }
+#endif
+
+SkFlattenable* SkDiffuseLightingImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkAutoTUnref<SkLight> light(SkLight::UnflattenLight(buffer));
+    SkScalar surfaceScale = buffer.readScalar();
+    SkScalar kd = buffer.readScalar();
+    return Create(light, surfaceScale, kd, common.getInput(0), &common.cropRect());
+}
 
 void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
@@ -1000,23 +1051,49 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect)
-  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+SkImageFilter* SkSpecularLightingImageFilter::Create(SkLight* light, SkScalar surfaceScale,
+                SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect) {
+    if (NULL == light) {
+        return NULL;
+    }
+    if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(ks) || !SkScalarIsFinite(shininess)) {
+        return NULL;
+    }
     // According to the spec, ks can be any non-negative number :
     // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingElement
-    fKS(ks < 0 ? 0 : ks),
+    if (ks < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkSpecularLightingImageFilter,
+                      (light, surfaceScale, ks, shininess, input, cropRect));
+}
+
+SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input, const CropRect* cropRect)
+  : SkLightingImageFilter(light, surfaceScale, input, cropRect),
+    fKS(ks),
     fShininess(shininess)
 {
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkSpecularLightingImageFilter::SkSpecularLightingImageFilter(SkReadBuffer& buffer)
-  : INHERITED(buffer)
+    : INHERITED(buffer)
 {
     fKS = buffer.readScalar();
     fShininess = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fKS) && (fKS >= 0) &&
                     SkScalarIsFinite(fShininess));
 }
+#endif
+
+SkFlattenable* SkSpecularLightingImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkAutoTUnref<SkLight> light(SkLight::UnflattenLight(buffer));
+    SkScalar surfaceScale = buffer.readScalar();
+    SkScalar ks = buffer.readScalar();
+    SkScalar shine = buffer.readScalar();
+    return Create(light, surfaceScale, ks, shine, common.getInput(0), &common.cropRect());
+}
 
 void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index d33e5e8..26621bb 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -41,16 +41,17 @@
     return SkNEW(SkLumaColorFilter);
 }
 
-SkLumaColorFilter::SkLumaColorFilter()
-    : INHERITED() {
+SkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
+#endif
+
+SkFlattenable* SkLumaColorFilter::CreateProc(SkReadBuffer&) {
+    return SkNEW(SkLumaColorFilter);
 }
 
-SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
-}
-
-void SkLumaColorFilter::flatten(SkWriteBuffer&) const {
-}
+void SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
 
 #ifndef SK_IGNORE_TO_STRING
 void SkLumaColorFilter::toString(SkString* str) const {
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 203cab7..cb0fc24 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -232,6 +232,22 @@
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
+
+SkImageFilter* SkMagnifierImageFilter::Create(const SkRect& srcRect, SkScalar inset,
+                                              SkImageFilter* input) {
+    
+    if (!SkScalarIsFinite(inset) || !SkIsValidRect(srcRect)) {
+        return NULL;
+    }
+    // Negative numbers in src rect are not supported
+    if (srcRect.fLeft < 0 || srcRect.fTop < 0) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset, input));
+}
+
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMagnifierImageFilter::SkMagnifierImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     float x = buffer.readScalar();
@@ -245,6 +261,7 @@
                     // Negative numbers in src rect are not supported
                     (fSrcRect.fLeft >= 0) && (fSrcRect.fTop >= 0));
 }
+#endif
 
 SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset,
                                                SkImageFilter* input)
@@ -271,12 +288,16 @@
 }
 #endif
 
+SkFlattenable* SkMagnifierImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkRect src;
+    buffer.readRect(&src);
+    return Create(src, buffer.readScalar(), common.getInput(0));
+}
+
 void SkMagnifierImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    buffer.writeScalar(fSrcRect.x());
-    buffer.writeScalar(fSrcRect.y());
-    buffer.writeScalar(fSrcRect.width());
-    buffer.writeScalar(fSrcRect.height());
+    buffer.writeRect(fSrcRect);
     buffer.writeScalar(fInset);
 }
 
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 6e1d1a4..e01b640 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -17,18 +17,6 @@
 #include "effects/GrMatrixConvolutionEffect.h"
 #endif
 
-static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) {
-    switch (tileMode) {
-    case SkMatrixConvolutionImageFilter::kClamp_TileMode:
-    case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
-    case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
-        return true;
-    default:
-        break;
-    }
-    return false;
-}
-
 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(
     const SkISize& kernelSize,
     const SkScalar* kernel,
@@ -54,6 +42,19 @@
     SkASSERT(kernelOffset.fY >= 0 && kernelOffset.fY < kernelSize.fHeight);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) {
+    switch (tileMode) {
+        case SkMatrixConvolutionImageFilter::kClamp_TileMode:
+        case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
+        case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
+            return true;
+        default:
+            break;
+    }
+    return false;
+}
+
 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buffer)
     : INHERITED(1, buffer) {
     // We need to be able to read at most SK_MaxS32 bytes, so divide that
@@ -86,6 +87,33 @@
                     (fKernelOffset.fX >= 0) && (fKernelOffset.fX < fKernelSize.fWidth) &&
                     (fKernelOffset.fY >= 0) && (fKernelOffset.fY < fKernelSize.fHeight));
 }
+#endif
+
+SkFlattenable* SkMatrixConvolutionImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkISize kernelSize;
+    kernelSize.fWidth = buffer.readInt();
+    kernelSize.fHeight = buffer.readInt();
+    const int count = buffer.getArrayCount();
+
+    const int64_t kernelArea = sk_64_mul(kernelSize.width(), kernelSize.height());
+    if (!buffer.validate(kernelArea == count)) {
+        return NULL;
+    }
+    SkAutoSTArray<16, SkScalar> kernel(count);
+    if (!buffer.readScalarArray(kernel.get(), count)) {
+        return NULL;
+    }
+    SkScalar gain = buffer.readScalar();
+    SkScalar bias = buffer.readScalar();
+    SkIPoint kernelOffset;
+    kernelOffset.fX = buffer.readInt();
+    kernelOffset.fY = buffer.readInt();
+    TileMode tileMode = (TileMode)buffer.readInt();
+    bool convolveAlpha = buffer.readBool();
+    return Create(kernelSize, kernel.get(), gain, bias, kernelOffset, tileMode, convolveAlpha,
+                  common.getInput(0), &common.cropRect());
+}
 
 void SkMatrixConvolutionImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkMatrixImageFilter.cpp b/src/effects/SkMatrixImageFilter.cpp
index c7c815a..2b7786a 100644
--- a/src/effects/SkMatrixImageFilter.cpp
+++ b/src/effects/SkMatrixImageFilter.cpp
@@ -29,11 +29,21 @@
     return SkNEW_ARGS(SkMatrixImageFilter, (transform, filterLevel, input));
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMatrixImageFilter::SkMatrixImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readMatrix(&fTransform);
     fFilterLevel = static_cast<SkPaint::FilterLevel>(buffer.readInt());
 }
+#endif
+
+SkFlattenable* SkMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    SkPaint::FilterLevel level = static_cast<SkPaint::FilterLevel>(buffer.readInt());
+    return Create(matrix, level, common.getInput(0));
+}
 
 void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index 4022da3..a76702f 100755
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -105,15 +105,41 @@
     return true;
 }
 
+SkFlattenable* SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) {
+    Common common;
+    if (!common.unflatten(buffer, -1)) {
+        return NULL;
+    }
+
+    const int count = common.inputCount();
+    bool hasModes = buffer.readBool();
+    if (hasModes) {
+        SkAutoSTArray<4, SkXfermode::Mode> modes(count);
+        SkAutoSTArray<4, uint8_t> modes8(count);
+        if (!buffer.readByteArray(modes8.get(), count)) {
+            return NULL;
+        }
+        for (int i = 0; i < count; ++i) {
+            modes[i] = (SkXfermode::Mode)modes8[i];
+            buffer.validate(SkIsValidMode(modes[i]));
+        }
+        if (!buffer.isValid()) {
+            return NULL;
+        }
+        return Create(common.inputs(), count, modes.get(), &common.cropRect());
+    }
+    return Create(common.inputs(), count, NULL, &common.cropRect());
+}
+
 void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeBool(fModes != NULL);
     if (fModes) {
         buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
     }
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMergeImageFilter::SkMergeImageFilter(SkReadBuffer& buffer)
   : INHERITED(-1, buffer) {
     bool hasModes = buffer.readBool();
@@ -132,3 +158,4 @@
         fModes = 0;
     }
 }
+#endif
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 67769f2..bb8478c 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -21,6 +21,7 @@
 #include "effects/Gr1DKernelEffect.h"
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkMorphologyImageFilter::SkMorphologyImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fRadius.fWidth = buffer.readInt();
@@ -28,6 +29,7 @@
     buffer.validate((fRadius.fWidth >= 0) &&
                     (fRadius.fHeight >= 0));
 }
+#endif
 
 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX,
                                                  int radiusY,
@@ -36,7 +38,6 @@
     : INHERITED(1, &input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) {
 }
 
-
 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writeInt(fRadius.fWidth);
@@ -258,6 +259,20 @@
     return true;
 }
 
+SkFlattenable* SkErodeImageFilter::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());
+}
+
+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());
+}
+
 #if SK_SUPPORT_GPU
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index 57f36db..fcf09cc 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -91,6 +91,13 @@
     return true;
 }
 
+SkFlattenable* SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkPoint offset;
+    buffer.readPoint(&offset);
+    return Create(offset.x(), offset.y(), common.getInput(0), &common.cropRect());
+}
+
 void SkOffsetImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writePoint(fOffset);
@@ -102,9 +109,11 @@
     fOffset.set(dx, dy);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkOffsetImageFilter::SkOffsetImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readPoint(&fOffset);
     buffer.validate(SkScalarIsFinite(fOffset.fX) &&
                     SkScalarIsFinite(fOffset.fY));
 }
+#endif
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index b9b09dd..427b451 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -287,9 +287,8 @@
     SkASSERT(numOctaves >= 0 && numOctaves < 256);
 }
 
-SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer)
-    : INHERITED(buffer)
-{
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : INHERITED(buffer) {
     fType           = (SkPerlinNoiseShader::Type) buffer.readInt();
     fBaseFrequencyX = buffer.readScalar();
     fBaseFrequencyY = buffer.readScalar();
@@ -302,18 +301,37 @@
                     (fNumOctaves >= 0) && (fNumOctaves <= 255) &&
                     (fStitchTiles != fTileSize.isEmpty()));
 }
+#endif
 
 SkPerlinNoiseShader::~SkPerlinNoiseShader() {
 }
 
+SkFlattenable* SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) {
+    Type type = (Type)buffer.readInt();
+    SkScalar freqX = buffer.readScalar();
+    SkScalar freqY = buffer.readScalar();
+    int octaves = buffer.readInt();
+    SkScalar seed = buffer.readScalar();
+    SkISize tileSize;
+    tileSize.fWidth = buffer.readInt();
+    tileSize.fHeight = buffer.readInt();
+
+    switch (type) {
+        case kFractalNoise_Type:
+            return SkPerlinNoiseShader::CreateFractalNoise(freqX, freqY, octaves, seed, &tileSize);
+        case kTurbulence_Type:
+            return SkPerlinNoiseShader::CreateTubulence(freqX, freqY, octaves, seed, &tileSize);
+        default:
+            return NULL;
+    }
+}
+
 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     buffer.writeInt((int) fType);
     buffer.writeScalar(fBaseFrequencyX);
     buffer.writeScalar(fBaseFrequencyY);
     buffer.writeInt(fNumOctaves);
     buffer.writeScalar(fSeed);
-    buffer.writeBool(fStitchTiles);
     buffer.writeInt(fTileSize.fWidth);
     buffer.writeInt(fTileSize.fHeight);
 }
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
index 508f53e..a1958f3 100644
--- a/src/effects/SkPictureImageFilter.cpp
+++ b/src/effects/SkPictureImageFilter.cpp
@@ -31,6 +31,7 @@
     SkSafeUnref(fPicture);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer)
   : INHERITED(0, buffer),
     fPicture(NULL) {
@@ -43,9 +44,25 @@
     }
     buffer.readRect(&fCropRect);
 }
+#endif
+
+SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SkAutoTUnref<SkPicture> picture;
+    SkRect cropRect;
+
+    if (!buffer.isCrossProcess()) {
+        if (buffer.readBool()) {
+            picture.reset(SkPicture::CreateFromBuffer(buffer));
+        }
+    } else {
+        buffer.validate(!buffer.readBool());
+    }
+    buffer.readRect(&cropRect);
+
+    return Create(picture, cropRect);
+}
 
 void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
     if (!buffer.isCrossProcess()) {
         bool hasPicture = (fPicture != NULL);
         buffer.writeBool(hasPicture);
diff --git a/src/effects/SkPixelXorXfermode.cpp b/src/effects/SkPixelXorXfermode.cpp
index 129f182..68b5306 100644
--- a/src/effects/SkPixelXorXfermode.cpp
+++ b/src/effects/SkPixelXorXfermode.cpp
@@ -22,14 +22,18 @@
 }
 
 void SkPixelXorXfermode::flatten(SkWriteBuffer& wb) const {
-    this->INHERITED::flatten(wb);
     wb.writeColor(fOpColor);
 }
 
-SkPixelXorXfermode::SkPixelXorXfermode(SkReadBuffer& rb)
-        : INHERITED(rb) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkPixelXorXfermode::SkPixelXorXfermode(SkReadBuffer& rb) : INHERITED(rb) {
     fOpColor = rb.readColor();
 }
+#endif
+
+SkFlattenable* SkPixelXorXfermode::CreateProc(SkReadBuffer& buffer) {
+    return Create(buffer.readColor());
+}
 
 #ifndef SK_IGNORE_TO_STRING
 void SkPixelXorXfermode::toString(SkString* str) const {
diff --git a/src/effects/SkRectShaderImageFilter.cpp b/src/effects/SkRectShaderImageFilter.cpp
index 6961fac..fe0be12 100644
--- a/src/effects/SkRectShaderImageFilter.cpp
+++ b/src/effects/SkRectShaderImageFilter.cpp
@@ -35,14 +35,20 @@
     s->ref();
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkRectShaderImageFilter::SkRectShaderImageFilter(SkReadBuffer& buffer)
   : INHERITED(0, buffer) {
     fShader = buffer.readShader();
 }
+#endif
+
+SkFlattenable* SkRectShaderImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    return Create(buffer.readShader(), &common.cropRect());
+}
 
 void SkRectShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeFlattenable(fShader);
 }
 
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 2544b03..54e1efe 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -61,7 +61,9 @@
     };
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkTable_ColorFilter(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
 private:
@@ -70,6 +72,8 @@
     uint8_t fStorage[256 * 4];
     unsigned fFlags;
 
+    friend class SkTableColorFilter;
+
     typedef SkColorFilter INHERITED;
 };
 
@@ -168,19 +172,62 @@
 #include "SkPackBits.h"
 
 void SkTable_ColorFilter::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-
     uint8_t storage[5*256];
     int count = gCountNibBits[fFlags & 0xF];
     size_t size = SkPackBits::Pack8(fStorage, count * 256, storage);
     SkASSERT(size <= sizeof(storage));
 
-//    SkDebugf("raw %d packed %d\n", count * 256, size);
-
-    buffer.writeInt(fFlags);
+    buffer.write32(fFlags);
     buffer.writeByteArray(storage, size);
 }
 
+SkFlattenable* SkTable_ColorFilter::CreateProc(SkReadBuffer& buffer) {
+    const int flags = buffer.read32();
+    const size_t count = gCountNibBits[flags & 0xF];
+    SkASSERT(count <= 4);
+
+    uint8_t packedStorage[5*256];
+    size_t packedSize = buffer.getArrayCount();
+    if (!buffer.validate(packedSize <= sizeof(packedStorage))) {
+        return NULL;
+    }
+    if (!buffer.readByteArray(packedStorage, packedSize)) {
+        return NULL;
+    }
+
+    uint8_t unpackedStorage[4*256];
+    size_t unpackedSize = SkPackBits::Unpack8(packedStorage, packedSize, unpackedStorage);
+    // now check that we got the size we expected
+    if (!buffer.validate(unpackedSize != count*256)) {
+        return NULL;
+    }
+
+    const uint8_t* a = NULL;
+    const uint8_t* r = NULL;
+    const uint8_t* g = NULL;
+    const uint8_t* b = NULL;
+    const uint8_t* ptr = unpackedStorage;
+
+    if (flags & kA_Flag) {
+        a = ptr;
+        ptr += 256;
+    }
+    if (flags & kR_Flag) {
+        r = ptr;
+        ptr += 256;
+    }
+    if (flags & kG_Flag) {
+        g = ptr;
+        ptr += 256;
+    }
+    if (flags & kB_Flag) {
+        b = ptr;
+        ptr += 256;
+    }
+    return SkTableColorFilter::CreateARGB(a, r, g, b);
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTable_ColorFilter::SkTable_ColorFilter(SkReadBuffer& buffer) : INHERITED(buffer) {
     fBitmap = NULL;
 
@@ -199,6 +246,7 @@
     SkDEBUGCODE(size_t count = gCountNibBits[fFlags & 0xF]);
     SkASSERT(raw == count * 256);
 }
+#endif
 
 bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
     if (table) {
diff --git a/src/effects/SkTableMaskFilter.cpp b/src/effects/SkTableMaskFilter.cpp
index 602302e..42b4ab6 100644
--- a/src/effects/SkTableMaskFilter.cpp
+++ b/src/effects/SkTableMaskFilter.cpp
@@ -71,15 +71,23 @@
 }
 
 void SkTableMaskFilter::flatten(SkWriteBuffer& wb) const {
-    this->INHERITED::flatten(wb);
     wb.writeByteArray(fTable, 256);
 }
 
-SkTableMaskFilter::SkTableMaskFilter(SkReadBuffer& rb)
-        : INHERITED(rb) {
+SkFlattenable* SkTableMaskFilter::CreateProc(SkReadBuffer& buffer) {
+    uint8_t table[256];
+    if (!buffer.readByteArray(table, 256)) {
+        return NULL;
+    }
+    return Create(table);
+}
+
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkTableMaskFilter::SkTableMaskFilter(SkReadBuffer& rb) : INHERITED(rb) {
     SkASSERT(256 == rb.getArrayCount());
     rb.readByteArray(fTable, 256);
 }
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/effects/SkTestImageFilters.cpp b/src/effects/SkTestImageFilters.cpp
index da88316..a414c92 100755
--- a/src/effects/SkTestImageFilters.cpp
+++ b/src/effects/SkTestImageFilters.cpp
@@ -71,14 +71,20 @@
     return true;
 }
 
+SkFlattenable* SkDownSampleImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    return Create(buffer.readScalar(), common.getInput(0));
+}
+
 void SkDownSampleImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
     buffer.writeScalar(fScale);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkDownSampleImageFilter::SkDownSampleImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     fScale = buffer.readScalar();
     buffer.validate(SkScalarIsFinite(fScale));
 }
+#endif
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index 73c0a58..64492e2 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -16,6 +16,14 @@
 #include "SkShader.h"
 #include "SkValidationUtils.h"
 
+SkTileImageFilter* SkTileImageFilter::Create(const SkRect& srcRect, const SkRect& dstRect,
+                                             SkImageFilter* input) {
+    if (!SkIsValidRect(srcRect) || !SkIsValidRect(dstRect)) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input));
+}
+
 bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
                                       const Context& ctx,
                                       SkBitmap* dst, SkIPoint* offset) const {
@@ -86,12 +94,22 @@
     return true;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTileImageFilter::SkTileImageFilter(SkReadBuffer& buffer)
   : INHERITED(1, buffer) {
     buffer.readRect(&fSrcRect);
     buffer.readRect(&fDstRect);
     buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect));
 }
+#endif
+
+SkFlattenable* SkTileImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    SkRect src, dst;
+    buffer.readRect(&src);
+    buffer.readRect(&dst);
+    return Create(src, dst, common.getInput(0));
+}
 
 void SkTileImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/SkTransparentShader.cpp b/src/effects/SkTransparentShader.cpp
index f290d0d..aab5a3d 100644
--- a/src/effects/SkTransparentShader.cpp
+++ b/src/effects/SkTransparentShader.cpp
@@ -115,6 +115,10 @@
     }
 }
 
+SkFlattenable* SkTransparentShader::CreateProc(SkReadBuffer& buffer) {
+    return SkNEW(SkTransparentShader);
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkTransparentShader::toString(SkString* str) const {
     str->append("SkTransparentShader: (");
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index c876d5f..15ff92a 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -31,10 +31,18 @@
     SkSafeUnref(fMode);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkXfermodeImageFilter::SkXfermodeImageFilter(SkReadBuffer& buffer)
   : INHERITED(2, buffer) {
     fMode = buffer.readXfermode();
 }
+#endif
+
+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());
+}
 
 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 21bf885..7cc9063 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -12,6 +12,61 @@
 #include "SkTwoPointConicalGradient.h"
 #include "SkSweepGradient.h"
 
+void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const {
+    buffer.writeColorArray(fColors, fCount);
+    if (fPos) {
+        buffer.writeBool(true);
+        buffer.writeScalarArray(fPos, fCount);
+    } else {
+        buffer.writeBool(false);
+    }
+    buffer.write32(fTileMode);
+    buffer.write32(fGradFlags);
+    if (fLocalMatrix) {
+        buffer.writeBool(true);
+        buffer.writeMatrix(*fLocalMatrix);
+    } else {
+        buffer.writeBool(false);
+    }
+}
+
+bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
+    fCount = buffer.getArrayCount();
+    if (fCount > kStorageCount) {
+        size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar)) * fCount;
+        fDynamicStorage.reset(allocSize);
+        fColors = (SkColor*)fDynamicStorage.get();
+        fPos = (SkScalar*)(fColors + fCount);
+    } else {
+        fColors = fColorStorage;
+        fPos = fPosStorage;
+    }
+
+    if (!buffer.readColorArray(const_cast<SkColor*>(fColors), fCount)) {
+        return false;
+    }
+    if (buffer.readBool()) {
+        if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) {
+            return false;
+        }
+    } else {
+        fPos = NULL;
+    }
+
+    fTileMode = (SkShader::TileMode)buffer.read32();
+    fGradFlags = buffer.read32();
+
+    if (buffer.readBool()) {
+        fLocalMatrix = &fLocalMatrixStorage;
+        buffer.readMatrix(&fLocalMatrixStorage);
+    } else {
+        fLocalMatrix = NULL;
+    }
+    return buffer.isValid();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc)
     : INHERITED(desc.fLocalMatrix)
 {
@@ -47,6 +102,9 @@
 
     if (fColorCount > kColorStorageCount) {
         size_t size = sizeof(SkColor) + sizeof(Rec);
+        if (desc.fPos) {
+            size += sizeof(SkScalar);
+        }
         fOrigColors = reinterpret_cast<SkColor*>(
                                         sk_malloc_throw(size * fColorCount));
     }
@@ -67,13 +125,23 @@
         }
     }
 
-    fRecs = (Rec*)(fOrigColors + fColorCount);
+    if (desc.fPos && fColorCount) {
+        fOrigPos = (SkScalar*)(fOrigColors + fColorCount);
+        fRecs = (Rec*)(fOrigPos + fColorCount);
+    } else {
+        fOrigPos = NULL;
+        fRecs = (Rec*)(fOrigColors + fColorCount);
+    }
+
     if (fColorCount > 2) {
         Rec* recs = fRecs;
         recs->fPos = 0;
         //  recs->fScale = 0; // unused;
         recs += 1;
         if (desc.fPos) {
+            SkScalar* origPosPtr = fOrigPos;
+            *origPosPtr++ = 0;
+
             /*  We need to convert the user's array of relative positions into
                 fixed-point positions and scale factors. We need these results
                 to be strictly monotonic (no two values equal or out of order).
@@ -81,26 +149,22 @@
                 value if it sees a segment out of order, and it assures that
                 we start at 0 and end at 1.0
             */
-            SkFixed prev = 0;
+            SkScalar prev = 0;
             int startIndex = dummyFirst ? 0 : 1;
             int count = desc.fCount + dummyLast;
             for (int i = startIndex; i < count; i++) {
                 // force the last value to be 1.0
-                SkFixed curr;
+                SkScalar curr;
                 if (i == desc.fCount) {  // we're really at the dummyLast
-                    curr = SK_Fixed1;
+                    curr = 1;
                 } else {
-                    curr = SkScalarToFixed(desc.fPos[i]);
+                    curr = SkScalarPin(desc.fPos[i], 0, 1);
                 }
-                // pin curr withing range
-                if (curr < 0) {
-                    curr = 0;
-                } else if (curr > SK_Fixed1) {
-                    curr = SK_Fixed1;
-                }
-                recs->fPos = curr;
+                *origPosPtr++ = curr;
+                
+                recs->fPos = SkScalarToFixed(curr);
                 if (curr > prev) {
-                    recs->fScale = (1 << 24) / (curr - prev);
+                    recs->fScale = (1 << 24) / SkScalarToFixed(curr - prev);
                 } else {
                     recs->fScale = 0; // ignore this segment
                 }
@@ -109,6 +173,8 @@
                 recs += 1;
             }
         } else {    // assume even distribution
+            fOrigPos = NULL;
+
             SkFixed dp = SK_Fixed1 / (desc.fCount - 1);
             SkFixed p = dp;
             SkFixed scale = (desc.fCount - 1) << 8;  // (1 << 24) / dp
@@ -121,16 +187,18 @@
             recs->fPos = SK_Fixed1;
             recs->fScale = scale;
         }
+    } else if (desc.fPos) {
+        SkASSERT(2 == fColorCount);
+        fOrigPos[0] = SkScalarPin(desc.fPos[0], 0, 1);
+        fOrigPos[1] = SkScalarPin(desc.fPos[1], fOrigPos[0], 1);
+        if (0 == fOrigPos[0] && 1 == fOrigPos[1]) {
+            fOrigPos = NULL;
+        }
     }
     this->initCommon();
 }
 
-static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) {
-    SkASSERT(0 == (flags >> 28));
-    SkASSERT(0 == ((uint32_t)mode >> 4));
-    return (flags << 4) | mode;
-}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 static SkShader::TileMode unpack_mode(uint32_t packed) {
     return (SkShader::TileMode)(packed & 0xF);
 }
@@ -177,6 +245,7 @@
     buffer.readMatrix(&fPtsToUnit);
     this->initCommon();
 }
+#endif
 
 SkGradientShaderBase::~SkGradientShaderBase() {
     if (fOrigColors != fStorage) {
@@ -193,17 +262,16 @@
 }
 
 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
-    this->INHERITED::flatten(buffer);
-    buffer.writeColorArray(fOrigColors, fColorCount);
-    buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags));
-    if (fColorCount > 2) {
-        Rec* recs = fRecs;
-        for (int i = 1; i < fColorCount; i++) {
-            buffer.writeInt(recs[i].fPos);
-            buffer.writeUInt(recs[i].fScale);
-        }
-    }
-    buffer.writeMatrix(fPtsToUnit);
+    Descriptor desc;
+    desc.fColors = fOrigColors;
+    desc.fPos = fOrigPos;
+    desc.fCount = fColorCount;
+    desc.fTileMode = fTileMode;
+    desc.fGradFlags = fGradFlags;
+
+    const SkMatrix& m = this->getLocalMatrix();
+    desc.fLocalMatrix = m.isIdentity() ? NULL : &m;
+    desc.flatten(buffer);
 }
 
 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 1787e24..cf6c671 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -95,6 +95,29 @@
         int                 fCount;
         SkShader::TileMode  fTileMode;
         uint32_t            fGradFlags;
+
+        void flatten(SkWriteBuffer&) const;
+    };
+
+    class DescriptorScope : public Descriptor {
+    public:
+        DescriptorScope() {}
+        
+        bool unflatten(SkReadBuffer&);
+
+        // fColors and fPos always point into local memory, so they can be safely mutated
+        //
+        SkColor* mutableColors() { return const_cast<SkColor*>(fColors); }
+        SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
+
+    private:
+        enum {
+            kStorageCount = 16
+        };
+        SkColor fColorStorage[kStorageCount];
+        SkScalar fPosStorage[kStorageCount];
+        SkMatrix fLocalMatrixStorage;
+        SkAutoMalloc fDynamicStorage;
     };
 
 public:
@@ -234,10 +257,11 @@
     enum {
         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
 
-        kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(Rec))
+        kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
     };
     SkColor     fStorage[(kStorageSize + 3) >> 2];
     SkColor*    fOrigColors; // original colors, before modulation by paint in context.
+    SkScalar*   fOrigPos;   // original positions
     bool        fColorsAreOpaque;
 
     GradientShaderCache* refCache(U8CPU alpha) const;
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 4f85da3..9d939bf 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -60,11 +60,25 @@
     pts_to_unit_matrix(pts, &fPtsToUnit);
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkLinearGradient::SkLinearGradient(SkReadBuffer& buffer)
     : INHERITED(buffer)
     , fStart(buffer.readPoint())
     , fEnd(buffer.readPoint()) {
 }
+#endif
+
+SkFlattenable* SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    SkPoint pts[2];
+    pts[0] = buffer.readPoint();
+    pts[1] = buffer.readPoint();
+    return SkGradientShader::CreateLinear(pts, desc.fColors, desc.fPos, desc.fCount,
+                                          desc.fTileMode, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkLinearGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h
index 65d8bfd..6890106 100644
--- a/src/effects/gradients/SkLinearGradient.h
+++ b/src/effects/gradients/SkLinearGradient.h
@@ -42,6 +42,7 @@
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
     const SkPoint fStart;
     const SkPoint fEnd;
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index a6a2e36..fb1d40a 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -252,11 +252,24 @@
     return kRadial_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkRadialGradient::SkRadialGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter(buffer.readPoint()),
       fRadius(buffer.readScalar()) {
 }
+#endif
+
+SkFlattenable* SkRadialGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint center = buffer.readPoint();
+    const SkScalar radius = buffer.readScalar();
+    return SkGradientShader::CreateRadial(center, radius, desc.fColors, desc.fPos, desc.fCount,
+                                          desc.fTileMode, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkRadialGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h
index b7dbcbd..7709c38 100644
--- a/src/effects/gradients/SkRadialGradient.h
+++ b/src/effects/gradients/SkRadialGradient.h
@@ -43,6 +43,7 @@
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
     const SkPoint fCenter;
     const SkScalar fRadius;
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index a539216..1bb595c 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -41,10 +41,22 @@
     return kSweep_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkSweepGradient::SkSweepGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter(buffer.readPoint()) {
 }
+#endif
+
+SkFlattenable* SkSweepGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint center = buffer.readPoint();
+    return SkGradientShader::CreateSweep(center.x(), center.y(), desc.fColors, desc.fPos,
+                                         desc.fCount, desc.fGradFlags, desc.fLocalMatrix);
+}
 
 void SkSweepGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h
index 5c46061..640079a 100644
--- a/src/effects/gradients/SkSweepGradient.h
+++ b/src/effects/gradients/SkSweepGradient.h
@@ -41,13 +41,16 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkSweepGradient(SkReadBuffer& buffer);
+#endif
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
     virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     const SkPoint fCenter;
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 91856c8..9284e7c 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -343,6 +343,7 @@
     return kConical_GradientType;
 }
 
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
     SkReadBuffer& buffer)
     : INHERITED(buffer),
@@ -366,9 +367,47 @@
     }
     this->init();
 };
+#endif
 
-void SkTwoPointConicalGradient::flatten(
-    SkWriteBuffer& buffer) const {
+SkFlattenable* SkTwoPointConicalGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    SkPoint c1 = buffer.readPoint();
+    SkPoint c2 = buffer.readPoint();
+    SkScalar r1 = buffer.readScalar();
+    SkScalar r2 = buffer.readScalar();
+
+    if (buffer.readBool()) {    // flipped
+        SkTSwap(c1, c2);
+        SkTSwap(r1, r2);
+
+        SkColor* colors = desc.mutableColors();
+        SkScalar* pos = desc.mutablePos();
+        const int last = desc.fCount - 1;
+        const int half = desc.fCount >> 1;
+        for (int i = 0; i < half; ++i) {
+            SkTSwap(colors[i], colors[last - i]);
+            if (pos) {
+                SkScalar tmp = pos[i];
+                pos[i] = SK_Scalar1 - pos[last - i];
+                pos[last - i] = SK_Scalar1 - tmp;
+            }
+        }
+        if (pos) {
+            if (desc.fCount & 1) {
+                pos[half] = SK_Scalar1 - pos[half];
+            }
+        }
+    }
+
+    return SkGradientShader::CreateTwoPointConical(c1, r1, c2, r2, desc.fColors, desc.fPos,
+                                                   desc.fCount, desc.fTileMode, desc.fGradFlags,
+                                                   desc.fLocalMatrix);
+}
+
+void SkTwoPointConicalGradient::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
     buffer.writePoint(fCenter1);
     buffer.writePoint(fCenter2);
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h
index fc39046..608ea76 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient.h
@@ -91,6 +91,7 @@
     SkScalar fRadius2;
     bool fFlippedGrad;
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 8a40822..754a532 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -343,8 +343,8 @@
 }
 #endif
 
-SkTwoPointRadialGradient::SkTwoPointRadialGradient(
-    SkReadBuffer& buffer)
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkTwoPointRadialGradient::SkTwoPointRadialGradient(SkReadBuffer& buffer)
     : INHERITED(buffer),
       fCenter1(buffer.readPoint()),
       fCenter2(buffer.readPoint()),
@@ -352,6 +352,21 @@
       fRadius2(buffer.readScalar()) {
     init();
 };
+#endif
+
+SkFlattenable* SkTwoPointRadialGradient::CreateProc(SkReadBuffer& buffer) {
+    DescriptorScope desc;
+    if (!desc.unflatten(buffer)) {
+        return NULL;
+    }
+    const SkPoint c1 = buffer.readPoint();
+    const SkPoint c2 = buffer.readPoint();
+    const SkScalar r1 = buffer.readScalar();
+    const SkScalar r2 = buffer.readScalar();
+    return SkGradientShader::CreateTwoPointRadial(c1, r1, c2, r2, desc.fColors, desc.fPos,
+                                                  desc.fCount, desc.fTileMode, desc.fGradFlags,
+                                                  desc.fLocalMatrix);
+}
 
 void SkTwoPointRadialGradient::flatten(
     SkWriteBuffer& buffer) const {
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h
index 73fa547..bfeecc5 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.h
+++ b/src/effects/gradients/SkTwoPointRadialGradient.h
@@ -58,6 +58,7 @@
 
     void init();
 
+    friend class SkGradientShader;
     typedef SkGradientShaderBase INHERITED;
 };
 
diff --git a/src/opts/SkXfermode_opts_SSE2.cpp b/src/opts/SkXfermode_opts_SSE2.cpp
index 94f9a4a..02ca038 100644
--- a/src/opts/SkXfermode_opts_SSE2.cpp
+++ b/src/opts/SkXfermode_opts_SSE2.cpp
@@ -641,11 +641,12 @@
 
 extern SkXfermodeProcSIMD gSSE2XfermodeProcs[];
 
-SkSSE2ProcCoeffXfermode::SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer)
-    : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkSSE2ProcCoeffXfermode::SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fProcSIMD = reinterpret_cast<void*>(gSSE2XfermodeProcs[this->getMode()]);
     buffer.validate(fProcSIMD != NULL);
 }
+#endif
 
 void SkSSE2ProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[],
                                      int count, const SkAlpha aa[]) const {
diff --git a/src/opts/SkXfermode_opts_SSE2.h b/src/opts/SkXfermode_opts_SSE2.h
index bfc1439..8512aee 100644
--- a/src/opts/SkXfermode_opts_SSE2.h
+++ b/src/opts/SkXfermode_opts_SSE2.h
@@ -23,10 +23,11 @@
                         int count, const SkAlpha aa[]) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSSE2ProcCoeffXfermode)
 
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkSSE2ProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     void* fProcSIMD;
     typedef SkProcCoeffXfermode INHERITED;
diff --git a/src/opts/SkXfermode_opts_arm_neon.cpp b/src/opts/SkXfermode_opts_arm_neon.cpp
index 88c179d..dca58eb 100644
--- a/src/opts/SkXfermode_opts_arm_neon.cpp
+++ b/src/opts/SkXfermode_opts_arm_neon.cpp
@@ -743,10 +743,11 @@
 
 extern SkXfermodeProcSIMD gNEONXfermodeProcs[];
 
-SkNEONProcCoeffXfermode::SkNEONProcCoeffXfermode(SkReadBuffer& buffer)
-        : INHERITED(buffer) {
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+SkNEONProcCoeffXfermode::SkNEONProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
     fProcSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[this->getMode()]);
 }
+#endif
 
 void SkNEONProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
                                      const SkPMColor* SK_RESTRICT src, int count,
diff --git a/src/opts/SkXfermode_opts_arm_neon.h b/src/opts/SkXfermode_opts_arm_neon.h
index 8f3aaae..745bfe2 100644
--- a/src/opts/SkXfermode_opts_arm_neon.h
+++ b/src/opts/SkXfermode_opts_arm_neon.h
@@ -15,10 +15,11 @@
                         int count, const SkAlpha* SK_RESTRICT aa) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNEONProcCoeffXfermode)
 
 private:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     SkNEONProcCoeffXfermode(SkReadBuffer& buffer);
+#endif
 
     // void* is used to avoid pulling arm_neon.h in the core and having to build
     // it with -mfpu=neon.
diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp
index 4815038..1893ed0 100644
--- a/src/ports/SkGlobalInitialization_chromium.cpp
+++ b/src/ports/SkGlobalInitialization_chromium.cpp
@@ -59,61 +59,64 @@
 #include "SkMatrixImageFilter.h"
 #include "SkXfermodeImageFilter.h"
 
-static void InitializeFlattenables() {
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
+class SkPrivateEffectInitializer {
+public:
+    static void Init() {
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
 
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
 
-    SkArithmeticMode::InitializeFlattenables();
-    SkBlurMaskFilter::InitializeFlattenables();
-    SkColorFilter::InitializeFlattenables();
-    SkGradientShader::InitializeFlattenables();
-    SkLightingImageFilter::InitializeFlattenables();
-    SkTableColorFilter::InitializeFlattenables();
-    SkXfermode::InitializeFlattenables();
-}
+        SkArithmeticMode::InitializeFlattenables();
+        SkBlurMaskFilter::InitializeFlattenables();
+        SkColorFilter::InitializeFlattenables();
+        SkGradientShader::InitializeFlattenables();
+        SkLightingImageFilter::InitializeFlattenables();
+        SkTableColorFilter::InitializeFlattenables();
+        SkXfermode::InitializeFlattenables();
+    }
+};
 
 void SkFlattenable::InitializeFlattenablesIfNeeded() {
     SK_DECLARE_STATIC_ONCE(once);
-    SkOnce(&once, InitializeFlattenables);
+    SkOnce(&once, SkPrivateEffectInitializer::Init);
 }
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index af386e0..1893ed0 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -59,62 +59,64 @@
 #include "SkMatrixImageFilter.h"
 #include "SkXfermodeImageFilter.h"
 
-static void InitializeFlattenables() {
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
+class SkPrivateEffectInitializer {
+public:
+    static void Init() {
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorMatrixFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDilateImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiscretePathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDisplacementMapEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDropShadowImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmptyShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkErodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureShader)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixConvolutionImageFilter)
 
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
-    SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOffsetImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMergeImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkColorFilterImageFilter)
+        SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDownSampleImageFilter)
 
-    SkArithmeticMode::InitializeFlattenables();
-    SkBlurMaskFilter::InitializeFlattenables();
-    SkColorFilter::InitializeFlattenables();
-    SkGradientShader::InitializeFlattenables();
-    SkLightingImageFilter::InitializeFlattenables();
-    SkTableColorFilter::InitializeFlattenables();
-    SkXfermode::InitializeFlattenables();
-
-}
+        SkArithmeticMode::InitializeFlattenables();
+        SkBlurMaskFilter::InitializeFlattenables();
+        SkColorFilter::InitializeFlattenables();
+        SkGradientShader::InitializeFlattenables();
+        SkLightingImageFilter::InitializeFlattenables();
+        SkTableColorFilter::InitializeFlattenables();
+        SkXfermode::InitializeFlattenables();
+    }
+};
 
 void SkFlattenable::InitializeFlattenablesIfNeeded() {
     SK_DECLARE_STATIC_ONCE(once);
-    SkOnce(&once, InitializeFlattenables);
+    SkOnce(&once, SkPrivateEffectInitializer::Init);
 }
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 9da1ecc..5763211 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -274,7 +274,7 @@
 void forceLinking() {
     SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0);
     SkAlphaThresholdFilter::Create(SkRegion(), .5f, .5f);
-    SkAutoTUnref<SkMagnifierImageFilter> mag(SkMagnifierImageFilter::Create(
+    SkAutoTUnref<SkImageFilter> mag(SkMagnifierImageFilter::Create(
         SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1));
     GrConfigConversionEffect::Create(NULL,
                                      false,
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index ee3de50..214aed9 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -56,12 +56,15 @@
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(MatrixTestImageFilter)
 
 protected:
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     explicit MatrixTestImageFilter(SkReadBuffer& buffer) : SkImageFilter(0, NULL) {
         fReporter = static_cast<skiatest::Reporter*>(buffer.readFunctionPtr());
         buffer.readMatrix(&fExpectedMatrix);
     }
+#endif
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
+        this->INHERITED::flatten(buffer);
         buffer.writeFunctionPtr(fReporter);
         buffer.writeMatrix(fExpectedMatrix);
     }
@@ -69,10 +72,20 @@
 private:
     skiatest::Reporter* fReporter;
     SkMatrix fExpectedMatrix;
+    
+    typedef SkImageFilter INHERITED;
 };
 
 }
 
+SkFlattenable* MatrixTestImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    skiatest::Reporter* reporter = (skiatest::Reporter*)buffer.readFunctionPtr();
+    SkMatrix matrix;
+    buffer.readMatrix(&matrix);
+    return SkNEW_ARGS(MatrixTestImageFilter, (reporter, matrix));
+}
+
 static void make_small_bitmap(SkBitmap& bitmap) {
     bitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
     SkCanvas canvas(bitmap);
diff --git a/tests/LayerRasterizerTest.cpp b/tests/LayerRasterizerTest.cpp
index 640c581..4b236ac 100644
--- a/tests/LayerRasterizerTest.cpp
+++ b/tests/LayerRasterizerTest.cpp
@@ -33,11 +33,9 @@
 
     static int GetCount() { return gCount; }
 
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyRasterizer)
+    SK_DECLARE_NOT_FLATTENABLE_PROCS(DummyRasterizer)
 
 private:
-    DummyRasterizer(SkReadBuffer&) {}
-
     static int gCount;
 
     typedef SkRasterizer INHERITED;