Bug 1430884 - Throttle nsChangeHint_UpdateContainingBlock on invisible element. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 22 Jun 2018 14:39:16 +0900
changeset 809462 f3188463cecce67b004b24192b8794c13ff528b4
parent 809461 1ee79e14f2191348d883366e7d2f6f61ef61e6b5
child 809463 0bd3d1928c6a4dc4d2d14be5211fc7daaf7c96e4
push id113685
push userhikezoe@mozilla.com
push dateFri, 22 Jun 2018 05:39:34 +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.