From: junov Date: Tue, 9 Dec 2014 21:07:22 +0000 (-0800) Subject: Adding an option for pixelated rendering in SkPictureImageFilter X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~4526 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f3c78ccf5694d22d2e4a7061a80399a7e69b59db;p=platform%2Fupstream%2FlibSkiaSharp.git 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 @@ protected: 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 @@ protected: SkAutoTUnref pictureSourceEmptyRect( SkPictureImageFilter::Create(fPicture, emptyRect)); SkAutoTUnref pictureSourceResampled( - SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect())); + SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(), + SkPaint::kLow_FilterLevel)); + SkAutoTUnref pictureSourcePixelated( + SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(), + SkPaint::kNone_FilterLevel)); canvas->save(); // Draw the picture unscaled. @@ -90,6 +94,10 @@ protected: // 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 @@ private: // 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 @@ public: 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 @@ public: */ 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 @@ protected: 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 @@ private: 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 @@ public: 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 @@ SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t un : 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 @@ SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) { 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 @@ void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { } 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 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Co 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 @@ void SkPictureImageFilter::drawPictureAtLocalResolution(Proxy* proxy, SkBaseDevi 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); }