Factory methods for heap-allocated SkImageFilter objects.

This is part of an effort to ensure that all SkPaint effects can only be
allocated on the heap.

This patch makes the constructors of SkImageFilter and its subclasses non-public
and instead provides factory methods for creating these objects on the heap. We
temporarily keep constructor of publicly visible classes public behind a flag.

BUG=skia:2187
R=scroggo@google.com, mtklein@chromium.org, reed@google.com, senorblanco@google.com, senorblanco@chromium.org, bsalomon@google.com, sugoi@chromium.org, zork@chromium.org

Author: dominikg@chromium.org

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

git-svn-id: http://skia.googlecode.com/svn/trunk@13718 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/effects/SkBicubicImageFilter.h b/include/effects/SkBicubicImageFilter.h
index 48105b1..9b65975 100644
--- a/include/effects/SkBicubicImageFilter.h
+++ b/include/effects/SkBicubicImageFilter.h
@@ -20,21 +20,21 @@
 
 class SK_API SkBicubicImageFilter : public SkImageFilter {
 public:
+    virtual ~SkBicubicImageFilter();
+
+    static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL);
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter)
+
+protected:
     /** Construct a (scaling-only) bicubic resampling image filter.
         @param scale        How much to scale the image.
         @param coefficients The 16 coefficients of the bicubic matrix.
         @param input        The input image filter.  If NULL, the src bitmap
                             passed to filterImage() is used instead.
     */
-
     SkBicubicImageFilter(const SkSize& scale, const SkScalar coefficients[16],
                          SkImageFilter* input = NULL);
-    static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL);
-    virtual ~SkBicubicImageFilter();
-
-    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter)
-
-protected:
     SkBicubicImageFilter(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
diff --git a/include/effects/SkBitmapSource.h b/include/effects/SkBitmapSource.h
index fcc1db9..9740e0e 100644
--- a/include/effects/SkBitmapSource.h
+++ b/include/effects/SkBitmapSource.h
@@ -13,8 +13,13 @@
 
 class SK_API SkBitmapSource : public SkImageFilter {
 public:
-    explicit SkBitmapSource(const SkBitmap& bitmap);
-    SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+    static SkBitmapSource* Create(const SkBitmap& bitmap) {
+        return SkNEW_ARGS(SkBitmapSource, (bitmap));
+    }
+    static SkBitmapSource* Create(const SkBitmap& bitmap, const SkRect& srcRect,
+                                  const SkRect& dstRect) {
+        return SkNEW_ARGS(SkBitmapSource, (bitmap, srcRect, dstRect));
+    }
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource)
@@ -26,6 +31,12 @@
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    explicit SkBitmapSource(const SkBitmap& bitmap);
+    SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+
 private:
     SkBitmap fBitmap;
     SkRect   fSrcRect, fDstRect;
diff --git a/include/effects/SkBlurImageFilter.h b/include/effects/SkBlurImageFilter.h
index 60dab72..44bf393 100644
--- a/include/effects/SkBlurImageFilter.h
+++ b/include/effects/SkBlurImageFilter.h
@@ -13,10 +13,13 @@
 
 class SK_API SkBlurImageFilter : public SkImageFilter {
 public:
-    SkBlurImageFilter(SkScalar sigmaX,
-                      SkScalar sigmaY,
-                      SkImageFilter* input = NULL,
-                      const CropRect* cropRect = NULL);
+    static SkBlurImageFilter* Create(SkScalar sigmaX,
+                                     SkScalar sigmaY,
+                                     SkImageFilter* input = NULL,
+                                     const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect));
+    }
+
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
@@ -34,6 +37,14 @@
     virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
                                 SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkBlurImageFilter(SkScalar sigmaX,
+                      SkScalar sigmaY,
+                      SkImageFilter* input = NULL,
+                      const CropRect* cropRect = NULL);
+
 private:
     SkSize   fSigma;
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkComposeImageFilter.h b/include/effects/SkComposeImageFilter.h
index 9e024ef..7a982d8 100644
--- a/include/effects/SkComposeImageFilter.h
+++ b/include/effects/SkComposeImageFilter.h
@@ -12,9 +12,12 @@
 
 class SK_API SkComposeImageFilter : public SkImageFilter {
 public:
-    SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {}
     virtual ~SkComposeImageFilter();
 
+    static SkComposeImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
+        return SkNEW_ARGS(SkComposeImageFilter, (outer, inner));
+    }
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
 
 protected:
@@ -24,6 +27,11 @@
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {}
+
 private:
     typedef SkImageFilter INHERITED;
 };
diff --git a/include/effects/SkDisplacementMapEffect.h b/include/effects/SkDisplacementMapEffect.h
index 5de4814..59549dc 100644
--- a/include/effects/SkDisplacementMapEffect.h
+++ b/include/effects/SkDisplacementMapEffect.h
@@ -18,18 +18,20 @@
         kR_ChannelSelectorType,
         kG_ChannelSelectorType,
         kB_ChannelSelectorType,
-        kA_ChannelSelectorType,
-        kKeyBits = 3 // Max value is 4, so 3 bits are required at most
+        kA_ChannelSelectorType
     };
 
-    SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
-                            ChannelSelectorType yChannelSelector,
-                            SkScalar scale, SkImageFilter* displacement,
-                            SkImageFilter* color = NULL,
-                            const CropRect* cropRect = NULL);
-
     ~SkDisplacementMapEffect();
 
+    static SkDisplacementMapEffect* Create(ChannelSelectorType xChannelSelector,
+                                           ChannelSelectorType yChannelSelector,
+                                           SkScalar scale, SkImageFilter* displacement,
+                                           SkImageFilter* color = NULL,
+                                           const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
+                                                    displacement, color, cropRect));
+    }
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
 
     virtual bool onFilterImage(Proxy* proxy,
@@ -52,6 +54,15 @@
     explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
+                            ChannelSelectorType yChannelSelector,
+                            SkScalar scale, SkImageFilter* displacement,
+                            SkImageFilter* color = NULL,
+                            const CropRect* cropRect = NULL);
+
 private:
     ChannelSelectorType fXChannelSelector;
     ChannelSelectorType fYChannelSelector;
diff --git a/include/effects/SkDropShadowImageFilter.h b/include/effects/SkDropShadowImageFilter.h
index aba2017..5804386 100644
--- a/include/effects/SkDropShadowImageFilter.h
+++ b/include/effects/SkDropShadowImageFilter.h
@@ -11,8 +11,17 @@
 
 class SK_API SkDropShadowImageFilter : public SkImageFilter {
 public:
-    SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor, SkImageFilter* input = NULL);
-    SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+    static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy, SkScalar sigma,
+                                           SkColor color, SkImageFilter* input = NULL) {
+        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigma, color, input));
+    }
+    static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
+                                           SkScalar sigmaX, SkScalar sigmaY, SkColor color,
+                                           SkImageFilter* input = NULL,
+                                           const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
+                                                    color, input, cropRect));
+    }
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
 
@@ -23,7 +32,13 @@
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
                                 SkIRect* dst) const SK_OVERRIDE;
 
-
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor,
+                            SkImageFilter* input = NULL);
+    SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
+                            SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
 
 private:
     SkScalar fDx, fDy, fSigmaX, fSigmaY;
diff --git a/include/effects/SkMagnifierImageFilter.h b/include/effects/SkMagnifierImageFilter.h
index 44f0d0d..cfe1f09 100644
--- a/include/effects/SkMagnifierImageFilter.h
+++ b/include/effects/SkMagnifierImageFilter.h
@@ -14,7 +14,9 @@
 
 class SK_API SkMagnifierImageFilter : public SkImageFilter {
 public:
-    SkMagnifierImageFilter(SkRect srcRect, SkScalar inset);
+    static SkMagnifierImageFilter* Create(const SkRect& srcRect, SkScalar inset) {
+        return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset));
+    }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter)
 
@@ -28,6 +30,11 @@
     virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset);
+
 private:
     SkRect fSrcRect;
     SkScalar fInset;
diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h
index 59af83e..524d05d 100644
--- a/include/effects/SkMatrixConvolutionImageFilter.h
+++ b/include/effects/SkMatrixConvolutionImageFilter.h
@@ -28,39 +28,43 @@
       kClampToBlack_TileMode,  /*!< Fill with transparent black. */
     };
 
-    /** Construct a matrix convolution image filter.
-        @param kernelSize  The kernel size in pixels, in each dimension (N by M).
-        @param kernel      The image processing kernel.  Must contain N * M
-                           elements, in row order.
-        @param gain        A scale factor applied to each pixel after
-                           convolution.  This can be used to normalize the
-                           kernel, if it does not sum to 1.
-        @param bias        A bias factor added to each pixel after convolution.
-        @param target      An offset applied to each pixel coordinate before
-                           convolution.  This can be used to center the kernel
-                           over the image (e.g., a 3x3 kernel should have a
-                           target of {1, 1}).
-        @param tileMode    How accesses outside the image are treated.  (@see
-                           TileMode).
-        @param convolveAlpha  If true, all channels are convolved.  If false,
-                           only the RGB channels are convolved, and
-                           alpha is copied from the source image.
-        @param input       The input image filter.  If NULL, the src bitmap
-                           passed to filterImage() is used instead.
-        @param cropRect    The rectangle to which the output processing will be limited.
-    */
-
-    SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
-                                   const SkScalar* kernel,
-                                   SkScalar gain,
-                                   SkScalar bias,
-                                   const SkIPoint& target,
-                                   TileMode tileMode,
-                                   bool convolveAlpha,
-                                   SkImageFilter* input = NULL,
-                                   const CropRect* cropRect = NULL);
     virtual ~SkMatrixConvolutionImageFilter();
 
+    /** Construct a matrix convolution image filter.
+        @param kernelSize     The kernel size in pixels, in each dimension (N by M).
+        @param kernel         The image processing kernel.  Must contain N * M
+                              elements, in row order.
+        @param gain           A scale factor applied to each pixel after
+                              convolution.  This can be used to normalize the
+                              kernel, if it does not sum to 1.
+        @param bias           A bias factor added to each pixel after convolution.
+        @param kernelOffset   An offset applied to each pixel coordinate before
+                              convolution.  This can be used to center the kernel
+                              over the image (e.g., a 3x3 kernel should have an
+                              offset of {1, 1}).
+        @param tileMode       How accesses outside the image are treated.  (@see
+                              TileMode).
+        @param convolveAlpha  If true, all channels are convolved.  If false,
+                              only the RGB channels are convolved, and
+                              alpha is copied from the source image.
+        @param input          The input image filter.  If NULL, the src bitmap
+                              passed to filterImage() is used instead.
+        @param cropRect       The rectangle to which the output processing will be limited.
+    */
+    static SkMatrixConvolutionImageFilter* Create(const SkISize& kernelSize,
+                                                  const SkScalar* kernel,
+                                                  SkScalar gain,
+                                                  SkScalar bias,
+                                                  const SkIPoint& kernelOffset,
+                                                  TileMode tileMode,
+                                                  bool convolveAlpha,
+                                                  SkImageFilter* input = NULL,
+                                                  const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias,
+                                                           kernelOffset, tileMode, convolveAlpha,
+                                                           input, cropRect));
+    }
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
 
 protected:
@@ -77,12 +81,25 @@
                              const SkIRect& bounds) const SK_OVERRIDE;
 #endif
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
+                                   const SkScalar* kernel,
+                                   SkScalar gain,
+                                   SkScalar bias,
+                                   const SkIPoint& kernelOffset,
+                                   TileMode tileMode,
+                                   bool convolveAlpha,
+                                   SkImageFilter* input = NULL,
+                                   const CropRect* cropRect = NULL);
+
 private:
     SkISize   fKernelSize;
     SkScalar* fKernel;
     SkScalar  fGain;
     SkScalar  fBias;
-    SkIPoint  fTarget;
+    SkIPoint  fKernelOffset;
     TileMode  fTileMode;
     bool      fConvolveAlpha;
     typedef SkImageFilter INHERITED;
diff --git a/include/effects/SkMergeImageFilter.h b/include/effects/SkMergeImageFilter.h
index 36eaaf3..54170a3 100755
--- a/include/effects/SkMergeImageFilter.h
+++ b/include/effects/SkMergeImageFilter.h
@@ -14,14 +14,19 @@
 
 class SK_API SkMergeImageFilter : public SkImageFilter {
 public:
-    SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
-                       SkXfermode::Mode = SkXfermode::kSrcOver_Mode,
-                       const CropRect* cropRect = NULL);
-    SkMergeImageFilter(SkImageFilter* filters[], int count,
-                       const SkXfermode::Mode modes[] = NULL,
-                       const CropRect* cropRect = NULL);
     virtual ~SkMergeImageFilter();
 
+    static SkMergeImageFilter* Create(SkImageFilter* first, SkImageFilter* second,
+                                      SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
+                                      const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkMergeImageFilter, (first, second, mode, cropRect));
+    }
+    static SkMergeImageFilter* Create(SkImageFilter* filters[], int count,
+                                      const SkXfermode::Mode modes[] = NULL,
+                                      const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect));
+    }
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
 
 protected:
@@ -30,6 +35,16 @@
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
+
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
+                       SkXfermode::Mode = SkXfermode::kSrcOver_Mode,
+                       const CropRect* cropRect = NULL);
+    SkMergeImageFilter(SkImageFilter* filters[], int count,
+                       const SkXfermode::Mode modes[] = NULL,
+                       const CropRect* cropRect = NULL);
 private:
     uint8_t*            fModes; // SkXfermode::Mode
 
diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h
index 4d60180..edf1040 100644
--- a/include/effects/SkMorphologyImageFilter.h
+++ b/include/effects/SkMorphologyImageFilter.h
@@ -15,7 +15,6 @@
 
 class SK_API SkMorphologyImageFilter : public SkImageFilter {
 public:
-    SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect);
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE;
 
@@ -30,6 +29,8 @@
                          int width, int height, int srcStride, int dstStride);
 
 protected:
+    SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input,
+                            const CropRect* cropRect);
     bool filterImageGeneric(Proc procX, Proc procY,
                             Proxy*, const SkBitmap& src, const SkMatrix&,
                             SkBitmap* result, SkIPoint* offset) const;
@@ -51,10 +52,11 @@
 
 class SK_API SkDilateImageFilter : public SkMorphologyImageFilter {
 public:
-    SkDilateImageFilter(int radiusX, int radiusY,
-                        SkImageFilter* input = NULL,
-                        const CropRect* cropRect = NULL)
-    : INHERITED(radiusX, radiusY, input, cropRect) {}
+    static SkDilateImageFilter* Create(int radiusX, int radiusY,
+                                       SkImageFilter* input = NULL,
+                                       const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect));
+    }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
@@ -68,16 +70,25 @@
 protected:
     SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkDilateImageFilter(int radiusX, int radiusY,
+                        SkImageFilter* input = NULL,
+                        const CropRect* cropRect = NULL)
+    : INHERITED(radiusX, radiusY, input, cropRect) {}
+
 private:
     typedef SkMorphologyImageFilter INHERITED;
 };
 
 class SK_API SkErodeImageFilter : public SkMorphologyImageFilter {
 public:
-    SkErodeImageFilter(int radiusX, int radiusY,
-                       SkImageFilter* input = NULL,
-                       const CropRect* cropRect = NULL)
-    : INHERITED(radiusX, radiusY, input, cropRect) {}
+    static SkErodeImageFilter* Create(int radiusX, int radiusY,
+                                      SkImageFilter* input = NULL,
+                                      const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect));
+    }
 
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
@@ -91,6 +102,14 @@
 protected:
     SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkErodeImageFilter(int radiusX, int radiusY,
+                       SkImageFilter* input = NULL,
+                       const CropRect* cropRect = NULL)
+    : INHERITED(radiusX, radiusY, input, cropRect) {}
+
 private:
     typedef SkMorphologyImageFilter INHERITED;
 };
diff --git a/include/effects/SkOffsetImageFilter.h b/include/effects/SkOffsetImageFilter.h
index 31eead3..93fc273 100644
--- a/include/effects/SkOffsetImageFilter.h
+++ b/include/effects/SkOffsetImageFilter.h
@@ -15,8 +15,10 @@
     typedef SkImageFilter INHERITED;
 
 public:
-    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
-                        const CropRect* cropRect = NULL);
+    static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
+                                       const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect));
+    }
     virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
 
@@ -28,6 +30,12 @@
                                SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
     virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
+                        const CropRect* cropRect = NULL);
+
 private:
     SkVector fOffset;
 };
diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h
index a10d23e..1eda5dc 100644
--- a/include/effects/SkPictureImageFilter.h
+++ b/include/effects/SkPictureImageFilter.h
@@ -16,13 +16,17 @@
     /**
      *  Refs the passed-in picture.
      */
-    explicit SkPictureImageFilter(SkPicture* picture);
+    static SkPictureImageFilter* Create(SkPicture* picture) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture));
+    }
 
     /**
-     *  Refs the passed-in picture. rect can be used to crop or expand the destination rect when
+     *  Refs the passed-in picture. cropRect can be used to crop or expand the destination rect when
      *  the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
      */
-    SkPictureImageFilter(SkPicture* picture, const SkRect& rect);
+    static SkPictureImageFilter* Create(SkPicture* picture, const SkRect& cropRect) {
+        return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect));
+    }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
 
@@ -39,9 +43,15 @@
     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    explicit SkPictureImageFilter(SkPicture* picture);
+    SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect);
+
 private:
     SkPicture* fPicture;
-    SkRect     fRect;
+    SkRect     fCropRect;
     typedef SkImageFilter INHERITED;
 };
 
diff --git a/include/effects/SkResizeImageFilter.h b/include/effects/SkResizeImageFilter.h
index 0a8fb14..9cb7bf3 100644
--- a/include/effects/SkResizeImageFilter.h
+++ b/include/effects/SkResizeImageFilter.h
@@ -21,6 +21,8 @@
 
 class SK_API SkResizeImageFilter : public SkImageFilter {
 public:
+    virtual ~SkResizeImageFilter();
+
     /** Construct a (scaling-only) resampling image filter.
      *  @param sx           The x scale parameter to apply when resizing.
      *  @param sy           The y scale parameter to apply when resizing.
@@ -28,10 +30,11 @@
      *  @param input        The input image filter.  If NULL, the src bitmap
      *                      passed to filterImage() is used instead.
      */
+    static SkResizeImageFilter* Create(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel,
+                                       SkImageFilter* input = NULL) {
+        return SkNEW_ARGS(SkResizeImageFilter, (sx, sy, filterLevel, input));
+    }
 
-    SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel,
-                        SkImageFilter* input = NULL);
-    virtual ~SkResizeImageFilter();
     virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkResizeImageFilter)
@@ -45,6 +48,12 @@
     virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
                                 SkIRect* dst) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel,
+                        SkImageFilter* input = NULL);
+
 private:
     SkScalar              fSx, fSy;
     SkPaint::FilterLevel  fFilterLevel;
diff --git a/include/effects/SkTestImageFilters.h b/include/effects/SkTestImageFilters.h
index abbaa92..24f6349 100755
--- a/include/effects/SkTestImageFilters.h
+++ b/include/effects/SkTestImageFilters.h
@@ -7,11 +7,14 @@
 // Fun mode that scales down (only) and then scales back up to look pixelated
 class SK_API SkDownSampleImageFilter : public SkImageFilter {
 public:
-    SkDownSampleImageFilter(SkScalar scale) : INHERITED(0), fScale(scale) {}
+    static SkDownSampleImageFilter* Create(SkScalar scale) {
+        return SkNEW_ARGS(SkDownSampleImageFilter, (scale));
+    }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter)
 
 protected:
+    SkDownSampleImageFilter(SkScalar scale) : INHERITED(0), fScale(scale) {}
     SkDownSampleImageFilter(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
diff --git a/include/effects/SkTileImageFilter.h b/include/effects/SkTileImageFilter.h
index 390e00c..4bc2a20 100644
--- a/include/effects/SkTileImageFilter.h
+++ b/include/effects/SkTileImageFilter.h
@@ -14,13 +14,15 @@
     typedef SkImageFilter INHERITED;
 
 public:
-    /** Tile image filter constructor
+    /** Create a tile image filter
         @param srcRect  Defines the pixels to tile
         @param dstRect  Defines the pixels where tiles are drawn
         @param input    Input from which the subregion defined by srcRect will be tiled
     */
-    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
-        : INHERITED(input), fSrcRect(srcRect), fDstRect(dstRect) {}
+    static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect,
+                                     SkImageFilter* input) {
+        return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input));
+    }
 
     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE;
@@ -32,6 +34,12 @@
 
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
+        : INHERITED(input), fSrcRect(srcRect), fDstRect(dstRect) {}
+
 private:
     SkRect fSrcRect;
     SkRect fDstRect;
diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h
index 602dc48..b3872a0 100644
--- a/include/effects/SkXfermodeImageFilter.h
+++ b/include/effects/SkXfermodeImageFilter.h
@@ -21,11 +21,14 @@
       */
 
 public:
-    SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background,
-                          SkImageFilter* foreground = NULL, const CropRect* cropRect = NULL);
-
     virtual ~SkXfermodeImageFilter();
 
+    static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
+                                         SkImageFilter* foreground = NULL,
+                                         const CropRect* cropRect = NULL) {
+        return SkNEW_ARGS(SkXfermodeImageFilter, (mode, background, foreground, cropRect));
+    }
+
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter)
 
     virtual bool onFilterImage(Proxy* proxy,
@@ -43,6 +46,12 @@
     explicit SkXfermodeImageFilter(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
+#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
+public:
+#endif
+    SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background,
+                          SkImageFilter* foreground = NULL, const CropRect* cropRect = NULL);
+
 private:
     SkXfermode* fMode;
     typedef SkImageFilter INHERITED;