Bug 1118092 - Manage invalidation policy directly in the image decoder. r=tn

This commit is contained in:
Seth Fowler 2015-01-10 20:47:38 -08:00
parent 78e1a6fe96
commit 73df45dfe2
4 changed files with 35 additions and 13 deletions

View File

@ -345,6 +345,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
if (mIsPNG) {
mContainedDecoder = new nsPNGDecoder(mImage);
mContainedDecoder->SetSizeDecode(IsSizeDecode());
mContainedDecoder->SetSendPartialInvalidations(mSendPartialInvalidations);
mContainedDecoder->Init();
if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) {
return;
@ -421,6 +422,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
mContainedDecoder = bmpDecoder;
bmpDecoder->SetUseAlphaData(true);
mContainedDecoder->SetSizeDecode(IsSizeDecode());
mContainedDecoder->SetSendPartialInvalidations(mSendPartialInvalidations);
mContainedDecoder->Init();
// The ICO format when containing a BMP does not include the 14 byte

View File

@ -28,6 +28,7 @@ Decoder::Decoder(RasterImage &aImage)
, mChunkCount(0)
, mDecodeFlags(0)
, mBytesDecoded(0)
, mSendPartialInvalidations(false)
, mDecodeDone(false)
, mDataError(false)
, mFrameCount(0)
@ -364,6 +365,12 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
mCurrentFrame->Finish(aFrameOpacity, aDisposalMethod, aTimeout, aBlendMethod);
mProgress |= FLAG_FRAME_COMPLETE | FLAG_ONLOAD_UNBLOCKED;
// If we're not sending partial invalidations, then we send an invalidation
// here when the first frame is complete.
if (!mSendPartialInvalidations && !mIsAnimated) {
mInvalidRect.UnionRect(mInvalidRect, mCurrentFrame->GetRect());
}
}
void
@ -373,9 +380,12 @@ Decoder::PostInvalidation(nsIntRect& aRect)
NS_ABORT_IF_FALSE(mInFrame, "Can't invalidate when not mid-frame!");
NS_ABORT_IF_FALSE(mCurrentFrame, "Can't invalidate when not mid-frame!");
// Account for the new region
mInvalidRect.UnionRect(mInvalidRect, aRect);
mCurrentFrame->ImageUpdated(aRect);
// Record this invalidation, unless we're not sending partial invalidations
// or we're past the first frame.
if (mSendPartialInvalidations && !mIsAnimated) {
mInvalidRect.UnionRect(mInvalidRect, aRect);
mCurrentFrame->ImageUpdated(aRect);
}
}
void

View File

@ -92,6 +92,24 @@ public:
mSizeDecode = aSizeDecode;
}
/**
* Set whether should send partial invalidations.
*
* If @aSend is true, we'll send partial invalidations when decoding the first
* frame of the image, so image notifications observers will be able to
* gradually draw in the image as it downloads.
*
* If @aSend is false (the default), we'll only send an invalidation when we
* complete the first frame.
*
* This must be called before Init() is called.
*/
void SetSendPartialInvalidations(bool aSend)
{
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
mSendPartialInvalidations = aSend;
}
size_t BytesDecoded() const { return mBytesDecoded; }
// The amount of time we've spent inside Write() so far for this decoder.
@ -262,6 +280,7 @@ protected:
uint32_t mDecodeFlags;
size_t mBytesDecoded;
bool mSendPartialInvalidations;
bool mDecodeDone;
bool mDataError;

View File

@ -1505,6 +1505,7 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
// Initialize the decoder
mDecoder->SetSizeDecode(aDoSizeDecode);
mDecoder->SetDecodeFlags(mFrameDecodeFlags);
mDecoder->SetSendPartialInvalidations(!mHasBeenDecoded);
mDecoder->Init();
CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError());
@ -2407,16 +2408,6 @@ RasterImage::FinishedSomeDecoding(ShutdownReason aReason /* = ShutdownReason::DO
}
}
if (GetCurrentFrameIndex() > 0) {
// Don't send invalidations for animated frames after the first; let
// RequestRefresh take care of that.
invalidRect = nsIntRect();
}
if (mHasBeenDecoded && !invalidRect.IsEmpty()) {
// Don't send partial invalidations if we've been decoded before.
invalidRect = mDecoded ? GetFirstFrameRect()
: nsIntRect();
}
if (!invalidRect.IsEmpty() && wasDefaultFlags) {
// Update our image container since we're invalidating.
UpdateImageContainer();