From 48723156c597ec4d7be8e0648548ff27ef6c4e02 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 10 Nov 2017 14:35:54 -0500 Subject: [PATCH] remove legacy code for resolution Bug: skia: Change-Id: I6909325d4ee51140ec0edb47682de18617c23cc7 Reviewed-on: https://skia-review.googlesource.com/70100 Commit-Queue: Mike Reed Reviewed-by: Florin Malita --- include/effects/SkPictureImageFilter.h | 22 +--- src/core/SkReadBuffer.cpp | 16 +++ src/core/SkReadBuffer.h | 13 ++- src/effects/SkPictureImageFilter.cpp | 135 ++++++------------------- 4 files changed, 61 insertions(+), 125 deletions(-) diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h index 76e7b63e3e..25ccaf508b 100644 --- a/include/effects/SkPictureImageFilter.h +++ b/include/effects/SkPictureImageFilter.h @@ -28,11 +28,6 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter) protected: - enum PictureResolution { - kDeviceSpace_PictureResolution, - kLocalSpace_PictureResolution - }; - /* Constructs an SkPictureImageFilter object from an SkReadBuffer. * Note: If the SkPictureImageFilter object construction requires bitmap * decoding, the decoder must be set on the SkReadBuffer parameter by calling @@ -46,21 +41,10 @@ protected: private: explicit SkPictureImageFilter(sk_sp picture); - SkPictureImageFilter(sk_sp picture, const SkRect& cropRect, - PictureResolution, SkFilterQuality, sk_sp); + SkPictureImageFilter(sk_sp picture, const SkRect& cropRect, sk_sp); - void drawPictureAtDeviceResolution(SkCanvas* canvas, - const SkIRect& deviceBounds, - const Context&) const; - void drawPictureAtLocalResolution(SkSpecialImage* source, - SkCanvas*, - const SkIRect& deviceBounds, - const Context&) const; - - sk_sp fPicture; - SkRect fCropRect; - PictureResolution fPictureResolution; - SkFilterQuality fFilterQuality; + sk_sp fPicture; + SkRect fCropRect; // Should never be set by a public constructor. This is only used when onMakeColorSpace() // forces a deferred color space xform. diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 2f5b264ae1..b9bcdd4550 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -399,3 +399,19 @@ SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { } return obj.release(); } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +int32_t SkReadBuffer::checkInt(int32_t min, int32_t max) { + SkASSERT(min <= max); + int32_t value = this->read32(); + if (value < min || value > max) { + this->validate(false); + value = min; + } + return value; +} + +SkFilterQuality SkReadBuffer::checkFilterQuality() { + return this->checkRange(kNone_SkFilterQuality, kLast_SkFilterQuality); +} diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index f7b724d588..a92049dee8 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -224,7 +224,18 @@ public: SkInflator* getInflator() const { return fInflator; } void setInflator(SkInflator* inf) { fInflator = inf; } -// sk_sp inflateImage(); + // Utilities that mark the buffer invalid if the requested value is out-of-range + + // If the read value is outside of the range, validate(false) is called, and min + // is returned, else the value is returned. + int32_t checkInt(int min, int max); + + template T checkRange(T min, T max) { + return static_cast(this->checkInt(static_cast(min), + static_cast(max))); + } + + SkFilterQuality checkFilterQuality(); protected: /** diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp index 5611900e7e..709a0901b6 100644 --- a/src/effects/SkPictureImageFilter.cpp +++ b/src/effects/SkPictureImageFilter.cpp @@ -10,6 +10,7 @@ #include "SkCanvas.h" #include "SkColorSpaceXformCanvas.h" #include "SkColorSpaceXformer.h" +#include "SkImageSource.h" #include "SkReadBuffer.h" #include "SkSpecialImage.h" #include "SkSpecialSurface.h" @@ -22,33 +23,35 @@ sk_sp SkPictureImageFilter::Make(sk_sp picture) { sk_sp SkPictureImageFilter::Make(sk_sp picture, const SkRect& cropRect) { - return sk_sp(new SkPictureImageFilter(std::move(picture), - cropRect, - kDeviceSpace_PictureResolution, - kLow_SkFilterQuality, - nullptr)); + return sk_sp(new SkPictureImageFilter(std::move(picture), cropRect, nullptr)); } SkPictureImageFilter::SkPictureImageFilter(sk_sp picture) : INHERITED(nullptr, 0, nullptr) , fPicture(std::move(picture)) - , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) - , fPictureResolution(kDeviceSpace_PictureResolution) - , fFilterQuality(kLow_SkFilterQuality) { + , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) { } SkPictureImageFilter::SkPictureImageFilter(sk_sp picture, const SkRect& cropRect, - PictureResolution pictureResolution, - SkFilterQuality filterQuality, sk_sp colorSpace) : INHERITED(nullptr, 0, nullptr) , fPicture(std::move(picture)) , fCropRect(cropRect) - , fPictureResolution(pictureResolution) - , fFilterQuality(filterQuality) , fColorSpace(std::move(colorSpace)) { } +enum PictureResolution { + kDeviceSpace_PictureResolution, + kLocalSpace_PictureResolution +}; +static sk_sp make_localspace_filter(sk_sp pic, const SkRect& cropRect, + SkFilterQuality fq) { + SkISize dim = { SkScalarRoundToInt(cropRect.width()), SkScalarRoundToInt(cropRect.height()) }; + auto img = SkImage::MakeFromPicture(std::move(pic), dim, nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); + return SkImageSource::Make(img, cropRect, cropRect, fq); +} + sk_sp SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) { sk_sp picture; SkRect cropRect; @@ -62,24 +65,15 @@ sk_sp SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) { } buffer.readRect(&cropRect); - // NOTE: these two fields can be removed from the class once we have out-lived the need - // to load pictures older than SkReadBuffer::kRemovePictureImageFilterLocalSpace - // - PictureResolution pictureResolution = kDeviceSpace_PictureResolution; - SkFilterQuality filterQuality = kNone_SkFilterQuality; - if (buffer.isVersionLT(SkReadBuffer::kRemovePictureImageFilterLocalSpace)) { - pictureResolution = (PictureResolution)buffer.readInt(); + PictureResolution pictureResolution = buffer.checkRange( + kDeviceSpace_PictureResolution, kLocalSpace_PictureResolution); if (kLocalSpace_PictureResolution == pictureResolution) { - //filterLevel is only serialized if pictureResolution is LocalSpace - filterQuality = (SkFilterQuality)buffer.readInt(); + return make_localspace_filter(std::move(picture), cropRect, + buffer.checkFilterQuality()); } } - return sk_sp(new SkPictureImageFilter(picture, - cropRect, - pictureResolution, - filterQuality, - nullptr)); + return sk_sp(new SkPictureImageFilter(picture, cropRect, nullptr)); } void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { @@ -120,12 +114,16 @@ sk_sp SkPictureImageFilter::onFilterImage(SkSpecialImage* source SkASSERT(canvas); canvas->clear(0x0); - if (kDeviceSpace_PictureResolution == fPictureResolution || - 0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { - this->drawPictureAtDeviceResolution(canvas, bounds, ctx); - } else { - this->drawPictureAtLocalResolution(source, canvas, bounds, ctx); + std::unique_ptr xformCanvas; + if (fColorSpace) { + // Only non-null in the case where onMakeColorSpace() was called. This instructs + // us to do the color space xform on playback. + xformCanvas = SkCreateColorSpaceXformCanvas(canvas, fColorSpace); + canvas = xformCanvas.get(); } + canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); + canvas->concat(ctx.ctm()); + canvas->drawPicture(fPicture); offset->fX = bounds.fLeft; offset->fY = bounds.fTop; @@ -138,80 +136,7 @@ sk_sp SkPictureImageFilter::onMakeColorSpace(SkColorSpaceXformer* return this->refMe(); } - return sk_sp(new SkPictureImageFilter(fPicture, fCropRect, fPictureResolution, - fFilterQuality, std::move(dstCS))); -} - -void SkPictureImageFilter::drawPictureAtDeviceResolution(SkCanvas* canvas, - const SkIRect& deviceBounds, - const Context& ctx) const { - std::unique_ptr xformCanvas = nullptr; - if (fColorSpace) { - // Only non-null in the case where onMakeColorSpace() was called. This instructs - // us to do the color space xform on playback. - xformCanvas = SkCreateColorSpaceXformCanvas(canvas, fColorSpace); - canvas = xformCanvas.get(); - } - canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop)); - canvas->concat(ctx.ctm()); - canvas->drawPicture(fPicture); -} - -void SkPictureImageFilter::drawPictureAtLocalResolution(SkSpecialImage* source, - SkCanvas* canvas, - const SkIRect& deviceBounds, - const Context& ctx) const { - SkMatrix inverseCtm; - if (!ctx.ctm().invert(&inverseCtm)) { - return; - } - - SkRect localBounds = SkRect::Make(ctx.clipBounds()); - inverseCtm.mapRect(&localBounds); - if (!localBounds.intersect(fCropRect)) { - return; - } - SkIRect localIBounds = localBounds.roundOut(); - - sk_sp localImg; - { - sk_sp localSurface(source->makeSurface(ctx.outputProperties(), - localIBounds.size())); - if (!localSurface) { - return; - } - - SkCanvas* localCanvas = localSurface->getCanvas(); - SkASSERT(localCanvas); - std::unique_ptr xformCanvas = nullptr; - if (fColorSpace) { - // Only non-null in the case where onMakeColorSpace() was called. This instructs - // us to do the color space xform on playback. - xformCanvas = SkCreateColorSpaceXformCanvas(localCanvas, fColorSpace); - localCanvas = xformCanvas.get(); - } - - localCanvas->clear(0x0); - - localCanvas->translate(-SkIntToScalar(localIBounds.fLeft), - -SkIntToScalar(localIBounds.fTop)); - localCanvas->drawPicture(fPicture); - - localImg = localSurface->makeImageSnapshot(); - SkASSERT(localImg); - } - - { - canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop)); - canvas->concat(ctx.ctm()); - SkPaint paint; - paint.setFilterQuality(fFilterQuality); - - localImg->draw(canvas, - SkIntToScalar(localIBounds.fLeft), - SkIntToScalar(localIBounds.fTop), - &paint); - } + return sk_sp(new SkPictureImageFilter(fPicture, fCropRect, std::move(dstCS))); } #ifndef SK_IGNORE_TO_STRING