Bug 1518816 - Set the NS_FRAME_MAY_BE_TRANSFORMED bit for animations when we check for the EffectSet; r=hiro
authorBrian Birtles <birtles@gmail.com>
Mon, 18 Mar 2019 04:12:38 +0000
changeset 506557 93b549966e0af3cd63270e0d851feaa1199154c8
parent 506556 e7c2055118e59b47284ce16b1233f7697e982efb
child 506558 551c4286614374560dbff3ac3fc2a0f9de9b971e
push id138
push usermtabara@mozilla.com
push dateWed, 20 Mar 2019 18:12:49 +0000
reviewershiro
bugs1518816
milestone68.0a1
Bug 1518816 - Set the NS_FRAME_MAY_BE_TRANSFORMED bit for animations when we check for the EffectSet; r=hiro Currently the way we set the NS_FRAME_MAY_BE_TRANSFORMED frame bit for transform animations fails to take into account the primary/style frame distinction for display:table content. This patch moves setting that bit for animations to the point where we already have a handle on the appropriate EffectSet and already detect the primary/style frame distinction. This should be equivalent because: a) Although it is inside a branch that is only run when |mContent| is set, nsLayoutUtils::HasAnimationOfPropertySet will return false if the passed-in frame does not have associated content (see EffectCompositor::GetAnimationElementAndPseudoForFrame). b) EffectSet::MayHaveTransformAnimation() should be set if we have any transform animations in the EffectSet so this should be equivalent to querying nsLayoutUtils::HasAnimationOfPropertySet. The only other consideration is that this code is only executed when aPrevInFlow is nullptr. As a result, this patch also updates the branch where aPrevInFlow is set to copy the NS_FRAME_MAY_BE_TRANSFORMED bit in that case too. Differential Revision: https://phabricator.services.mozilla.com/D23636
layout/generic/nsFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -633,16 +633,17 @@ void nsFrame::Init(nsIContent* aContent,
     if (HasAnyStateBits(NS_FRAME_IN_POPUP) && TrackingVisibility()) {
       // Assume all frames in popups are visible.
       IncApproximateVisibleCount();
     }
   }
   if (aPrevInFlow) {
     mMayHaveOpacityAnimation = aPrevInFlow->MayHaveOpacityAnimation();
     mMayHaveTransformAnimation = aPrevInFlow->MayHaveTransformAnimation();
+    mState |= aPrevInFlow->mState & NS_FRAME_MAY_BE_TRANSFORMED;
   } else if (mContent) {
     // It's fine to fetch the EffectSet for the style frame here because in the
     // following code we take care of the case where animations may target
     // a different frame.
     EffectSet* effectSet = EffectSet::GetEffectSetForStyleFrame(this);
     if (effectSet) {
       mMayHaveOpacityAnimation = effectSet->MayHaveOpacityAnimation();
 
@@ -652,33 +653,32 @@ void nsFrame::Init(nsIContent* aContent,
         // frame).
         //
         // We do this when initializing the child frame (table inner frame),
         // because when initializng the table wrapper frame, we don't yet have
         // access to its children so we can't tell if we have transform
         // animations or not.
         if (IsFrameOfType(eSupportsCSSTransforms)) {
           mMayHaveTransformAnimation = true;
+          AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
         } else if (aParent && nsLayoutUtils::GetStyleFrame(aParent) == this) {
           MOZ_ASSERT(
               aParent->IsFrameOfType(eSupportsCSSTransforms),
               "Style frames that don't support transforms should have parents"
               " that do");
           aParent->mMayHaveTransformAnimation = true;
+          aParent->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
         }
       }
     }
   }
 
   const nsStyleDisplay* disp = StyleDisplay();
-  if (disp->HasTransform(this) ||
-      (IsFrameOfType(eSupportsCSSTransforms) &&
-       nsLayoutUtils::HasAnimationOfPropertySet(
-           this, nsCSSPropertyIDSet::TransformLikeProperties()))) {
-    // The frame gets reconstructed if we toggle the -moz-transform
+  if (disp->HasTransform(this)) {
+    // The frame gets reconstructed if we toggle the transform
     // property, so we can set this bit here and then ignore it.
     AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
   }
   if (disp->mPosition == NS_STYLE_POSITION_STICKY && !aPrevInFlow &&
       !(mState & NS_FRAME_IS_NONDISPLAY)) {
     // Note that we only add first continuations, but we really only
     // want to add first continuation-or-ib-split-siblings.  But since we
     // don't yet know if we're a later part of a block-in-inline split,