Bug 1155332 - If we don't have enough memory to fully decode an image, discard it immediately. r=tn

This commit is contained in:
Seth Fowler 2015-05-07 09:25:12 -07:00
parent fdc5ab88b6
commit 26a4965347
2 changed files with 25 additions and 6 deletions

View File

@ -500,12 +500,15 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
aDecodeFlags,
aFrameNum),
Lifetime::Persistent);
if (outcome != InsertOutcome::SUCCESS) {
// We either hit InsertOutcome::FAILURE, which is a temporary failure due to
// low memory (we know it's not permanent because we checked CanHold()
// above), or InsertOutcome::FAILURE_ALREADY_PRESENT, which means that
// another decoder beat us to decoding this frame. Either way, we should
// abort this decoder rather than treat this as a real error.
if (outcome == InsertOutcome::FAILURE) {
// We couldn't insert the surface, almost certainly due to low memory. We
// treat this as a permanent error to help the system recover; otherwise, we
// might just end up attempting to decode this image again immediately.
ref->Abort();
return RawAccessFrameRef();
} else if (outcome == InsertOutcome::FAILURE_ALREADY_PRESENT) {
// Another decoder beat us to decoding this frame. We abort this decoder
// rather than treat this as a real error.
mDecodeAborted = true;
ref->Abort();
return RawAccessFrameRef();

View File

@ -1946,6 +1946,22 @@ RasterImage::DoError()
// Put the container in an error state.
mError = true;
// Stop animation and release our FrameAnimator.
if (mAnimating) {
StopAnimation();
}
mAnim.release();
// Release all locks.
mLockCount = 0;
SurfaceCache::UnlockImage(ImageKey(this));
// Release all frames from the surface cache.
SurfaceCache::RemoveImage(ImageKey(this));
// Invalidate to get rid of any partially-drawn image content.
NotifyProgress(NoProgress, IntRect(0, 0, mSize.width, mSize.height));
// Log our error
LOG_CONTAINER_ERROR;
}