Bug 1321412 - Allow controlling the size of the prerendered area via prefs. r=mattwoodrow,birtles
Note that the default values of the prefs are chosen so as to preserve
existing behaviour.
The patch also updates a user-visible warning message, which was
already out of date as of
bug 1274991.
MozReview-Commit-ID: AqBBoIucShT
--- a/dom/animation/AnimationPerformanceWarning.cpp
+++ b/dom/animation/AnimationPerformanceWarning.cpp
@@ -36,22 +36,22 @@ AnimationPerformanceWarning::ToLocalized
case Type::ContentTooSmall:
MOZ_ASSERT(mParams && mParams->Length() == 2,
"Parameter's length should be 2 for ContentTooSmall");
return NS_SUCCEEDED(
ToLocalizedStringWithIntParams<2>(
"CompositorAnimationWarningContentTooSmall", aLocalizedString));
case Type::ContentTooLarge:
- MOZ_ASSERT(mParams && mParams->Length() == 7,
- "Parameter's length should be 7 for ContentTooLarge");
+ MOZ_ASSERT(mParams && mParams->Length() == 6,
+ "Parameter's length should be 6 for ContentTooLarge");
return NS_SUCCEEDED(
ToLocalizedStringWithIntParams<7>(
- "CompositorAnimationWarningContentTooLarge", aLocalizedString));
+ "CompositorAnimationWarningContentTooLarge2", aLocalizedString));
case Type::TransformBackfaceVisibilityHidden:
key = "CompositorAnimationWarningTransformBackfaceVisibilityHidden";
break;
case Type::TransformPreserve3D:
key = "CompositorAnimationWarningTransformPreserve3D";
break;
case Type::TransformSVG:
key = "CompositorAnimationWarningTransformSVG";
--- a/dom/animation/test/chrome/test_animation_performance_warning.html
+++ b/dom/animation/test/chrome/test_animation_performance_warning.html
@@ -870,19 +870,19 @@ function start() {
animation.effect.getProperties(),
[ { property: 'transform', runningOnCompositor: true } ]);
animation.effect.target.style = 'width: 10000px; height: 10000px';
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 bigger than the viewport \\(\\d+, \\d+\\) " +
- "or the visual rectangle \\(10000, 10000\\) is larger than the " +
- "maximum allowed value \\(\\d+\\)");
+ "\\(10000, 10000\\) 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(
animation.effect.getProperties(),
[ {
property: 'transform',
runningOnCompositor: false,
warning: expectedWarning
} ]);
animation.effect.target.style = 'width: 100px; height: 100px';
--- a/dom/locales/en-US/chrome/layout/layout_errors.properties
+++ b/dom/locales/en-US/chrome/layout/layout_errors.properties
@@ -9,22 +9,21 @@ ImageMapPolyWrongNumberOfCoords=The “coords” attribute of the <area shape="poly"> tag is not in the “x1,y1,x2,y2 …” format.
ImageMapPolyOddNumberOfCoords=The “coords” attribute of the <area shape="poly"> tag is missing the last “y” coordinate (the correct format is “x1,y1,x2,y2 …”).
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(CompositorAnimationWarningContentTooSmall):
## (%1$S, %2$S) is a pair of integer values of the frame size
CompositorAnimationWarningContentTooSmall=Animation cannot be run on the compositor because frame size (%1$S, %2$S) is smaller than (16, 16)
-## LOCALIZATION NOTE(CompositorAnimationWarningContentTooLarge):
+## 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 the viewport size
-## (%5$S, %6$S) is a pair of integer values of the visual rectangle size
-## (%7$S) is an integer value
-CompositorAnimationWarningContentTooLarge=Animation cannot be run on the compositor because the frame size (%1$S, %2$S) is bigger than the viewport (%3$S, %4$S) or the visual rectangle (%5$S, %6$S) is larger than the maximum allowed value (%7$S)
+## (%3$S, %4$S) is a pair of integer values of a limit based on the viewport size
+## (%5$S, %6$S) is a pair of integer values of an absolute limit
+CompositorAnimationWarningContentTooLarge2=Animation cannot be run on the compositor because the frame size (%1$S, %2$S) is too large relative to the viewport (larger than (%3$S, %4$S)) or larger than the maximum allowed value (%5$S, %6$S)
## LOCALIZATION NOTE(CompositorAnimationWarningTransformBackfaceVisibilityHidden):
## 'backface-visibility: hidden' is a CSS property, don't translate it.
CompositorAnimationWarningTransformBackfaceVisibilityHidden=Animations of ‘backface-visibility: hidden’ transforms cannot be run on the compositor
## LOCALIZATION NOTE(CompositorAnimationWarningTransformPreserve3D):
## 'transform-style: preserve-3d' is a CSS property, don't translate it.
CompositorAnimationWarningTransformPreserve3D=Animations of ‘transform-style: preserve-3d’ transforms cannot be run on the compositor
## LOCALIZATION NOTE(CompositorAnimationWarningTransformSVG,
## CompositorAnimationWarningTransformWithGeometricProperties,
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -523,16 +523,21 @@ private:
DECL_GFX_PREF(Once, "layers.tiles.edge-padding", TileEdgePaddingEnabled, bool, true);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.enabled", LayerTileFadeInEnabled, bool, false);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.duration-ms", LayerTileFadeInDuration, uint32_t, 250);
DECL_GFX_PREF(Live, "layers.transaction.warning-ms", LayerTransactionWarning, uint32_t, 200);
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, true);
DECL_GFX_PREF(Live, "layers.draw-mask-debug", DrawMaskLayer, bool, false);
+ DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-x", AnimationPrerenderViewportRatioLimitX, float, 1.125f);
+ DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-y", AnimationPrerenderViewportRatioLimitY, float, 1.125f);
+ DECL_GFX_PREF(Live, "layout.animation.prerender.absolute-limit-x", AnimationPrerenderAbsoluteLimitX, uint32_t, 4096);
+ DECL_GFX_PREF(Live, "layout.animation.prerender.absolute-limit-y", AnimationPrerenderAbsoluteLimitY, uint32_t, 4096);
+
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled", ScrollBehaviorEnabled, bool, true);
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.spring-constant", ScrollBehaviorSpringConstant, float, 250.0f);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-max-velocity", ScrollSnapPredictionMaxVelocity, int32_t, 2000);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-sensitivity", ScrollSnapPredictionSensitivity, float, 0.750f);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.proximity-threshold", ScrollSnapProximityThreshold, int32_t, 200);
DECL_GFX_PREF(Live, "layout.css.touch_action.enabled", TouchActionEnabled, bool, false);
DECL_GFX_PREF(Live, "layout.display-list.dump", LayoutDumpDisplayList, bool, false);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6169,49 +6169,49 @@ nsDisplayTransform::ShouldPrerenderTrans
EffectCompositor::SetPerformanceWarning(
aFrame, eCSSProperty_transform,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::TransformFrameInactive));
return NoPrerender;
}
+ float viewportRatioX = gfxPrefs::AnimationPrerenderViewportRatioLimitX();
+ float viewportRatioY = gfxPrefs::AnimationPrerenderViewportRatioLimitY();
+ uint32_t absoluteLimitX = gfxPrefs::AnimationPrerenderAbsoluteLimitX();
+ uint32_t absoluteLimitY = gfxPrefs::AnimationPrerenderAbsoluteLimitY();
nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
- // Only prerender if the transformed frame's size is <= the
- // reference frame size (~viewport), allowing a 1/8th fuzz factor
- // for shadows, borders, etc.
- refSize += nsSize(refSize.width / 8, refSize.height / 8);
+ // Only prerender if the transformed frame's size is <= a multiple of the
+ // reference frame size (~viewport), and less than an absolute limit.
+ // Both the ratio and the absolute limit are configurable.
+ nsSize relativeLimit(nscoord(refSize.width * viewportRatioX),
+ nscoord(refSize.height * viewportRatioY));
+ nsSize absoluteLimit(aFrame->PresContext()->DevPixelsToAppUnits(absoluteLimitX),
+ aFrame->PresContext()->DevPixelsToAppUnits(absoluteLimitY));
+ nsSize maxSize = Min(relativeLimit, absoluteLimit);
gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(aFrame);
nsRect overflow = aFrame->GetVisualOverflowRectRelativeToSelf();
nsSize frameSize = nsSize(overflow.Size().width * scale.width,
overflow.Size().height * scale.height);
- nscoord maxInAppUnits = nscoord_MAX;
- if (frameSize <= refSize) {
- maxInAppUnits = aFrame->PresContext()->DevPixelsToAppUnits(4096);
- if (frameSize <= nsSize(maxInAppUnits, maxInAppUnits)) {
- *aDirtyRect = overflow;
- return FullPrerender;
- }
- }
-
- nsRect visual = aFrame->GetVisualOverflowRect();
-
+ if (frameSize <= maxSize) {
+ *aDirtyRect = overflow;
+ return FullPrerender;
+ }
EffectCompositor::SetPerformanceWarning(
aFrame, eCSSProperty_transform,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::ContentTooLarge,
{
nsPresContext::AppUnitsToIntCSSPixels(frameSize.width),
nsPresContext::AppUnitsToIntCSSPixels(frameSize.height),
- nsPresContext::AppUnitsToIntCSSPixels(refSize.width),
- nsPresContext::AppUnitsToIntCSSPixels(refSize.height),
- nsPresContext::AppUnitsToIntCSSPixels(visual.width),
- nsPresContext::AppUnitsToIntCSSPixels(visual.height),
- nsPresContext::AppUnitsToIntCSSPixels(maxInAppUnits)
+ nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.width),
+ nsPresContext::AppUnitsToIntCSSPixels(relativeLimit.height),
+ nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.width),
+ nsPresContext::AppUnitsToIntCSSPixels(absoluteLimit.height),
}));
return NoPrerender;
}
/* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix)
{
if (aMatrix.IsSingular()) {
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2723,16 +2723,23 @@ pref("dom.animations-api.core.enabled",
// API) enabled?
// Note that if dom.animations-api.core.enabled is true, this preference is
// ignored.
pref("dom.animations-api.element-animate.enabled", true);
// Pref to throttle offsreen animations
pref("dom.animations.offscreen-throttling", true);
+// Prefs to control the maximum area to pre-render when animating a large
+// element on the compositor.
+pref("layout.animation.prerender.viewport-ratio-limit-x", "1.125");
+pref("layout.animation.prerender.viewport-ratio-limit-y", "1.125");
+pref("layout.animation.prerender.absolute-limit-x", 4096);
+pref("layout.animation.prerender.absolute-limit-y", 4096);
+
// pref to permit users to make verified SOAP calls by default
pref("capability.policy.default.SOAPCall.invokeVerifySourceHeader", "allAccess");
// if true, allow plug-ins to override internal imglib decoder mime types in full-page mode
pref("plugin.override_internal_types", false);
// See bug 136985. Gives embedders a pref to hook into to show
// a popup blocker if they choose.