Bug 779598 - Don't try to send transform animations to the compositor if the display item is a transform separator. r?mattwoodrow draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Tue, 24 Jul 2018 13:12:25 +0900
changeset 821850 0afa946b8eb53e0ef9f04bbf4bd93e66eda9817a
parent 821849 4f04019f9555fc5f8b9e5c189ff42eb86b282001
child 821851 07ee873392ad5f2aebea34cda321bcb695938dbf
push id117200
push userhikezoe@mozilla.com
push dateTue, 24 Jul 2018 04:13:09 +0000
reviewersmattwoodrow
bugs779598
milestone63.0a1
Bug 779598 - Don't try to send transform animations to the compositor if the display item is a transform separator. r?mattwoodrow MozReview-Commit-ID: 72kMmcUHoJM
layout/painting/nsDisplayList.cpp
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8271,56 +8271,63 @@ nsDisplayTransform::CreateWebRenderComma
   gfx::Matrix4x4* transformForSC = &newTransformMatrix;
   if (newTransformMatrix.IsIdentity()) {
     // If the transform is an identity transform, strip it out so that WR
     // doesn't turn this stacking context into a reference frame, as it
     // affects positioning. Bug 1345577 tracks a better fix.
     transformForSC = nullptr;
   }
 
-  RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
-
-  AnimationInfo& animationInfo = animationData->GetAnimationInfo();
-  AddAnimationsForProperty(Frame(), aDisplayListBuilder,
-                           this, eCSSProperty_transform,
-                           animationInfo, false, true);
-  animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
-
-  // Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
-  // are no active animations.
-  uint64_t animationsId = animationInfo.GetCompositorAnimationsId();
+  uint64_t animationsId = 0;
   wr::WrAnimationProperty prop;
-  if (!animationInfo.GetAnimations().IsEmpty()) {
-    prop.id = animationsId;
-    prop.effect_type = wr::WrAnimationType::Transform;
-
-    OpAddCompositorAnimations
-      anim(CompositorAnimations(animationInfo.GetAnimations(), animationsId));
-    aManager->WrBridge()->AddWebRenderParentCommand(anim);
-    aManager->AddActiveCompositorAnimationId(animationsId);
-  } else if (animationsId) {
-    aManager->AddCompositorAnimationsIdForDiscard(animationsId);
-    animationsId = 0;
+
+  if (!mIsTransformSeparator) {
+    RefPtr<WebRenderAnimationData> animationData =
+      aManager->CommandBuilder()
+              .CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
+
+    AnimationInfo& animationInfo = animationData->GetAnimationInfo();
+    AddAnimationsForProperty(Frame(), aDisplayListBuilder,
+                             this, eCSSProperty_transform,
+                             animationInfo, false, true);
+    animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
+
+    // Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
+    // are no active animations.
+    animationsId = animationInfo.GetCompositorAnimationsId();
+    if (!animationInfo.GetAnimations().IsEmpty()) {
+      prop.id = animationsId;
+      prop.effect_type = wr::WrAnimationType::Transform;
+
+      OpAddCompositorAnimations
+        anim(CompositorAnimations(animationInfo.GetAnimations(), animationsId));
+      aManager->WrBridge()->AddWebRenderParentCommand(anim);
+      aManager->AddActiveCompositorAnimationId(animationsId);
+    } else if (animationsId) {
+      aManager->AddCompositorAnimationsIdForDiscard(animationsId);
+      animationsId = 0;
+    }
   }
 
   nsTArray<mozilla::wr::WrFilterOp> filters;
   Maybe<nsDisplayTransform*> deferredTransformItem;
   if (!mFrame->HasPerspective()) {
     // If it has perspective, we create a new scroll data via the
     // UpdateScrollData call because that scenario is more complex. Otherwise
     // we can just stash the transform on the StackingContextHelper and
     // apply it to any scroll data that are created inside this
     // nsDisplayTransform.
     deferredTransformItem = Some(this);
   }
 
   // If it looks like we're animated, we should rasterize in local space
   // (disabling subpixel-aa and global pixel snapping)
-  bool rasterizeLocally = ActiveLayerTracker::IsStyleMaybeAnimated(
-    Frame(), eCSSProperty_transform);
+  bool rasterizeLocally =
+    !mIsTransformSeparator &&
+    ActiveLayerTracker::IsStyleMaybeAnimated(Frame(), eCSSProperty_transform);
 
   StackingContextHelper sc(aSc,
                            aBuilder,
                            filters,
                            LayoutDeviceRect(position, LayoutDeviceSize()),
                            &newTransformMatrix,
                            animationsId ? &prop : nullptr,
                            nullptr,
@@ -8392,19 +8399,23 @@ already_AddRefed<Layer> nsDisplayTransfo
   } else {
     container->SetContentFlags(container->GetContentFlags() & ~Layer::CONTENT_EXTEND_3D_CONTEXT);
   }
 
   if (mAllowAsyncAnimation) {
     mFrame->SetProperty(nsIFrame::RefusedAsyncAnimationProperty(), false);
   }
 
-  nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
-                                                           this, mFrame,
-                                                           eCSSProperty_transform);
+  if (!mIsTransformSeparator) {
+    nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(
+      container, aBuilder,
+      this, mFrame,
+      eCSSProperty_transform);
+  }
+
   if (mAllowAsyncAnimation && MayBeAnimated(aBuilder)) {
     // Only allow async updates to the transform if we're an animated layer, since that's what
     // triggers us to set the correct AGR in the constructor and makes sure FrameLayerBuilder
     // won't compute occlusions for this layer.
     container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(),
                            /*the value is irrelevant*/nullptr);
     container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM);
   } else {