Bug 1364221 - Allow frames to be prerendered as long as the area of the frame is less than the area of the relative limit and the dimensions are less than the absolute limit. r=mattwoodrow,mstange

MozReview-Commit-ID: C3QLjaCRbzE

--HG--
extra : rebase_source : 1c9ad6b7c04d65b8b71f5112b7f4c91415aa70d9
This commit is contained in:
Jared Wein 2017-06-05 17:01:19 -04:00
parent 94170bb269
commit 6e57031fc1
5 changed files with 81 additions and 19 deletions

View File

@ -35,11 +35,18 @@ AnimationPerformanceWarning::ToLocalizedString(
switch (mType) {
case Type::ContentTooLarge:
MOZ_ASSERT(mParams && mParams->Length() == 6,
"Parameter's length should be 6 for ContentTooLarge");
"Parameter's length should be 6 for ContentTooLarge2");
return NS_SUCCEEDED(
ToLocalizedStringWithIntParams<7>(
"CompositorAnimationWarningContentTooLarge2", aLocalizedString));
case Type::ContentTooLargeArea:
MOZ_ASSERT(mParams && mParams->Length() == 2,
"Parameter's length should be 2 for ContentTooLargeArea");
return NS_SUCCEEDED(
ToLocalizedStringWithIntParams<3>(
"CompositorAnimationWarningContentTooLargeArea", aLocalizedString));
case Type::TransformBackfaceVisibilityHidden:
key = "CompositorAnimationWarningTransformBackfaceVisibilityHidden";
break;

View File

@ -21,6 +21,7 @@ struct AnimationPerformanceWarning
{
enum class Type : uint8_t {
ContentTooLarge,
ContentTooLargeArea,
TransformBackfaceVisibilityHidden,
TransformPreserve3D,
TransformSVG,

View File

@ -1175,13 +1175,48 @@ function start() {
assert_animation_property_state_equals(
animation.effect.getProperties(),
[ { property: 'transform', runningOnCompositor: true } ]);
animation.effect.target.style = 'width: 10000px; height: 10000px';
animation.effect.target.style = 'width: 5200px; height: 5200px';
return waitForFrame();
}).then(function() {
// viewport depends on test environment.
var expectedWarning = new RegExp(
"Animation cannot be run on the compositor because the area of the frame size " +
"\\(\\d+\\) is too large relative to the viewport " +
"\\(larger than \\d+\\)");
assert_animation_property_state_equals(
animation.effect.getProperties(),
[ {
property: 'transform',
runningOnCompositor: false,
warning: expectedWarning
} ]);
animation.effect.target.style = 'width: 100px; height: 100px';
return waitForFrame();
}).then(function() {
// FIXME: Bug 1253164: the animation should get back on compositor.
assert_animation_property_state_equals(
animation.effect.getProperties(),
[ { property: 'transform', runningOnCompositor: false } ]);
});
}, 'transform on too big element - area');
promise_test(function(t) {
var animation = addDivAndAnimate(t,
{ class: 'compositable' },
{ transform: [ 'translate(0px)',
'translate(100px)'] },
100 * MS_PER_SEC);
return animation.ready.then(function() {
assert_animation_property_state_equals(
animation.effect.getProperties(),
[ { property: 'transform', runningOnCompositor: true } ]);
animation.effect.target.style = 'width: 5200px; height: 1px';
return waitForFrame();
}).then(function() {
// viewport depends on test environment.
var expectedWarning = new RegExp(
"Animation cannot be run on the compositor because the frame size " +
"\\(10000, 10000\\) is too large relative to the viewport " +
"\\(5200, 1\\) is too large relative to the viewport " +
"\\(larger than \\(\\d+, \\d+\\)\\) or larger than the " +
"maximum allowed value \\(\\d+, \\d+\\)");
assert_animation_property_state_equals(
@ -1199,7 +1234,7 @@ function start() {
animation.effect.getProperties(),
[ { property: 'transform', runningOnCompositor: false } ]);
});
}, 'transform on too big element');
}, 'transform on too big element - dimensions');
promise_test(function(t) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

View File

@ -11,6 +11,10 @@ ImageMapPolyOddNumberOfCoords=The “coords” attribute of the <area shape="pol
TablePartRelPosWarning=Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature having no effect.
ScrollLinkedEffectFound2=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!
## LOCALIZATION NOTE(CompositorAnimationWarningContentTooLargeArea):
## %1$S is an integer value of the area of the frame size
## %2$S is an integer value of the area of a limit based on the viewport size
CompositorAnimationWarningContentTooLargeArea=Animation cannot be run on the compositor because the area of the frame size (%1$S) is too large relative to the viewport (larger than %2$S)
## LOCALIZATION NOTE(CompositorAnimationWarningContentTooLarge2):
## (%1$S, %2$S) is a pair of integer values of the frame size
## (%3$S, %4$S) is a pair of integer values of a limit based on the viewport size

View File

@ -7356,9 +7356,11 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
aFrame->PresContext()->DevPixelsToAppUnits(absoluteLimitY));
nsSize maxSize = Min(relativeLimit, absoluteLimit);
gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(aFrame);
nsSize frameSize = nsSize(overflow.Size().width * scale.width,
overflow.Size().height * scale.height);
if (frameSize <= maxSize) {
nsSize frameSize(overflow.Size().width * scale.width,
overflow.Size().height * scale.height);
uint64_t maxLimitArea = uint64_t(maxSize.width) * maxSize.height;
uint64_t frameArea = uint64_t(frameSize.width) * frameSize.height;
if (frameArea <= maxLimitArea && frameSize <= absoluteLimit) {
*aDirtyRect = overflow;
return FullPrerender;
} else if (gfxPrefs::PartiallyPrerenderAnimatedContent()) {
@ -7366,18 +7368,31 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
return PartialPrerender;
}
EffectCompositor::SetPerformanceWarning(
aFrame, eCSSProperty_transform,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::ContentTooLarge,
{
nsPresContext::AppUnitsToIntCSSPixels(frameSize.width),
nsPresContext::AppUnitsToIntCSSPixels(frameSize.height),
nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.width),
nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.height),
nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.width),
nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.height),
}));
if (frameArea > maxLimitArea) {
uint64_t appUnitsPerPixel = nsPresContext::AppUnitsPerCSSPixel();
EffectCompositor::SetPerformanceWarning(
aFrame, eCSSProperty_transform,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::ContentTooLargeArea,
{
int(frameArea / (appUnitsPerPixel * appUnitsPerPixel)),
int(maxLimitArea / (appUnitsPerPixel * appUnitsPerPixel)),
}));
} else {
EffectCompositor::SetPerformanceWarning(
aFrame, eCSSProperty_transform,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::ContentTooLarge,
{
nsPresContext::AppUnitsToIntCSSPixels(frameSize.width),
nsPresContext::AppUnitsToIntCSSPixels(frameSize.height),
nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.width),
nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.height),
nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.width),
nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.height),
}));
}
return NoPrerender;
}