mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 856486 (Part 2) - Buffer the last fully-decoded frame for multipart images. r=jrmuizel
This commit is contained in:
parent
4d5dd53b5e
commit
9b33d58640
@ -385,6 +385,7 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
|
||||
ImageResource(aStatusTracker, aURI), // invoke superclass's constructor
|
||||
mSize(0,0),
|
||||
mFrameDecodeFlags(DECODE_FLAGS_DEFAULT),
|
||||
mMultipartDecodedFrame(nullptr),
|
||||
mAnim(nullptr),
|
||||
mLoopCount(-1),
|
||||
mLockCount(0),
|
||||
@ -458,6 +459,8 @@ RasterImage::~RasterImage()
|
||||
for (unsigned int i = 0; i < mFrames.Length(); ++i)
|
||||
delete mFrames[i];
|
||||
|
||||
delete mMultipartDecodedFrame;
|
||||
|
||||
// Total statistics
|
||||
num_containers--;
|
||||
total_source_bytes -= mSourceData.Length();
|
||||
@ -1571,6 +1574,25 @@ RasterImage::DecodingComplete()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Double-buffer our frame in the multipart case, since we'll start decoding
|
||||
// into mFrames again immediately and this produces severe tearing.
|
||||
if (mMultipart) {
|
||||
if (mFrames.Length() == 1) {
|
||||
imgFrame* swapFrame = mMultipartDecodedFrame;
|
||||
mMultipartDecodedFrame = GetImgFrameNoDecode(GetCurrentFrameIndex());
|
||||
mFrames.Clear();
|
||||
if (swapFrame) {
|
||||
mFrames.AppendElement(swapFrame);
|
||||
}
|
||||
} else {
|
||||
// Don't double buffer for animated multipart images. It entails more
|
||||
// complexity and it's not really needed since we already are smart about
|
||||
// not displaying the still-decoding frame of an animated image. We may
|
||||
// have already stored an extra frame, though, so we'll release it here.
|
||||
delete mMultipartDecodedFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2473,6 +2495,10 @@ RasterImage::Discard(bool force)
|
||||
mScaleResult.status = SCALE_INVALID;
|
||||
mScaleResult.frame = nullptr;
|
||||
|
||||
// Clear the last decoded multipart frame.
|
||||
delete mMultipartDecodedFrame;
|
||||
mMultipartDecodedFrame = nullptr;
|
||||
|
||||
// Flag that we no longer have decoded frames for this image
|
||||
mDecoded = false;
|
||||
|
||||
@ -3193,9 +3219,19 @@ RasterImage::Draw(gfxContext *aContext,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
|
||||
: GetCurrentImgFrameIndex();
|
||||
imgFrame *frame = GetDrawableImgFrame(frameIndex);
|
||||
imgFrame* frame = nullptr;
|
||||
|
||||
if (mMultipart) {
|
||||
// In the multipart case we prefer to use mMultipartDecodedFrame, which is
|
||||
// the most recent one we completely decoded, rather than display the real
|
||||
// current frame and risk severe tearing.
|
||||
frame = mMultipartDecodedFrame;
|
||||
}
|
||||
if (!frame) {
|
||||
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
|
||||
: GetCurrentImgFrameIndex();
|
||||
frame = GetDrawableImgFrame(frameIndex);
|
||||
}
|
||||
if (!frame) {
|
||||
return NS_OK; // Getting the frame (above) touches the image and kicks off decoding
|
||||
}
|
||||
|
@ -729,7 +729,10 @@ private: // data
|
||||
// IMPORTANT: if you use mFrames in a method, call EnsureImageIsDecoded() first
|
||||
// to ensure that the frames actually exist (they may have been discarded to save
|
||||
// memory, or we may be decoding on draw).
|
||||
nsTArray<imgFrame *> mFrames;
|
||||
nsTArray<imgFrame*> mFrames;
|
||||
|
||||
// The last frame we decoded for multipart images.
|
||||
imgFrame* mMultipartDecodedFrame;
|
||||
|
||||
nsCOMPtr<nsIProperties> mProperties;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user