Bug 1319025 - Fix how animated images disposal method should use frame rect size instead of the image size as its bounds. r=tnikkel

This commit is contained in:
Andrew Osmond
2016-11-25 10:38:37 -05:00
parent 9d88e0d519
commit f90cfd6c9c
5 changed files with 25 additions and 18 deletions

View File

@@ -423,10 +423,13 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
prevFrameData.mDisposalMethod = DisposalMethod::CLEAR; prevFrameData.mDisposalMethod = DisposalMethod::CLEAR;
} }
bool isFullPrevFrame = prevFrameData.mRect.x == 0 && IntRect prevRect = prevFrameData.mBlendRect
prevFrameData.mRect.y == 0 && ? prevFrameData.mRect.Intersect(*prevFrameData.mBlendRect)
prevFrameData.mRect.width == mSize.width && : prevFrameData.mRect;
prevFrameData.mRect.height == mSize.height;
bool isFullPrevFrame = prevRect.x == 0 && prevRect.y == 0 &&
prevRect.width == mSize.width &&
prevRect.height == mSize.height;
// Optimization: DisposeClearAll if the previous frame is the same size as // Optimization: DisposeClearAll if the previous frame is the same size as
// container and it's clearing itself // container and it's clearing itself
@@ -436,10 +439,14 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
} }
AnimationData nextFrameData = nextFrame->GetAnimationData(); AnimationData nextFrameData = nextFrame->GetAnimationData();
bool isFullNextFrame = nextFrameData.mRect.x == 0 &&
nextFrameData.mRect.y == 0 && IntRect nextRect = nextFrameData.mBlendRect
nextFrameData.mRect.width == mSize.width && ? nextFrameData.mRect.Intersect(*nextFrameData.mBlendRect)
nextFrameData.mRect.height == mSize.height; : nextFrameData.mRect;
bool isFullNextFrame = nextRect.x == 0 && nextRect.y == 0 &&
nextRect.width == mSize.width &&
nextRect.height == mSize.height;
if (!nextFrame->GetIsPaletted()) { if (!nextFrame->GetIsPaletted()) {
// Optimization: Skip compositing if the previous frame wants to clear the // Optimization: Skip compositing if the previous frame wants to clear the
@@ -465,7 +472,7 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod"); MOZ_FALLTHROUGH_ASSERT("Unexpected DisposalMethod");
case DisposalMethod::NOT_SPECIFIED: case DisposalMethod::NOT_SPECIFIED:
case DisposalMethod::KEEP: case DisposalMethod::KEEP:
*aDirtyRect = nextFrameData.mRect; *aDirtyRect = nextRect;
break; break;
case DisposalMethod::CLEAR_ALL: case DisposalMethod::CLEAR_ALL:
@@ -481,7 +488,7 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
// way at the bottom, and both frames being small, we'd be // way at the bottom, and both frames being small, we'd be
// telling framechanged to refresh the whole image when only two // telling framechanged to refresh the whole image when only two
// small areas are needed. // small areas are needed.
aDirtyRect->UnionRect(nextFrameData.mRect, prevFrameData.mRect); aDirtyRect->UnionRect(nextRect, prevRect);
break; break;
case DisposalMethod::RESTORE_PREVIOUS: case DisposalMethod::RESTORE_PREVIOUS:
@@ -537,12 +544,9 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
// No need to blank the composite frame // No need to blank the composite frame
needToBlankComposite = false; needToBlankComposite = false;
} else { } else {
if ((prevFrameData.mRect.x >= nextFrameData.mRect.x) && if ((prevRect.x >= nextRect.x) && (prevRect.y >= nextRect.y) &&
(prevFrameData.mRect.y >= nextFrameData.mRect.y) && (prevRect.x + prevRect.width <= nextRect.x + nextRect.width) &&
(prevFrameData.mRect.x + prevFrameData.mRect.width <= (prevRect.y + prevRect.height <= nextRect.y + nextRect.height)) {
nextFrameData.mRect.x + nextFrameData.mRect.width) &&
(prevFrameData.mRect.y + prevFrameData.mRect.height <=
nextFrameData.mRect.y + nextFrameData.mRect.height)) {
// Optimization: No need to dispose prev.frame when // Optimization: No need to dispose prev.frame when
// next frame fully overlaps previous frame. // next frame fully overlaps previous frame.
doDisposal = false; doDisposal = false;
@@ -563,7 +567,7 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
// Only blank out previous frame area (both color & Mask/Alpha) // Only blank out previous frame area (both color & Mask/Alpha)
ClearFrame(compositingFrameData.mRawData, ClearFrame(compositingFrameData.mRawData,
compositingFrameData.mRect, compositingFrameData.mRect,
prevFrameData.mRect); prevRect);
} }
break; break;
@@ -610,7 +614,7 @@ FrameAnimator::DoBlend(IntRect* aDirtyRect,
if (isFullPrevFrame && !prevFrame->GetIsPaletted()) { if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
// Just copy the bits // Just copy the bits
CopyFrameImage(prevFrameData.mRawData, CopyFrameImage(prevFrameData.mRawData,
prevFrameData.mRect, prevRect,
compositingFrameData.mRawData, compositingFrameData.mRawData,
compositingFrameData.mRect); compositingFrameData.mRect);
} else { } else {

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

View File

@@ -40,6 +40,8 @@ support-files =
bug1180105.sjs bug1180105.sjs
bug1180105-waiter.sjs bug1180105-waiter.sjs
bug1217571-iframe.html bug1217571-iframe.html
bug1319025.png
bug1319025-ref.png
clear.gif clear.gif
clear.png clear.png
clear2.gif clear2.gif

View File

@@ -42,6 +42,7 @@ var gTests = [
"== over.png grey.png", "== over.png grey.png",
"!= source.png grey.png", "!= source.png grey.png",
"== bug900200.png bug900200-ref.png", "== bug900200.png bug900200-ref.png",
"== bug1319025.png bug1319025-ref.png",
// Test of subframe updates. // Test of subframe updates.
"== clear2.gif clear2-results.gif", "== clear2.gif clear2-results.gif",