--- 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;
}
}