From eb02069aa55fd9fe9ddaedcd4564a3b644f0ee86 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 5 May 2015 15:35:34 -0700 Subject: [PATCH] Bug 1145560 - During downscale-during-decode, compute the original size invalid rect based on the target size invalid rect. r=tn --- image/decoders/nsJPEGDecoder.cpp | 14 +++++++------- image/src/Downscaler.cpp | 20 +++++++++++++++----- image/src/Downscaler.h | 14 +++++++++++++- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp index 9d7eeb04e642..c6f09f6fff4f 100644 --- a/image/decoders/nsJPEGDecoder.cpp +++ b/image/decoders/nsJPEGDecoder.cpp @@ -719,16 +719,16 @@ nsJPEGDecoder::OutputScanlines(bool* suspend) } } - if (top != mInfo.output_scanline) { + if (mDownscaler && mDownscaler->HasInvalidation()) { + DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect(); + PostInvalidation(invalidRect.mOriginalSizeRect, + Some(invalidRect.mTargetSizeRect)); + MOZ_ASSERT(!mDownscaler->HasInvalidation()); + } else if (!mDownscaler && top != mInfo.output_scanline) { PostInvalidation(nsIntRect(0, top, mInfo.output_width, - mInfo.output_scanline - top), - mDownscaler ? Some(mDownscaler->TakeInvalidRect()) - : Nothing()); + mInfo.output_scanline - top)); } - - MOZ_ASSERT(!mDownscaler || !mDownscaler->HasInvalidation(), - "Didn't send downscaler's invalidation"); } // Override the standard error method in the IJG JPEG decoder code. diff --git a/image/src/Downscaler.cpp b/image/src/Downscaler.cpp index a0839e54a091..40459c5e12cb 100644 --- a/image/src/Downscaler.cpp +++ b/image/src/Downscaler.cpp @@ -69,6 +69,8 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize, "Invalid original size"); mOriginalSize = aOriginalSize; + mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width, + double(mOriginalSize.height) / mTargetSize.height); mOutputBuffer = aOutputBuffer; mHasAlpha = aHasAlpha; @@ -183,17 +185,25 @@ Downscaler::HasInvalidation() const return mCurrentOutLine > mPrevInvalidatedLine; } -nsIntRect +DownscalerInvalidRect Downscaler::TakeInvalidRect() { if (MOZ_UNLIKELY(!HasInvalidation())) { - return nsIntRect(); + return DownscalerInvalidRect(); } - nsIntRect invalidRect(0, mPrevInvalidatedLine, - mTargetSize.width, - mCurrentOutLine - mPrevInvalidatedLine); + DownscalerInvalidRect invalidRect; + + // Compute the target size invalid rect. + invalidRect.mTargetSizeRect = + nsIntRect(0, mPrevInvalidatedLine, + mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine); mPrevInvalidatedLine = mCurrentOutLine; + + // Compute the original size invalid rect. + invalidRect.mOriginalSizeRect = invalidRect.mTargetSizeRect; + invalidRect.mOriginalSizeRect.ScaleRoundOut(mScale.width, mScale.height); + return invalidRect; } diff --git a/image/src/Downscaler.h b/image/src/Downscaler.h index 67c88e2c8bab..b052f3da6da0 100644 --- a/image/src/Downscaler.h +++ b/image/src/Downscaler.h @@ -24,6 +24,16 @@ namespace skia { namespace mozilla { namespace image { +/** + * DownscalerInvalidRect wraps two invalidation rects: one in terms of the + * original image size, and one in terms of the target size. + */ +struct DownscalerInvalidRect +{ + nsIntRect mOriginalSizeRect; + nsIntRect mTargetSizeRect; +}; + /** * Downscaler is a high-quality, streaming image downscaler based upon Skia's * scaling implementation. @@ -47,6 +57,7 @@ public: const nsIntSize& OriginalSize() const { return mOriginalSize; } const nsIntSize& TargetSize() const { return mTargetSize; } + const gfxSize& Scale() const { return mScale; } /** * Begins a new frame and reinitializes the Downscaler. @@ -73,7 +84,7 @@ public: bool HasInvalidation() const; /// Takes the Downscaler's current invalid rect and resets it. - nsIntRect TakeInvalidRect(); + DownscalerInvalidRect TakeInvalidRect(); /** * Resets the Downscaler's position in the image, for a new progressive pass @@ -88,6 +99,7 @@ private: nsIntSize mOriginalSize; nsIntSize mTargetSize; + gfxSize mScale; uint8_t* mOutputBuffer;