Bug 1324591 - Store the corresponding LayersId for each animation on the compositor. r?kats draft
authorHiroyuki Ikezoe <hikezoe.birchill@mozilla.com>
Mon, 18 May 2020 09:27:20 +0900
changeset 3000248 d5f413ef9294e1a9d252deb485c0526841e3f640
parent 3000247 1565ea4eacd1867e2ffeb6702d4b35f73ecfdecd
child 3000249 b1593da16002b7d021c51c0c94cd5cd90cfd38d4
push id558657
push userhikezoe.birchill@mozilla.com
push dateWed, 24 Jun 2020 01:19:11 +0000
treeherdertry@bb059ebb3e19 [default view] [failures only]
reviewerskats
bugs1324591
milestone79.0a1
Bug 1324591 - Store the corresponding LayersId for each animation on the compositor. r?kats Differential Revision: https://phabricator.services.mozilla.com/D75728
gfx/layers/AnimationHelper.cpp
gfx/layers/AnimationHelper.h
gfx/layers/AnimationInfo.cpp
gfx/layers/AnimationInfo.h
gfx/layers/AnimationStorageData.h
gfx/layers/CompositorAnimationStorage.cpp
gfx/layers/CompositorAnimationStorage.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/wr/OMTASampler.cpp
gfx/layers/wr/OMTASampler.h
gfx/layers/wr/WebRenderBridgeParent.cpp
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -310,18 +310,19 @@ static bool HasTransformLikeAnimations(c
     }
   }
 
   return false;
 }
 #endif
 
 AnimationStorageData AnimationHelper::ExtractAnimations(
-    const AnimationArray& aAnimations) {
+    const LayersId& aLayersId, const AnimationArray& aAnimations) {
   AnimationStorageData storageData;
+  storageData.mLayersId = aLayersId;
 
   nsCSSPropertyID prevID = eCSSProperty_UNKNOWN;
   PropertyAnimationGroup* currData = nullptr;
   DebugOnly<const layers::Animatable*> currBaseStyle = nullptr;
 
   for (const Animation& animation : aAnimations) {
     // Animations with same property are grouped together, so we can just
     // check if the current property is the same as the previous one for
--- a/gfx/layers/AnimationHelper.h
+++ b/gfx/layers/AnimationHelper.h
@@ -110,17 +110,17 @@ class AnimationHelper {
    *     [ { transform, Animation A }, { transform, Animation B } ],
    *   ]
    *
    * In the process of grouping these animations, we also convert their values
    * from the rather compact representation we use for transferring across the
    * IPC boundary into something we can readily use for sampling.
    */
   static AnimationStorageData ExtractAnimations(
-      const AnimationArray& aAnimations);
+      const LayersId& aLayersId, const AnimationArray& aAnimations);
 
   /**
    * Get a unique id to represent the compositor animation between child
    * and parent side. This id will be used as a key to store animation
    * data in the CompositorAnimationStorage per compositor.
    * Each layer on the content side calls this when it gets new animation
    * data.
    */
--- a/gfx/layers/AnimationInfo.cpp
+++ b/gfx/layers/AnimationInfo.cpp
@@ -76,21 +76,22 @@ void AnimationInfo::ClearAnimationsForNe
   if (!mPendingAnimations) {
     mPendingAnimations = MakeUnique<AnimationArray>();
   }
 
   mPendingAnimations->Clear();
 }
 
 void AnimationInfo::SetCompositorAnimations(
+    const LayersId& aLayersId,
     const CompositorAnimations& aCompositorAnimations) {
   mCompositorAnimationsId = aCompositorAnimations.id();
 
-  mStorageData =
-      AnimationHelper::ExtractAnimations(aCompositorAnimations.animations());
+  mStorageData = AnimationHelper::ExtractAnimations(
+      aLayersId, aCompositorAnimations.animations());
 }
 
 bool AnimationInfo::StartPendingAnimations(const TimeStamp& aReadyTime) {
   bool updated = false;
   for (size_t animIdx = 0, animEnd = mAnimations.Length(); animIdx < animEnd;
        animIdx++) {
     Animation& anim = mAnimations[animIdx];
 
--- a/gfx/layers/AnimationInfo.h
+++ b/gfx/layers/AnimationInfo.h
@@ -72,30 +72,32 @@ class AnimationInfo final {
   Maybe<uint64_t> GetAnimationGeneration() const {
     return mAnimationGeneration;
   }
 
   // ClearAnimations clears animations on this layer.
   void ClearAnimations();
   void ClearAnimationsForNextTransaction();
   void SetCompositorAnimations(
+      const LayersId& aLayersId,
       const CompositorAnimations& aCompositorAnimations);
   bool StartPendingAnimations(const TimeStamp& aReadyTime);
   void TransferMutatedFlagToLayer(Layer* aLayer);
 
   uint64_t GetCompositorAnimationsId() { return mCompositorAnimationsId; }
   // Note: We don't set mAnimations on the compositor thread, so this will
   // always return an empty array on the compositor thread.
   AnimationArray& GetAnimations() { return mAnimations; }
   nsTArray<PropertyAnimationGroup>& GetPropertyAnimationGroups() {
     return mStorageData.mAnimation;
   }
   const Maybe<TransformData>& GetTransformData() const {
     return mStorageData.mTransformData;
   }
+  const LayersId& GetLayersId() const { return mStorageData.mLayersId; }
   bool ApplyPendingUpdatesForThisTransaction();
   bool HasTransformAnimation() const;
 
   gfx::Path* CachedMotionPath() { return mStorageData.mCachedMotionPath; }
 
   // In case of continuation, |aFrame| must be the first or the last
   // continuation frame, otherwise this function might return Nothing().
   static Maybe<uint64_t> GetGenerationFromFrame(
--- a/gfx/layers/AnimationStorageData.h
+++ b/gfx/layers/AnimationStorageData.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_AnimationStorageData_h
 #define mozilla_layers_AnimationStorageData_h
 
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/ComputedTimingFunction.h"  // for ComputedTimingFunction
 #include "mozilla/layers/LayersMessages.h"   // for TransformData, etc
+#include "mozilla/layers/LayersTypes.h"      // for LayersId
 #include "mozilla/TimeStamp.h"               // for TimeStamp
 #include "mozilla/TimingParams.h"
 #include "X11UndefineNone.h"
 
 namespace mozilla {
 
 namespace dom {
 enum class CompositeOperation : uint8_t;
@@ -70,16 +71,19 @@ struct PropertyAnimationGroup {
 struct AnimationStorageData {
   // Each entry in the array represents an animation list for one property.  For
   // transform-like properties (e.g. transform, rotate etc.), there may be
   // multiple entries depending on how many transform-like properties we have.
   nsTArray<PropertyAnimationGroup> mAnimation;
   Maybe<TransformData> mTransformData;
   // For motion path. We cached the gfx path for optimization.
   RefPtr<gfx::Path> mCachedMotionPath;
+  // This is used to communicate with the main-thread. E.g. to tell the fact
+  // that this animation needs to be pre-rendered again on the main-thread, etc.
+  LayersId mLayersId;
 
   AnimationStorageData() = default;
   AnimationStorageData(AnimationStorageData&& aOther) = default;
   AnimationStorageData& operator=(AnimationStorageData&& aOther) = default;
 
   // Avoid any copy because mAnimation could be a large array.
   AnimationStorageData(const AnimationStorageData& aOther) = delete;
   AnimationStorageData& operator=(const AnimationStorageData& aOther) = delete;
--- a/gfx/layers/CompositorAnimationStorage.cpp
+++ b/gfx/layers/CompositorAnimationStorage.cpp
@@ -132,22 +132,23 @@ void CompositorAnimationStorage::SetAnim
   }
 
   MOZ_ASSERT(aPreviousValue->Is<float>());
   MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
   aPreviousValue->SetOpacity(aOpacity);
 }
 
 void CompositorAnimationStorage::SetAnimations(uint64_t aId,
+                                               const LayersId& aLayersId,
                                                const AnimationArray& aValue) {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   MutexAutoLock lock(mLock);
 
   mAnimations[aId] = std::make_unique<AnimationStorageData>(
-      AnimationHelper::ExtractAnimations(aValue));
+      AnimationHelper::ExtractAnimations(aLayersId, aValue));
 }
 
 bool CompositorAnimationStorage::SampleAnimations(TimeStamp aPreviousFrameTime,
                                                   TimeStamp aCurrentFrameTime) {
   MutexAutoLock lock(mLock);
 
   bool isAnimating = false;
 
--- a/gfx/layers/CompositorAnimationStorage.h
+++ b/gfx/layers/CompositorAnimationStorage.h
@@ -116,17 +116,18 @@ class CompositorAnimationStorage final {
   /**
    * Collect all animations in this class as WebRender type properties.
    */
   WrAnimations CollectWebRenderAnimations() const;
 
   /**
    * Set the animations based on the unique id
    */
-  void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
+  void SetAnimations(uint64_t aId, const LayersId& aLayersId,
+                     const AnimationArray& aAnimations);
 
   /**
    * Sample animation based the given timestamps and store them in this
    * CompositorAnimationStorage. The animated values after sampling will be
    * stored in CompositorAnimationStorage as well.
    *
    * Returns true if there is any animation.
    * Note that even if there are only in-delay phase animations (i.e. not
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -182,22 +182,23 @@ Layer::Layer(LayerManager* aManager, voi
       mDebugColorIndex(0)
 #endif
 {
 }
 
 Layer::~Layer() = default;
 
 void Layer::SetCompositorAnimations(
+    const LayersId& aLayersId,
     const CompositorAnimations& aCompositorAnimations) {
   MOZ_LAYERS_LOG_IF_SHADOWABLE(
       this, ("Layer::Mutated(%p) SetCompositorAnimations with id=%" PRIu64,
              this, mAnimationInfo.GetCompositorAnimationsId()));
 
-  mAnimationInfo.SetCompositorAnimations(aCompositorAnimations);
+  mAnimationInfo.SetCompositorAnimations(aLayersId, aCompositorAnimations);
 
   Mutated();
 }
 
 void Layer::ClearCompositorAnimations() {
   MOZ_LAYERS_LOG_IF_SHADOWABLE(
       this, ("Layer::Mutated(%p) ClearCompositorAnimations with id=%" PRIu64,
              this, mAnimationInfo.GetCompositorAnimationsId()));
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1249,16 +1249,17 @@ class Layer {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(
           this, ("Layer::Mutated(%p) TransformIsPerspective", this));
       MutatedSimple();
     }
   }
   // This is only called when the layer tree is updated. Do not call this from
   // layout code.  To add an animation to this layer, use AddAnimation.
   void SetCompositorAnimations(
+      const LayersId& aLayersId,
       const CompositorAnimations& aCompositorAnimations);
   // Go through all animations in this layer and its children and, for
   // any animations with a null start time, update their start time such
   // that at |aReadyTime| the animation's current time corresponds to its
   // 'initial current time' value.
   void StartPendingAnimations(const TimeStamp& aReadyTime);
 
   void ClearCompositorAnimations();
@@ -1463,16 +1464,19 @@ class Layer {
     return mAnimationInfo.GetCompositorAnimationsId();
   }
   nsTArray<PropertyAnimationGroup>& GetPropertyAnimationGroups() {
     return mAnimationInfo.GetPropertyAnimationGroups();
   }
   const Maybe<TransformData>& GetTransformData() const {
     return mAnimationInfo.GetTransformData();
   }
+  const LayersId& GetAnimationLayersId() const {
+    return mAnimationInfo.GetLayersId();
+  }
 
   Maybe<uint64_t> GetAnimationGeneration() const {
     return mAnimationInfo.GetAnimationGeneration();
   }
 
   gfx::Path* CachedMotionPath() { return mAnimationInfo.CachedMotionPath(); }
 
   bool HasTransformAnimation() const;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -519,17 +519,17 @@ bool LayerTransactionParent::SetLayerAtt
     UpdateHitTestingTree(layer, "clip rect changed");
     layer->SetClipRect(clipRect);
   }
   if (LayerHandle maskLayer = common.maskLayer()) {
     layer->SetMaskLayer(AsLayer(maskLayer));
   } else {
     layer->SetMaskLayer(nullptr);
   }
-  layer->SetCompositorAnimations(common.compositorAnimations());
+  layer->SetCompositorAnimations(mId, common.compositorAnimations());
   // Clean up the Animations by id in the CompositorAnimationStorage
   // if there are no active animations on the layer
   if (mAnimStorage && layer->GetCompositorAnimationsId() &&
       layer->GetPropertyAnimationGroups().IsEmpty()) {
     mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
   }
   if (common.scrollMetadata() != layer->GetAllScrollMetadata()) {
     UpdateHitTestingTree(layer, "scroll metadata changed");
--- a/gfx/layers/wr/OMTASampler.cpp
+++ b/gfx/layers/wr/OMTASampler.cpp
@@ -149,21 +149,22 @@ void OMTASampler::SampleForTesting(const
     }
   }
 
   MutexAutoLock storageLock(mStorageLock);
   mAnimStorage->SampleAnimations(previousSampleTime, sampleTime);
 }
 
 void OMTASampler::SetAnimations(
-    uint64_t aId, const nsTArray<layers::Animation>& aAnimations) {
+    uint64_t aId, const LayersId& aLayersId,
+    const nsTArray<layers::Animation>& aAnimations) {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   MutexAutoLock lock(mStorageLock);
 
-  mAnimStorage->SetAnimations(aId, aAnimations);
+  mAnimStorage->SetAnimations(aId, aLayersId, aAnimations);
 }
 
 bool OMTASampler::HasAnimations() const {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   MutexAutoLock lock(mStorageLock);
 
   return mAnimStorage->HasAnimations();
 }
--- a/gfx/layers/wr/OMTASampler.h
+++ b/gfx/layers/wr/OMTASampler.h
@@ -61,17 +61,17 @@ class OMTASampler final {
    */
   void Sample(wr::TransactionWrapper& aTxn);
 
   /**
    * These funtions get called on the the compositor thread.
    */
   void SetSampleTime(const TimeStamp& aSampleTime);
   void ResetPreviousSampleTime();
-  void SetAnimations(uint64_t aId,
+  void SetAnimations(uint64_t aId, const LayersId& aLayersId,
                      const nsTArray<layers::Animation>& aAnimations);
   bool HasAnimations() const;
 
   /**
    * Clear AnimatedValues and Animations data, called on the compositor
    * thread.
    */
   void ClearActiveAnimations(
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -1382,17 +1382,17 @@ bool WebRenderBridgeParent::ProcessWebRe
         // AnimationHelper::GetNextCompositorAnimationsId() encodes the child
         // process PID in the upper 32 bits of the id, verify that this is as
         // expected.
         if ((data.id() >> 32) != (uint64_t)OtherPid()) {
           return false;
         }
         if (data.animations().Length()) {
           if (RefPtr<OMTASampler> sampler = GetOMTASampler()) {
-            sampler->SetAnimations(data.id(), data.animations());
+            sampler->SetAnimations(data.id(), GetLayersId(), data.animations());
             const auto activeAnim = mActiveAnimations.find(data.id());
             if (activeAnim == mActiveAnimations.end()) {
               mActiveAnimations.emplace(data.id(), mWrEpoch);
             } else {
               // Update wr::Epoch if the animation already exists.
               activeAnim->second = mWrEpoch;
             }
           }