--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3636,36 +3636,37 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMEle
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame,
nsDisplayItem::TYPE_OPACITY);
if (layer) {
ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
if (forwarder && forwarder->HasShadowManager()) {
float value;
bool hadAnimatedOpacity;
- forwarder->GetShadowManager()->SendGetAnimationOpacity(
- layer->AsShadowableLayer()->GetShadow(),
- &value, &hadAnimatedOpacity);
+ forwarder->GetShadowManager()->
+ SendGetAnimationOpacity(layer->GetCompositorAnimationsId(),
+ &value,
+ &hadAnimatedOpacity);
if (hadAnimatedOpacity) {
cssValue = new nsROCSSPrimitiveValue;
cssValue->SetNumber(value);
}
}
}
} else if (aProperty.EqualsLiteral("transform")) {
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame,
nsDisplayItem::TYPE_TRANSFORM);
if (layer) {
ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
if (forwarder && forwarder->HasShadowManager()) {
MaybeTransform transform;
- forwarder->GetShadowManager()->SendGetAnimationTransform(
- layer->AsShadowableLayer()->GetShadow(), &transform);
+ forwarder->GetShadowManager()->
+ SendGetAnimationTransform(layer->GetCompositorAnimationsId(), &transform);
if (transform.type() == MaybeTransform::TMatrix4x4) {
Matrix4x4 matrix = transform.get_Matrix4x4();
cssValue = nsComputedDOMStyle::MatrixToCSSValue(matrix);
}
}
}
}
}
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -4,28 +4,80 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AnimationHelper.h"
#include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for dom::FillMode
#include "mozilla/dom/KeyframeEffectBinding.h" // for dom::IterationComposite
#include "mozilla/dom/KeyframeEffectReadOnly.h" // for dom::KeyFrameEffectReadOnly
+#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
-#include "mozilla/layers/LayersMessages.h" // for TransformFunction, etc
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
namespace mozilla {
namespace layers {
struct StyleAnimationValueCompositePair {
StyleAnimationValue mValue;
dom::CompositeOperation mComposite;
};
+void
+CompositorAnimationStorage::Clear()
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+
+ mAnimatedValues.Clear();
+ mAnimations.Clear();
+
+}
+
+AnimatedValue*
+CompositorAnimationStorage::GetAnimatedValue(const uint64_t& aId) const
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ return mAnimatedValues.Get(aId);
+}
+
+void
+CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
+ gfx::Matrix4x4&& aTransformInDevSpace,
+ gfx::Matrix4x4&& aFrameTransform,
+ const TransformData& aData)
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ AnimatedValue* value = new AnimatedValue(Move(aTransformInDevSpace), Move(aFrameTransform), aData);
+ mAnimatedValues.Put(aId, value);
+}
+
+void
+CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
+ const float& aOpacity)
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ AnimatedValue* value = new AnimatedValue(aOpacity);
+ mAnimatedValues.Put(aId, value);
+}
+
+AnimationArray*
+CompositorAnimationStorage::GetAnimations(const uint64_t& aId) const
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ return mAnimations.Get(aId);
+}
+
+void
+CompositorAnimationStorage::SetAnimations(uint64_t aId, const AnimationArray& aValue)
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ AnimationArray* value = new AnimationArray(aValue);
+ mAnimations.Put(aId, value);
+}
+
static StyleAnimationValue
SampleValue(float aPortion, const layers::Animation& aAnimation,
const StyleAnimationValueCompositePair& aStart,
const StyleAnimationValueCompositePair& aEnd,
const StyleAnimationValue& aLastValue,
uint64_t aCurrentIteration,
const StyleAnimationValue& aUnderlyingValue)
{
--- a/gfx/layers/AnimationHelper.h
+++ b/gfx/layers/AnimationHelper.h
@@ -3,36 +3,135 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_AnimationHelper_h
#define mozilla_layers_AnimationHelper_h
#include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
+#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
#include "mozilla/TimeStamp.h" // for TimeStamp
namespace mozilla {
- class StyleAnimationValue;
+class StyleAnimationValue;
namespace layers {
class Animation;
typedef InfallibleTArray<layers::Animation> AnimationArray;
struct AnimData {
InfallibleTArray<mozilla::StyleAnimationValue> mStartValues;
InfallibleTArray<mozilla::StyleAnimationValue> mEndValues;
InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
};
+struct AnimationTransform {
+ /*
+ * This transform is calculated from sampleanimation in device pixel
+ * and used by compositor.
+ */
+ gfx::Matrix4x4 mTransformInDevSpace;
+ /*
+ * This transform is calculated from frame and used by getOMTAStyle()
+ * for OMTA testing.
+ */
+ gfx::Matrix4x4 mFrameTransform;
+ TransformData mData;
+};
+
+struct AnimatedValue {
+ enum {
+ TRANSFORM,
+ OPACITY,
+ NONE
+ } mType {NONE};
+
+ union {
+ AnimationTransform mTransform;
+ float mOpacity;
+ };
+
+ AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
+ gfx::Matrix4x4&& aFrameTransform,
+ const TransformData& aData)
+ : mType(AnimatedValue::TRANSFORM)
+ {
+ mTransform.mTransformInDevSpace = Move(aTransformInDevSpace);
+ mTransform.mFrameTransform = Move(aFrameTransform);
+ mTransform.mData = aData;
+ }
+
+ explicit AnimatedValue(const float& aValue)
+ : mType(AnimatedValue::OPACITY)
+ , mOpacity(aValue)
+ {
+ }
+
+ ~AnimatedValue() {}
+
+private:
+ AnimatedValue() = delete;
+};
+
+// CompositorAnimationStorage stores the layer animations and animated value
+// after sampling based on an unique id (CompositorAnimationsId)
+class CompositorAnimationStorage final
+{
+ typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
+ typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable;
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
+public:
+
+ /**
+ * Set the animation transform based on the unique id
+ */
+ void SetAnimatedValue(uint64_t aId,
+ gfx::Matrix4x4&& aTransformInDevSpace,
+ gfx::Matrix4x4&& aFrameTransform,
+ const TransformData& aData);
+
+ /**
+ * Set the animation opacity based on the unique id
+ */
+ void SetAnimatedValue(uint64_t aId, const float& aOpacity);
+
+ /**
+ * Return the animated value if a given id can map to its animated value
+ */
+ AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
+
+ /**
+ * Set the animations based on the unique id
+ */
+ void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
+
+ /**
+ * Return the animations if a given id can map to its animations
+ */
+ AnimationArray* GetAnimations(const uint64_t& aId) const;
+
+ /**
+ * Clear AnimatedValues and Animations data
+ */
+ void Clear();
+
+private:
+ ~CompositorAnimationStorage() { Clear(); };
+
+private:
+ AnimatedValueTable mAnimatedValues;
+ AnimationsTable mAnimations;
+};
+
class AnimationHelper
{
public:
-
static bool
SampleAnimationForEachNode(TimeStamp aPoint,
AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimationData,
StyleAnimationValue& aAnimationValue,
bool& aHasInEffectAnimations);
static void
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -62,22 +62,24 @@ IsSameDimension(dom::ScreenOrientationIn
}
static bool
ContentMightReflowOnOrientationChange(const IntRect& rect)
{
return rect.width != rect.height;
}
-AsyncCompositionManager::AsyncCompositionManager(HostLayerManager* aManager)
+ AsyncCompositionManager::AsyncCompositionManager(CompositorBridgeParent* aParent,
+ HostLayerManager* aManager)
: mLayerManager(aManager)
, mIsFirstPaint(true)
, mLayersUpdated(false)
, mPaintSyncId(0)
, mReadyForCompose(true)
+ , mCompositorBridge(aParent)
{
}
AsyncCompositionManager::~AsyncCompositionManager()
{
}
void
@@ -571,101 +573,116 @@ AsyncCompositionManager::AlignFixedAndSt
}
}
return;
}
static void
ApplyAnimatedValue(Layer* aLayer,
+ CompositorAnimationStorage* aStorage,
nsCSSPropertyID aProperty,
const AnimationData& aAnimationData,
const StyleAnimationValue& aValue)
{
if (aValue.IsNull()) {
// Return gracefully if we have no valid StyleAnimationValue.
return;
}
HostLayer* layerCompositor = aLayer->AsHostLayer();
switch (aProperty) {
case eCSSProperty_opacity: {
MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Float,
"Interpolated value for opacity should be float");
layerCompositor->SetShadowOpacity(aValue.GetFloatValue());
layerCompositor->SetShadowOpacitySetByAnimation(true);
+ aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(),
+ aValue.GetFloatValue());
+
break;
}
case eCSSProperty_transform: {
MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Transform,
"The unit of interpolated value for transform should be "
"transform");
nsCSSValueSharedList* list = aValue.GetCSSValueSharedListValue();
const TransformData& transformData = aAnimationData.get_TransformData();
nsPoint origin = transformData.origin();
// we expect all our transform data to arrive in device pixels
Point3D transformOrigin = transformData.transformOrigin();
nsDisplayTransform::FrameTransformProperties props(list,
transformOrigin);
+ Matrix4x4 transform =
+ nsDisplayTransform::GetResultingTransformMatrix(props, origin,
+ transformData.appUnitsPerDevPixel(),
+ 0, &transformData.bounds());
+ Matrix4x4 frameTransform = transform;
+
// If our parent layer is a perspective layer, then the offset into reference
// frame coordinates is already on that layer. If not, then we need to ask
// for it to be added here.
- uint32_t flags = 0;
if (!aLayer->GetParent() ||
!aLayer->GetParent()->GetTransformIsPerspective()) {
- flags = nsDisplayTransform::OFFSET_BY_ORIGIN;
+ nsLayoutUtils::PostTranslate(transform, origin,
+ transformData.appUnitsPerDevPixel(),
+ true);
}
- Matrix4x4 transform =
- nsDisplayTransform::GetResultingTransformMatrix(props, origin,
- transformData.appUnitsPerDevPixel(),
- flags, &transformData.bounds());
-
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
transform.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
}
+
layerCompositor->SetShadowBaseTransform(transform);
layerCompositor->SetShadowTransformSetByAnimation(true);
+ aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(),
+ Move(transform), Move(frameTransform),
+ transformData);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
}
}
static bool
-SampleAnimations(Layer* aLayer, TimeStamp aPoint, uint64_t* aLayerAreaAnimated)
+SampleAnimations(Layer* aLayer,
+ CompositorAnimationStorage* aStorage,
+ TimeStamp aPoint,
+ uint64_t* aLayerAreaAnimated)
{
bool activeAnimations = false;
ForEachNode<ForwardIterator>(
aLayer,
- [&activeAnimations, &aPoint, &aLayerAreaAnimated] (Layer* layer)
+ [aStorage, &activeAnimations, &aPoint, &aLayerAreaAnimated] (Layer* layer)
{
bool hasInEffectAnimations = false;
StyleAnimationValue animationValue = layer->GetBaseAnimationStyle();
activeAnimations |=
AnimationHelper::SampleAnimationForEachNode(aPoint,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,
hasInEffectAnimations);
if (hasInEffectAnimations) {
Animation& animation = layer->GetAnimations().LastElement();
ApplyAnimatedValue(layer,
+ aStorage,
animation.property(),
animation.data(),
animationValue);
if (aLayerAreaAnimated) {
*aLayerAreaAnimated += (layer->GetVisibleRegion().Area());
}
}
});
+
return activeAnimations;
}
static bool
SampleAPZAnimations(const LayerMetricsWrapper& aLayer, TimeStamp aSampleTime)
{
bool activeAnimations = false;
@@ -1302,31 +1319,43 @@ AsyncCompositionManager::TransformShadow
PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree",
js::ProfileEntry::Category::GRAPHICS);
Layer* root = mLayerManager->GetRoot();
if (!root) {
return false;
}
+ // GetAnimationStorage in CompositorBridgeParent expects id as 0
+ CompositorAnimationStorage* storage =
+ mCompositorBridge->GetAnimationStorage(0);
// First, compute and set the shadow transforms from OMT animations.
// NB: we must sample animations *before* sampling pan/zoom
// transforms.
// Use a previous vsync time to make main thread animations and compositor
// more in sync with each other.
// On the initial frame we use aVsyncTimestamp here so the timestamp on the
// second frame are the same as the initial frame, but it does not matter.
uint64_t layerAreaAnimated = 0;
- bool wantNextFrame = SampleAnimations(root,
- !mPreviousFrameTimeStamp.IsNull() ?
- mPreviousFrameTimeStamp : aCurrentFrame,
- &layerAreaAnimated);
+ bool wantNextFrame =
+ SampleAnimations(root,
+ storage,
+ !mPreviousFrameTimeStamp.IsNull() ?
+ mPreviousFrameTimeStamp : aCurrentFrame,
+ &layerAreaAnimated);
+
mAnimationMetricsTracker.UpdateAnimationInProgress(
wantNextFrame, layerAreaAnimated);
+ if (!wantNextFrame) {
+ // Clean up the CompositorAnimationStorage because
+ // there are no active animations running
+ storage->Clear();
+ }
+
// Reset the previous time stamp if we don't already have any running
// animations to avoid using the time which is far behind for newly
// started animations.
mPreviousFrameTimeStamp = wantNextFrame ? aCurrentFrame : TimeStamp();
if (!(aSkip & TransformsToSkip::APZ)) {
// FIXME/bug 775437: unify this interface with the ~native-fennec
// derived code
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -66,17 +66,17 @@ struct AsyncTransform {
class AsyncCompositionManager final
{
friend class AutoResolveRefLayers;
~AsyncCompositionManager();
public:
NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager)
- explicit AsyncCompositionManager(HostLayerManager* aManager);
+ explicit AsyncCompositionManager(CompositorBridgeParent* aParent, HostLayerManager* aManager);
/**
* This forces the is-first-paint flag to true. This is intended to
* be called by the widget code when it loses its viewport information
* (or for whatever reason wants to refresh the viewport information).
* The information refresh happens because the compositor will call
* SetFirstPaintViewport on the next frame of composition.
*/
@@ -236,16 +236,18 @@ private:
bool mReadyForCompose;
gfx::Matrix mWorldTransform;
LayerTransformRecorder mLayerTransformRecorder;
TimeStamp mPreviousFrameTimeStamp;
AnimationMetricsTracker mAnimationMetricsTracker;
+ CompositorBridgeParent* mCompositorBridge;
+
#ifdef MOZ_WIDGET_ANDROID
// The following two fields are only needed on Fennec with C++ APZ, because
// then we need to reposition the gecko scrollbar to deal with the
// dynamic toolbar shifting content around.
FrameMetrics::ViewID mRootScrollableId;
ScreenMargin mFixedLayerMargins;
#endif
};
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -30,16 +30,17 @@
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/GPUChild.h" // for GfxPrefValue
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Rect.h" // for IntSize
#include "mozilla/gfx/gfxVars.h" // for gfxVars
#include "VRManager.h" // for VRManager
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/gfx/gfxVars.h"
+#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager
#include "mozilla/layers/AsyncCompositionManager.h"
#include "mozilla/layers/BasicCompositor.h" // for BasicCompositor
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorThread.h"
@@ -315,16 +316,17 @@ CompositorBridgeParent::CompositorBridge
, mPauseCompositionMonitor("PauseCompositionMonitor")
, mResumeCompositionMonitor("ResumeCompositionMonitor")
, mResetCompositorMonitor("ResetCompositorMonitor")
, mRootLayerTreeID(0)
, mOverrideComposeReadiness(false)
, mForceCompositionTask(nullptr)
, mCompositorThreadHolder(CompositorThreadHolder::GetSingleton())
, mCompositorScheduler(nullptr)
+ , mAnimationStorage(nullptr)
, mPaintTime(TimeDuration::Forever())
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
, mLastPluginUpdateLayerTreeId(0)
, mDeferPluginWindows(false)
, mPluginWindowsHidden(false)
#endif
{
// Always run destructor on the main thread
@@ -634,16 +636,17 @@ CompositorBridgeParent::RecvNotifyApprox
void
CompositorBridgeParent::ActorDestroy(ActorDestroyReason why)
{
StopAndClearResources();
RemoveCompositor(mCompositorID);
mCompositionManager = nullptr;
+ mAnimationStorage = nullptr;
if (mApzcTreeManager) {
mApzcTreeManager->ClearTree();
mApzcTreeManager = nullptr;
}
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
@@ -1294,16 +1297,27 @@ CompositorBridgeParent::ApplyAsyncProper
CancelCurrentCompositeTask();
// Pretend we composited in case someone is waiting for this event.
TimeStamp now = TimeStamp::Now();
DidComposite(now, now);
}
}
}
+CompositorAnimationStorage*
+CompositorBridgeParent::GetAnimationStorage(const uint64_t& aId)
+{
+ MOZ_ASSERT(aId == 0);
+
+ if (!mAnimationStorage) {
+ mAnimationStorage = new CompositorAnimationStorage();
+ }
+ return mAnimationStorage;
+}
+
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
{
mCompositionManager->GetFrameUniformity(aOutData);
return IPC_OK();
}
void
@@ -1452,17 +1466,17 @@ CompositorBridgeParent::AllocPLayerTrans
if (!mLayerManager) {
NS_WARNING("Failed to initialise Compositor");
*aSuccess = false;
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
p->AddIPDLReference();
return p;
}
- mCompositionManager = new AsyncCompositionManager(mLayerManager);
+ mCompositionManager = new AsyncCompositionManager(this, mLayerManager);
*aSuccess = true;
*aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier();
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
p->AddIPDLReference();
return p;
}
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -59,16 +59,17 @@ class Shmem;
} // namespace ipc
namespace layers {
class APZCTreeManager;
class APZCTreeManagerParent;
class AsyncCompositionManager;
class Compositor;
+class CompositorAnimationStorage;
class CompositorBridgeParent;
class CompositorVsyncScheduler;
class HostLayerManager;
class LayerTransactionParent;
class PAPZParent;
class CrossProcessCompositorBridgeParent;
class CompositorThreadHolder;
class InProcessCompositorSession;
@@ -100,16 +101,17 @@ public:
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) { }
virtual void ForceComposite(LayerTransactionParent* aLayerTree) { }
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) { return true; }
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree) = 0;
+ virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) { return nullptr; }
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) = 0;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) { }
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) {}
@@ -222,16 +224,17 @@ public:
const TransactionInfo& aInfo,
bool aHitTestUpdate) override;
virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) override;
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
override;
+ virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) override;
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) override;
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) override;
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) override { return mCompositionManager; }
@@ -592,16 +595,17 @@ protected:
RefPtr<APZCTreeManager> mApzcTreeManager;
RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
// This makes sure the compositorParent is not destroyed before receiving
// confirmation that the channel is closed.
// mSelfRef is cleared in DeferredDestroy which is scheduled by ActorDestroy.
RefPtr<CompositorBridgeParent> mSelfRef;
+ RefPtr<CompositorAnimationStorage> mAnimationStorage;
TimeDuration mPaintTime;
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
// cached plugin data used to reduce the number of updates we request.
uint64_t mLastPluginUpdateLayerTreeId;
nsIntPoint mPluginsLayerOffset;
nsIntRegion mPluginsLayerVisibleRegion;
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -6,16 +6,17 @@
#include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
#include <stdint.h> // for uint64_t
#include "LayerTransactionParent.h" // for LayerTransactionParent
#include "base/message_loop.h" // for MessageLoop
#include "base/task.h" // for CancelableTask, etc
#include "base/thread.h" // for Thread
#include "mozilla/ipc/Transport.h" // for Transport
+#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager
#include "mozilla/layers/AsyncCompositionManager.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h"
@@ -402,16 +403,32 @@ CrossProcessCompositorBridgeParent::Appl
if (!state) {
return;
}
MOZ_ASSERT(state->mParent);
state->mParent->ApplyAsyncProperties(aLayerTree);
}
+CompositorAnimationStorage*
+CrossProcessCompositorBridgeParent::GetAnimationStorage(
+ const uint64_t& aId)
+{
+ MOZ_ASSERT(aId != 0);
+ const CompositorBridgeParent::LayerTreeState* state =
+ CompositorBridgeParent::GetIndirectShadowTree(aId);
+ if (!state) {
+ return nullptr;
+ }
+
+ MOZ_ASSERT(state->mParent);
+ // GetAnimationStorage in CompositorBridgeParent expects id as 0
+ return state->mParent->GetAnimationStorage(0);
+}
+
void
CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
const CompositorBridgeParent::LayerTreeState* state =
CompositorBridgeParent::GetIndirectShadowTree(id);
if (!state) {
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -9,16 +9,17 @@
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
namespace mozilla {
namespace layers {
class CompositorOptions;
+class CompositorAnimationStorage;
/**
* This class handles layer updates pushed directly from child processes to
* the compositor thread. It's associated with a CompositorBridgeParent on the
* compositor thread. While it uses the PCompositorBridge protocol to manage
* these updates, it doesn't actually drive compositing itself. For that it
* hands off work to the CompositorBridgeParent it's associated with.
*/
@@ -100,16 +101,18 @@ public:
bool aHitTestUpdate) override;
virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) override;
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) override;
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
override;
+ virtual CompositorAnimationStorage*
+ GetAnimationStorage(const uint64_t& aId) override;
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) override;
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) override;
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -10,16 +10,17 @@
#include "apz/src/AsyncPanZoomController.h"
#include "CompositableHost.h" // for CompositableParent, Get, etc
#include "ImageLayers.h" // for ImageLayer
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "CompositableTransactionParent.h" // for EditReplyVector
#include "CompositorBridgeParent.h"
#include "gfxPrefs.h"
#include "mozilla/gfx/BasePoint3D.h" // for BasePoint3D
+#include "mozilla/layers/AnimationHelper.h" // for GetAnimatedPropValue
#include "mozilla/layers/CanvasLayerComposite.h"
#include "mozilla/layers/ColorLayerComposite.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/ContainerLayerComposite.h"
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
#include "mozilla/layers/ImageLayerComposite.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc
@@ -690,104 +691,77 @@ LayerTransactionParent::RecvSetTestSampl
mozilla::ipc::IPCResult
LayerTransactionParent::RecvLeaveTestMode()
{
mCompositorBridge->LeaveTestMode(this);
return IPC_OK();
}
mozilla::ipc::IPCResult
-LayerTransactionParent::RecvGetAnimationOpacity(const LayerHandle& aParent,
+LayerTransactionParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnimationsId,
float* aOpacity,
bool* aHasAnimationOpacity)
{
*aHasAnimationOpacity = false;
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return IPC_FAIL_NO_REASON(this);
}
- RefPtr<Layer> layer = AsLayer(aParent);
- if (!layer) {
+ mCompositorBridge->ApplyAsyncProperties(this);
+
+ CompositorAnimationStorage* storage =
+ mCompositorBridge->GetAnimationStorage(GetId());
+
+ if (!storage) {
return IPC_FAIL_NO_REASON(this);
}
- mCompositorBridge->ApplyAsyncProperties(this);
+ auto value = storage->GetAnimatedValue(aCompositorAnimationsId);
- if (!layer->AsHostLayer()->GetShadowOpacitySetByAnimation()) {
+ if (!value || value->mType != AnimatedValue::OPACITY) {
return IPC_OK();
}
- *aOpacity = layer->GetLocalOpacity();
+ *aOpacity = value->mOpacity;
*aHasAnimationOpacity = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
-LayerTransactionParent::RecvGetAnimationTransform(const LayerHandle& aLayerHandle,
+LayerTransactionParent::RecvGetAnimationTransform(const uint64_t& aCompositorAnimationsId,
MaybeTransform* aTransform)
{
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return IPC_FAIL_NO_REASON(this);
}
- Layer* layer = AsLayer(aLayerHandle);
- if (!layer) {
- return IPC_FAIL_NO_REASON(this);
- }
-
// Make sure we apply the latest animation style or else we can end up with
// a race between when we temporarily clear the animation transform (in
// CompositorBridgeParent::SetShadowProperties) and when animation recalculates
// the value.
mCompositorBridge->ApplyAsyncProperties(this);
- // This method is specific to transforms applied by animation.
- // This is because this method uses the information stored with an animation
- // such as the origin of the reference frame corresponding to the layer, to
- // recover the untranslated transform from the shadow transform. For
- // transforms that are not set by animation we don't have this information
- // available.
- if (!layer->AsHostLayer()->GetShadowTransformSetByAnimation()) {
+ CompositorAnimationStorage* storage =
+ mCompositorBridge->GetAnimationStorage(GetId());
+
+ if (!storage) {
+ return IPC_FAIL_NO_REASON(this);
+ }
+
+ auto value = storage->GetAnimatedValue(aCompositorAnimationsId);
+
+ if (!value || value->mType != AnimatedValue::TRANSFORM) {
*aTransform = mozilla::void_t();
return IPC_OK();
}
- // The following code recovers the untranslated transform
- // from the shadow transform by undoing the translations in
- // AsyncCompositionManager::SampleValue.
-
- Matrix4x4 transform = layer->AsHostLayer()->GetShadowBaseTransform();
- if (ContainerLayer* c = layer->AsContainerLayer()) {
- // Undo the scale transform applied by AsyncCompositionManager::SampleValue
- transform.PostScale(1.0f/c->GetInheritedXScale(),
- 1.0f/c->GetInheritedYScale(),
- 1.0f);
- }
- float scale = 1;
- Point3D scaledOrigin;
- Point3D transformOrigin;
- for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) {
- if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) {
- const TransformData& data = layer->GetAnimations()[i].data().get_TransformData();
- scale = data.appUnitsPerDevPixel();
- scaledOrigin =
- Point3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
- NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
- 0.0f);
- transformOrigin = data.transformOrigin();
- break;
- }
- }
-
- // If our parent isn't a perspective layer, then the offset into reference
- // frame coordinates will have been applied to us. Add an inverse translation
- // to cancel it out.
- if (!layer->GetParent() || !layer->GetParent()->GetTransformIsPerspective()) {
- transform.PostTranslate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z);
- }
+ Matrix4x4 transform = value->mTransform.mFrameTransform;
+ const TransformData& data = value->mTransform.mData;
+ float scale = data.appUnitsPerDevPixel();
+ Point3D transformOrigin = data.transformOrigin();
// Undo the rebasing applied by
// nsDisplayTransform::GetResultingTransformMatrixInternal
transform.ChangeBasis(-transformOrigin);
// Convert to CSS pixels (this undoes the operations performed by
// nsStyleTransformMatrix::ProcessTranslatePart which is called from
// nsDisplayTransform::GetResultingTransformMatrix)
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -120,20 +120,20 @@ protected:
const TextureInfo& aInfo) override;
virtual mozilla::ipc::IPCResult RecvReleaseLayer(const LayerHandle& aHandle) override;
virtual mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
virtual mozilla::ipc::IPCResult RecvClearCachedResources() override;
virtual mozilla::ipc::IPCResult RecvForceComposite() override;
virtual mozilla::ipc::IPCResult RecvSetTestSampleTime(const TimeStamp& aTime) override;
virtual mozilla::ipc::IPCResult RecvLeaveTestMode() override;
- virtual mozilla::ipc::IPCResult RecvGetAnimationOpacity(const LayerHandle& aLayerHandle,
+ virtual mozilla::ipc::IPCResult RecvGetAnimationOpacity(const uint64_t& aCompositorAnimationsId,
float* aOpacity,
bool* aHasAnimationOpacity) override;
- virtual mozilla::ipc::IPCResult RecvGetAnimationTransform(const LayerHandle& aLayerHandle,
+ virtual mozilla::ipc::IPCResult RecvGetAnimationTransform(const uint64_t& aCompositorAnimationsId,
MaybeTransform* aTransform)
override;
virtual mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aId,
const float& aX, const float& aY) override;
virtual mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aId,
const float& aValue) override;
virtual mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
virtual mozilla::ipc::IPCResult RecvGetAPZTestData(APZTestData* aOutData) override;
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -76,25 +76,25 @@ parent:
// animations. sampleTime must not be null.
sync SetTestSampleTime(TimeStamp sampleTime);
// Leave test mode and resume normal compositing
sync LeaveTestMode();
// Returns the value of the opacity applied to the layer by animation.
// |hasAnimationOpacity| is true if the layer has an opacity value
// specified by animation. If it's false, |opacity| value is indefinite.
- sync GetAnimationOpacity(LayerHandle layer) returns (float opacity,
+ sync GetAnimationOpacity(uint64_t aCompositorAnimationsId) returns (float opacity,
bool hasAnimationOpacity);
// Returns the value of the transform applied to the layer by animation after
// factoring out translation components introduced to account for the offset
// of the corresponding frame and transform origin and after converting to CSS
// pixels. If the layer is not transformed by animation, the return value will
// be void_t.
- sync GetAnimationTransform(LayerHandle layer) returns (MaybeTransform transform);
+ sync GetAnimationTransform(uint64_t aCompositorAnimationId) returns (MaybeTransform transform);
// The next time the layer tree is composited, add this async scroll offset in
// CSS pixels for the given ViewID.
// Useful for testing rendering of async scrolling.
sync SetAsyncScrollOffset(ViewID id, float x, float y);
// The next time the layer tree is composited, include this async zoom in
// for the given ViewID.