Adding an option for pixelated rendering in SkPictureImageFilter

BUG=skia:3209

Review URL: https://codereview.chromium.org/787073003
diff --git a/gm/pictureimagefilter.cpp b/gm/pictureimagefilter.cpp
index 712e059..bae94f5 100644
--- a/gm/pictureimagefilter.cpp
+++ b/gm/pictureimagefilter.cpp
@@ -36,7 +36,7 @@
         fPicture.reset(recorder.endRecording());
     }
 
-    virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(400, 300); }
+    virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(600, 300); }
 
     virtual void onOnceBeforeDraw() SK_OVERRIDE {
         this->makePicture();
@@ -64,7 +64,11 @@
             SkAutoTUnref<SkPictureImageFilter> pictureSourceEmptyRect(
                 SkPictureImageFilter::Create(fPicture, emptyRect));
             SkAutoTUnref<SkPictureImageFilter> pictureSourceResampled(
-                SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect()));
+                SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(),
+                    SkPaint::kLow_FilterLevel));
+            SkAutoTUnref<SkPictureImageFilter> pictureSourcePixelated(
+                SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(),
+                    SkPaint::kNone_FilterLevel));
 
             canvas->save();
             // Draw the picture unscaled.
@@ -90,6 +94,10 @@
             // Draw the picture scaled, but rasterized at original resolution
             canvas->translate(srcRect.width(), 0);
             fillRectFiltered(canvas, srcRect, pictureSourceResampled);
+
+            // Draw the picture scaled, pixelated
+            canvas->translate(srcRect.width(), 0);
+            fillRectFiltered(canvas, srcRect, pictureSourcePixelated);
         }
     }
 
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index f764d34..eb136e1 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -246,14 +246,15 @@
     // V35: Store SkRect (rather then width & height) in header
     // V36: Remove (obsolete) alphatype from SkColorTable
     // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR)
-    // V37: Added PictureResolution and FilterLevel options to SkPictureImageFilter
+    // V38: Added PictureResolution option to SkPictureImageFilter
+    // V39: Added FilterLevel option to SkPictureImageFilter
 
     // Note: If the picture version needs to be increased then please follow the
     // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t MIN_PICTURE_VERSION = 35;     // Produced by Chrome M39.
-    static const uint32_t CURRENT_PICTURE_VERSION = 38;
+    static const uint32_t CURRENT_PICTURE_VERSION = 39;
 
     void createHeader(SkPictInfo* info) const;
     static bool IsValidPictInfo(const SkPictInfo& info);
diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h
index 8c3c9c4..9db6f2f 100644
--- a/include/effects/SkPictureImageFilter.h
+++ b/include/effects/SkPictureImageFilter.h
@@ -27,7 +27,8 @@
     static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect,
                                         uint32_t uniqueID = 0) {
         return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID,
-                                                 kDeviceSpace_PictureResolution));
+                                                 kDeviceSpace_PictureResolution,
+                                                 SkPaint::kLow_FilterLevel));
     }
 
     /**
@@ -39,9 +40,10 @@
      */
     static SkPictureImageFilter* CreateForLocalSpace(const SkPicture* picture,
                                                      const SkRect& cropRect,
+                                                     SkPaint::FilterLevel filterLevel,
                                                      uint32_t uniqueID = 0) {
         return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID,
-                                                 kLocalSpace_PictureResolution));
+                                                 kLocalSpace_PictureResolution, filterLevel));
     }
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
@@ -54,7 +56,7 @@
 
     explicit SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID);
     SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID,
-                         PictureResolution);
+                         PictureResolution, SkPaint::FilterLevel);
     virtual ~SkPictureImageFilter();
     /*  Constructs an SkPictureImageFilter object from an SkReadBuffer.
      *  Note: If the SkPictureImageFilter object construction requires bitmap
@@ -77,6 +79,7 @@
     const SkPicture*      fPicture;
     SkRect                fCropRect;
     PictureResolution     fPictureResolution;
+    SkPaint::FilterLevel  fFilterLevel;
     typedef SkImageFilter INHERITED;
 };
 
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 9056b07..a24ca55 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -54,6 +54,7 @@
         kRemoveColorTableAlpha_Version     = 36,
         kDropShadowMode_Version            = 37,
         kPictureImageFilterResolution_Version = 38,
+        kPictureImageFilterLevel_Version   = 39,
     };
 
     /**
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
index e18600d..8075f36 100644
--- a/src/effects/SkPictureImageFilter.cpp
+++ b/src/effects/SkPictureImageFilter.cpp
@@ -17,15 +17,18 @@
     : INHERITED(0, 0, NULL, uniqueID)
     , fPicture(SkSafeRef(picture))
     , fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty())
-    , fPictureResolution(kDeviceSpace_PictureResolution) {
+    , fPictureResolution(kDeviceSpace_PictureResolution) 
+    , fFilterLevel(SkPaint::kLow_FilterLevel) {
 }
 
 SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
-                                           uint32_t uniqueID, PictureResolution pictureResolution)
+                                           uint32_t uniqueID, PictureResolution pictureResolution,
+                                           SkPaint::FilterLevel filterLevel)
     : INHERITED(0, 0, NULL, uniqueID)
     , fPicture(SkSafeRef(picture))
     , fCropRect(cropRect)
-    , fPictureResolution(pictureResolution) {
+    , fPictureResolution(pictureResolution)
+    , fFilterLevel(filterLevel) {
 }
 
 SkPictureImageFilter::~SkPictureImageFilter() {
@@ -49,10 +52,17 @@
         pictureResolution = kDeviceSpace_PictureResolution;
     } else {
         pictureResolution = (PictureResolution)buffer.readInt();
-    } 
+    }  
 
-    if (pictureResolution == kLocalSpace_PictureResolution) {
-        return CreateForLocalSpace(picture, cropRect);
+    if (kLocalSpace_PictureResolution == pictureResolution) {
+        //filterLevel is only serialized if pictureResolution is LocalSpace
+        SkPaint::FilterLevel filterLevel;
+        if (buffer.isVersionLT(SkReadBuffer::kPictureImageFilterLevel_Version)) {
+            filterLevel = SkPaint::kLow_FilterLevel;
+        } else {
+            filterLevel = (SkPaint::FilterLevel)buffer.readInt();
+        }
+        return CreateForLocalSpace(picture, cropRect, filterLevel);    
     }
     return Create(picture, cropRect);
 }
@@ -69,6 +79,9 @@
     }
     buffer.writeRect(fCropRect);
     buffer.writeInt(fPictureResolution);
+    if (kLocalSpace_PictureResolution == fPictureResolution) {
+        buffer.writeInt(fFilterLevel);
+    }
 }
 
 bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
@@ -95,11 +108,11 @@
         return false;
     }
 
-    if (kLocalSpace_PictureResolution == fPictureResolution && 
-        (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) {
-        drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx);
+    if (kDeviceSpace_PictureResolution == fPictureResolution || 
+        0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) {
+        drawPictureAtDeviceResolution(proxy, device.get(), bounds, ctx);        
     } else {
-        drawPictureAtDeviceResolution(proxy, device.get(), bounds, ctx);
+        drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx);
     }
 
     *result = device.get()->accessBitmap(false);
@@ -149,7 +162,8 @@
     canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop));
     canvas.concat(ctx.ctm());
     SkPaint paint;
-    paint.setFilterLevel(SkPaint::kLow_FilterLevel);
-    canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(localIBounds.fLeft), SkIntToScalar(localIBounds.fTop), &paint);
+    paint.setFilterLevel(fFilterLevel);
+    canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(localIBounds.fLeft),
+                      SkIntToScalar(localIBounds.fTop), &paint);
     //canvas.drawPicture(fPicture);
 }