Bug 1430884 - Throttle animations producing nsChangeHint_UpdateOverflow change hint if the target element is not visible. r?birtles
In the case where the target element is scrolled out or visibility:hidden and
has no visible descendants, we can treat nsChangeHint_UpdateOverflow just like
transform animations which produce nsChangeHint_UpdatePostTransformOverflow,
i.e. unthrottle the animations periodically if the target element is inside a
scrollable element. Some transform animations produce UpdateOverflow hint,
so it would be really nice to optimize the hint.
MozReview-Commit-ID: E1MgPZRi8mW
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -441,18 +441,19 @@ private:
void UpdateEffectSet(mozilla::EffectSet* aEffectSet = nullptr) const;
// Returns true if this effect has properties that might affect the overflow
// region.
// This function is used for updating scroll bars or notifying intersection
// observers reflected by the transform.
bool HasPropertiesThatMightAffectOverflow() const
{
- return mCumulativeChangeHint & (nsChangeHint_UpdatePostTransformOverflow |
- nsChangeHint_AddOrRemoveTransform |
+ return mCumulativeChangeHint & (nsChangeHint_AddOrRemoveTransform |
+ nsChangeHint_UpdateOverflow |
+ nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_UpdateTransformLayer);
}
// Returns true if this effect causes visibility change.
// (i.e. 'visibility: hidden' -> 'visibility: visible' and vice versa.)
bool HasVisibilityChange() const
{
return mCumulativeChangeHint & nsChangeHint_VisibilityChange;
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -129,16 +129,17 @@ function waitForWheelEvent(aTarget) {
{ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaY: targetRect.height },
resolve);
});
}
const omtaEnabled = isOMTAEnabled();
+const isAndroid = !!navigator.userAgent.includes("Android");
const isWebRender =
SpecialPowers.DOMWindowUtils.layerManagerType == 'WebRender';
function add_task_if_omta_enabled(test) {
if (!omtaEnabled) {
info(test.name + " is skipped because OMTA is disabled");
return;
}
@@ -1726,12 +1727,36 @@ waitForAllPaints(() => {
const markers = await observeStyling(5);
is(markers.length, 5,
'Visibility animation running on the main-thread on in-view element ' +
'should not be throttled');
await ensureElementRemoval(div);
});
+ add_task(async function restyling_outline_offset_animations_on_invisible_element() {
+ if (isAndroid) {
+ // FIXME: Bug 1470798: Enable this test on Android.
+ return;
+ }
+ const div = addDiv(null,
+ { style: 'visibility: hidden; ' +
+ 'outline-style: solid; ' +
+ 'outline-width: 1px;' });
+ const animation =
+ div.animate({ outlineOffset: [ '0px', '10px' ] },
+ { duration: 100 * MS_PER_SEC,
+ iterations: Infinity });
+
+ await waitForAnimationReadyToRestyle(animation);
+
+ const markers = await observeStyling(5);
+
+ is(markers.length, 0,
+ 'Outline offset animation running on the main-thread on invisible ' +
+ 'element should be throttled');
+ await ensureElementRemoval(div);
+ });
+
});
</script>
</body>
--- a/layout/base/nsChangeHint.h
+++ b/layout/base/nsChangeHint.h
@@ -456,16 +456,17 @@ static_assert(!(nsChangeHint_Hints_Alway
#define NS_STYLE_HINT_REFLOW \
nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints)
#define nsChangeHint_Hints_CanIgnoreIfNotVisible \
nsChangeHint(NS_STYLE_HINT_VISUAL | \
nsChangeHint_NeutralChange | \
nsChangeHint_UpdateOpacityLayer | \
nsChangeHint_AddOrRemoveTransform | \
+ nsChangeHint_UpdateOverflow | \
nsChangeHint_UpdatePostTransformOverflow | \
nsChangeHint_UpdateTransformLayer | \
nsChangeHint_UpdateUsesOpacity | \
nsChangeHint_VisibilityChange)
// NB: Once we drop support for the old style system, this logic should be
// inlined in the Servo style system to eliminate the FFI call.
inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {