Bug 1430884 - Throttle nsChangeHint_UpdateContainingBlock on invisible element. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 22 Jun 2018 13:27:20 +0900
changeset 809450 50a971162051a703f3f9ae12ed93041364c07aa7
parent 809449 907b0c2eea90d45454412c51ff13c33620ffe5db
child 809451 5587343fb5ac6f7245672351c47435c12657d712
push id113680
push userhikezoe@mozilla.com
push dateFri, 22 Jun 2018 04:33:20 +0000
reviewersbirtles
bugs1430884, 1470349
milestone62.0a1
Bug 1430884 - Throttle nsChangeHint_UpdateContainingBlock on invisible element. r?birtles When an animation for a CSS property which might cause a containing block for its descendants, the animation creates a containing block even if the property value doesn't create a stacking context, e.g. transform:none. So it doesn't matter that UpdateContainingBlock change hint doesn't happen during animation restyles, that means that we can throttle the change hint if the animating element isn't visible. Unfortuntely perspective animations start with 'none' don't create a containing block (bug 1470349), but it doesn't mean that the bug blocks us from doing this optimization because the bug happens regardless of the element visibility. MozReview-Commit-ID: 8rTl8dShHrD
dom/animation/test/mozilla/file_restyles.html
layout/base/nsChangeHint.h
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -1746,12 +1746,30 @@ waitForAllPaints(() => {
     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);
   });
 
+  add_task(async function restyling_transform_aimations_on_invisible_element() {
+    // 'opacity: 0' prevents transform animations to be sent to the compositor.
+    const div = addDiv(null, { style: 'visibility: hidden; opacity: 0' });
+
+    const animation =
+      div.animate({ transform: [ 'none', 'rotate(360deg)' ] },
+                  { duration: 100 * MS_PER_SEC,
+                    iterations: Infinity });
+
+    await waitForAnimationReadyToRestyle(animation);
+
+    const markers = await observeStyling(5);
+
+    is(markers.length, 0,
+       'Transform animations on visibility hidden 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_UpdateContainingBlock |        \
                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.