2017-01-25 05:51:30 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
#include "AnimationHelper.h"
|
|
|
|
#include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
|
2018-05-07 05:15:16 +03:00
|
|
|
#include "mozilla/dom/AnimationEffectBinding.h" // for dom::FillMode
|
2017-01-26 10:04:16 +03:00
|
|
|
#include "mozilla/dom/KeyframeEffectBinding.h" // for dom::IterationComposite
|
2018-05-07 05:07:06 +03:00
|
|
|
#include "mozilla/dom/KeyframeEffect.h" // for dom::KeyFrameEffectReadOnly
|
2018-04-05 20:42:42 +03:00
|
|
|
#include "mozilla/dom/Nullable.h" // for dom::Nullable
|
2017-02-10 01:30:11 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
|
2017-01-26 10:04:16 +03:00
|
|
|
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
|
2019-03-18 21:04:50 +03:00
|
|
|
#include "mozilla/LayerAnimationInfo.h" // for GetCSSPropertiesFor()
|
2018-04-19 07:50:14 +03:00
|
|
|
#include "mozilla/ServoBindings.h" // for Servo_ComposeAnimationSegment, etc
|
2017-01-25 05:51:30 +03:00
|
|
|
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
|
2017-06-28 03:29:06 +03:00
|
|
|
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
|
2017-04-12 11:40:48 +03:00
|
|
|
#include "nsDisplayList.h" // for nsDisplayTransform, etc
|
2017-01-25 05:51:30 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
void CompositorAnimationStorage::Clear() {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
|
|
|
|
mAnimatedValues.Clear();
|
|
|
|
mAnimations.Clear();
|
2019-03-22 21:28:42 +03:00
|
|
|
mAnimationRenderRoots.Clear();
|
2017-04-12 11:40:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CompositorAnimationStorage::ClearById(const uint64_t& aId) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2017-02-10 01:30:11 +03:00
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
mAnimatedValues.Remove(aId);
|
|
|
|
mAnimations.Remove(aId);
|
2019-03-22 21:28:42 +03:00
|
|
|
mAnimationRenderRoots.Remove(aId);
|
2017-02-10 01:30:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
AnimatedValue* CompositorAnimationStorage::GetAnimatedValue(
|
|
|
|
const uint64_t& aId) const {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
return mAnimatedValues.Get(aId);
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:13:15 +03:00
|
|
|
OMTAValue CompositorAnimationStorage::GetOMTAValue(const uint64_t& aId) const {
|
|
|
|
OMTAValue omtaValue = mozilla::null_t();
|
|
|
|
auto animatedValue = GetAnimatedValue(aId);
|
|
|
|
if (!animatedValue) {
|
|
|
|
return omtaValue;
|
|
|
|
}
|
|
|
|
|
2019-04-11 15:37:06 +03:00
|
|
|
animatedValue->Value().match(
|
|
|
|
[&](const AnimationTransform& aTransform) {
|
|
|
|
gfx::Matrix4x4 transform = aTransform.mFrameTransform;
|
|
|
|
const TransformData& data = aTransform.mData;
|
|
|
|
float scale = data.appUnitsPerDevPixel();
|
|
|
|
gfx::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)
|
|
|
|
double devPerCss = double(scale) / double(AppUnitsPerCSSPixel());
|
|
|
|
transform._41 *= devPerCss;
|
|
|
|
transform._42 *= devPerCss;
|
|
|
|
transform._43 *= devPerCss;
|
|
|
|
omtaValue = transform;
|
|
|
|
},
|
|
|
|
[&](const float& aOpacity) { omtaValue = aOpacity; },
|
|
|
|
[&](const nscolor& aColor) { omtaValue = aColor; });
|
2018-07-31 00:13:15 +03:00
|
|
|
return omtaValue;
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
void CompositorAnimationStorage::SetAnimatedValue(
|
|
|
|
uint64_t aId, gfx::Matrix4x4&& aTransformInDevSpace,
|
|
|
|
gfx::Matrix4x4&& aFrameTransform, const TransformData& aData) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2018-04-24 09:13:10 +03:00
|
|
|
auto count = mAnimatedValues.Count();
|
|
|
|
AnimatedValue* value = mAnimatedValues.LookupOrAdd(
|
2018-05-30 22:15:35 +03:00
|
|
|
aId, std::move(aTransformInDevSpace), std::move(aFrameTransform), aData);
|
2018-04-24 09:13:10 +03:00
|
|
|
if (count == mAnimatedValues.Count()) {
|
2019-04-11 15:37:06 +03:00
|
|
|
MOZ_ASSERT(value->Is<AnimationTransform>());
|
|
|
|
*value = AnimatedValue(std::move(aTransformInDevSpace),
|
|
|
|
std::move(aFrameTransform), aData);
|
2018-04-24 09:13:10 +03:00
|
|
|
}
|
2017-04-25 06:52:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CompositorAnimationStorage::SetAnimatedValue(
|
|
|
|
uint64_t aId, gfx::Matrix4x4&& aTransformInDevSpace) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
const TransformData dontCare = {};
|
2018-05-30 22:15:35 +03:00
|
|
|
SetAnimatedValue(aId, std::move(aTransformInDevSpace), gfx::Matrix4x4(),
|
2018-04-24 09:13:10 +03:00
|
|
|
dontCare);
|
2017-02-10 01:30:11 +03:00
|
|
|
}
|
|
|
|
|
2018-11-28 03:59:15 +03:00
|
|
|
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
|
|
|
|
nscolor aColor) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
auto count = mAnimatedValues.Count();
|
|
|
|
AnimatedValue* value = mAnimatedValues.LookupOrAdd(aId, aColor);
|
|
|
|
if (count == mAnimatedValues.Count()) {
|
2019-04-11 15:37:06 +03:00
|
|
|
MOZ_ASSERT(value->Is<nscolor>());
|
|
|
|
*value = AnimatedValue(aColor);
|
2018-11-28 03:59:15 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
|
|
|
|
const float& aOpacity) {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2018-04-24 09:13:10 +03:00
|
|
|
auto count = mAnimatedValues.Count();
|
|
|
|
AnimatedValue* value = mAnimatedValues.LookupOrAdd(aId, aOpacity);
|
|
|
|
if (count == mAnimatedValues.Count()) {
|
2019-04-11 15:37:06 +03:00
|
|
|
MOZ_ASSERT(value->Is<float>());
|
|
|
|
*value = AnimatedValue(aOpacity);
|
2018-04-24 09:13:10 +03:00
|
|
|
}
|
2017-02-10 01:30:11 +03:00
|
|
|
}
|
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
nsTArray<PropertyAnimationGroup>* CompositorAnimationStorage::GetAnimations(
|
2017-02-10 01:30:11 +03:00
|
|
|
const uint64_t& aId) const {
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
return mAnimations.Get(aId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompositorAnimationStorage::SetAnimations(uint64_t aId,
|
2019-03-22 21:28:42 +03:00
|
|
|
const AnimationArray& aValue,
|
|
|
|
wr::RenderRoot aRenderRoot) {
|
2017-02-10 01:30:11 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
mAnimations.Put(aId, new nsTArray<PropertyAnimationGroup>(
|
|
|
|
AnimationHelper::ExtractAnimations(aValue)));
|
2019-03-22 21:28:42 +03:00
|
|
|
mAnimationRenderRoots.Put(aId, aRenderRoot);
|
2017-02-10 01:30:11 +03:00
|
|
|
}
|
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
enum class CanSkipCompose {
|
|
|
|
IfPossible,
|
|
|
|
No,
|
|
|
|
};
|
|
|
|
static AnimationHelper::SampleResult SampleAnimationForProperty(
|
2018-05-08 06:58:42 +03:00
|
|
|
TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime,
|
2019-03-18 21:04:50 +03:00
|
|
|
const AnimatedValue* aPreviousValue, CanSkipCompose aCanSkipCompose,
|
|
|
|
nsTArray<PropertyAnimation>& aPropertyAnimations,
|
|
|
|
RefPtr<RawServoAnimationValue>& aAnimationValue) {
|
|
|
|
MOZ_ASSERT(!aPropertyAnimations.IsEmpty(), "Should have animations");
|
2018-04-24 03:27:54 +03:00
|
|
|
bool hasInEffectAnimations = false;
|
2018-04-28 12:09:27 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
// In cases where this function returns a SampleResult::Skipped, we actually
|
|
|
|
// do populate aAnimationValue in debug mode, so that we can MOZ_ASSERT at the
|
|
|
|
// call site that the value that would have been computed matches the stored
|
|
|
|
// value that we end up using. This flag is used to ensure we populate
|
|
|
|
// aAnimationValue in this scenario.
|
|
|
|
bool shouldBeSkipped = false;
|
|
|
|
#endif
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
// Process in order, since later animations override earlier ones.
|
2019-03-18 21:04:50 +03:00
|
|
|
for (PropertyAnimation& animation : aPropertyAnimations) {
|
2017-05-02 10:49:51 +03:00
|
|
|
MOZ_ASSERT(
|
2019-03-25 22:29:46 +03:00
|
|
|
(!animation.mOriginTime.IsNull() && animation.mStartTime.isSome()) ||
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mIsNotPlaying,
|
|
|
|
"If we are playing, we should have an origin time and a start time");
|
2018-05-08 06:58:42 +03:00
|
|
|
|
2018-05-08 10:58:06 +03:00
|
|
|
// Determine if the animation was play-pending and used a ready time later
|
|
|
|
// than the previous frame time.
|
|
|
|
//
|
2019-03-18 21:04:50 +03:00
|
|
|
// To determine this, _all_ of the following conditions need to hold:
|
2018-05-08 10:58:06 +03:00
|
|
|
//
|
|
|
|
// * There was no previous animation value (i.e. this is the first frame for
|
|
|
|
// the animation since it was sent to the compositor), and
|
|
|
|
// * The animation is playing, and
|
|
|
|
// * There is a previous frame time, and
|
|
|
|
// * The ready time of the animation is ahead of the previous frame time.
|
|
|
|
//
|
|
|
|
bool hasFutureReadyTime = false;
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
if (!aPreviousValue && !animation.mIsNotPlaying &&
|
2018-05-08 10:58:06 +03:00
|
|
|
!aPreviousFrameTime.IsNull()) {
|
|
|
|
// This is the inverse of the calculation performed in
|
|
|
|
// AnimationInfo::StartPendingAnimations to calculate the start time of
|
|
|
|
// play-pending animations.
|
2018-05-09 04:47:51 +03:00
|
|
|
// Note that we have to calculate (TimeStamp + TimeDuration) last to avoid
|
|
|
|
// underflow in the middle of the calulation.
|
2018-05-08 10:58:06 +03:00
|
|
|
const TimeStamp readyTime =
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mOriginTime +
|
2019-03-25 22:29:46 +03:00
|
|
|
(animation.mStartTime.ref() +
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mHoldTime.MultDouble(1.0 / animation.mPlaybackRate));
|
2018-05-09 04:47:51 +03:00
|
|
|
hasFutureReadyTime =
|
|
|
|
!readyTime.IsNull() && readyTime > aPreviousFrameTime;
|
2018-05-08 10:58:06 +03:00
|
|
|
}
|
|
|
|
// Use the previous vsync time to make main thread animations and compositor
|
|
|
|
// more closely aligned.
|
|
|
|
//
|
|
|
|
// On the first frame where we have animations the previous timestamp will
|
|
|
|
// not be set so we simply use the current timestamp. As a result we will
|
|
|
|
// end up painting the first frame twice. That doesn't appear to be
|
|
|
|
// noticeable, however.
|
|
|
|
//
|
|
|
|
// Likewise, if the animation is play-pending, it may have a ready time that
|
|
|
|
// is *after* |aPreviousFrameTime| (but *before* |aCurrentFrameTime|).
|
|
|
|
// To avoid flicker we need to use |aCurrentFrameTime| to avoid temporarily
|
|
|
|
// jumping backwards into the range prior to when the animation starts.
|
|
|
|
const TimeStamp& timeStamp =
|
|
|
|
aPreviousFrameTime.IsNull() || hasFutureReadyTime ? aCurrentFrameTime
|
|
|
|
: aPreviousFrameTime;
|
2018-05-08 06:58:42 +03:00
|
|
|
|
2017-05-18 08:06:36 +03:00
|
|
|
// If the animation is not currently playing, e.g. paused or
|
2017-01-26 10:04:16 +03:00
|
|
|
// finished, then use the hold time to stay at the same position.
|
2017-05-18 08:06:36 +03:00
|
|
|
TimeDuration elapsedDuration =
|
2019-03-25 22:29:46 +03:00
|
|
|
animation.mIsNotPlaying || animation.mStartTime.isNothing()
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
? animation.mHoldTime
|
2019-03-25 22:29:46 +03:00
|
|
|
: (timeStamp - animation.mOriginTime - animation.mStartTime.ref())
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
.MultDouble(animation.mPlaybackRate);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-05-07 05:15:16 +03:00
|
|
|
ComputedTiming computedTiming = dom::AnimationEffect::GetComputedTimingAt(
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
dom::Nullable<TimeDuration>(elapsedDuration), animation.mTiming,
|
|
|
|
animation.mPlaybackRate);
|
2017-01-26 10:04:16 +03:00
|
|
|
|
|
|
|
if (computedTiming.mProgress.IsNull()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-04-24 03:27:54 +03:00
|
|
|
dom::IterationCompositeOperation iterCompositeOperation =
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mIterationComposite;
|
2018-04-24 03:27:54 +03:00
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
// Skip calculation if the progress hasn't changed since the last
|
2018-04-24 03:27:54 +03:00
|
|
|
// calculation.
|
|
|
|
// Note that we don't skip calculate this animation if there is another
|
|
|
|
// animation since the other animation might be 'accumulate' or 'add', or
|
|
|
|
// might have a missing keyframe (i.e. this animation value will be used in
|
|
|
|
// the missing keyframe).
|
|
|
|
// FIXME Bug 1455476: We should do this optimizations for the case where
|
2019-03-18 21:04:50 +03:00
|
|
|
// the layer has multiple animations and multiple properties.
|
|
|
|
if (aCanSkipCompose == CanSkipCompose::IfPossible &&
|
|
|
|
!dom::KeyframeEffect::HasComputedTimingChanged(
|
|
|
|
computedTiming, iterCompositeOperation,
|
|
|
|
animation.mProgressOnLastCompose,
|
|
|
|
animation.mCurrentIterationOnLastCompose)) {
|
2018-04-28 12:09:27 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
shouldBeSkipped = true;
|
|
|
|
#else
|
2019-03-18 21:04:50 +03:00
|
|
|
return AnimationHelper::SampleResult::Skipped;
|
2018-04-28 12:09:27 +03:00
|
|
|
#endif
|
2018-04-24 03:27:54 +03:00
|
|
|
}
|
|
|
|
|
2017-01-26 10:04:16 +03:00
|
|
|
uint32_t segmentIndex = 0;
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
size_t segmentSize = animation.mSegments.Length();
|
|
|
|
PropertyAnimation::SegmentData* segment = animation.mSegments.Elements();
|
|
|
|
while (segment->mEndPortion < computedTiming.mProgress.Value() &&
|
2017-01-26 10:04:16 +03:00
|
|
|
segmentIndex < segmentSize - 1) {
|
|
|
|
++segment;
|
|
|
|
++segmentIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
double positionInSegment =
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
(computedTiming.mProgress.Value() - segment->mStartPortion) /
|
|
|
|
(segment->mEndPortion - segment->mStartPortion);
|
2017-01-26 10:04:16 +03:00
|
|
|
|
|
|
|
double portion = ComputedTimingFunction::GetPortion(
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
segment->mFunction, positionInSegment, computedTiming.mBeforeFlag);
|
2017-01-26 10:04:16 +03:00
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
// Like above optimization, skip calculation if the target segment isn't
|
2018-04-24 03:27:54 +03:00
|
|
|
// changed and if the portion in the segment isn't changed.
|
|
|
|
// This optimization is needed for CSS animations/transitions with step
|
2019-03-18 21:04:50 +03:00
|
|
|
// timing functions (e.g. the throbber animation on tabs or frame based
|
2018-04-24 03:27:54 +03:00
|
|
|
// animations).
|
|
|
|
// FIXME Bug 1455476: Like the above optimization, we should apply this
|
2019-03-18 21:04:50 +03:00
|
|
|
// optimizations for multiple animation cases and multiple properties as
|
|
|
|
// well.
|
|
|
|
if (aCanSkipCompose == CanSkipCompose::IfPossible &&
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mSegmentIndexOnLastCompose == segmentIndex &&
|
|
|
|
!animation.mPortionInSegmentOnLastCompose.IsNull() &&
|
|
|
|
animation.mPortionInSegmentOnLastCompose.Value() == portion) {
|
2018-04-28 12:09:27 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
shouldBeSkipped = true;
|
|
|
|
#else
|
2019-03-18 21:04:50 +03:00
|
|
|
return AnimationHelper::SampleResult::Skipped;
|
2018-04-28 12:09:27 +03:00
|
|
|
#endif
|
2018-04-24 03:27:54 +03:00
|
|
|
}
|
|
|
|
|
2017-10-27 22:09:11 +03:00
|
|
|
AnimationPropertySegment animSegment;
|
|
|
|
animSegment.mFromKey = 0.0;
|
|
|
|
animSegment.mToKey = 1.0;
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animSegment.mFromValue = AnimationValue(segment->mStartValue);
|
|
|
|
animSegment.mToValue = AnimationValue(segment->mEndValue);
|
|
|
|
animSegment.mFromComposite = segment->mStartComposite;
|
|
|
|
animSegment.mToComposite = segment->mEndComposite;
|
2017-10-27 22:09:11 +03:00
|
|
|
|
2017-01-26 10:04:16 +03:00
|
|
|
// interpolate the property
|
2018-04-19 07:50:14 +03:00
|
|
|
aAnimationValue =
|
2018-02-01 07:04:04 +03:00
|
|
|
Servo_ComposeAnimationSegment(
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
&animSegment, aAnimationValue,
|
|
|
|
animation.mSegments.LastElement().mEndValue, iterCompositeOperation,
|
|
|
|
portion, computedTiming.mCurrentIteration)
|
2018-02-01 07:04:04 +03:00
|
|
|
.Consume();
|
2018-04-28 12:09:27 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (shouldBeSkipped) {
|
2019-03-18 21:04:50 +03:00
|
|
|
return AnimationHelper::SampleResult::Skipped;
|
2018-04-28 12:09:27 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-04-24 03:27:54 +03:00
|
|
|
hasInEffectAnimations = true;
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
animation.mProgressOnLastCompose = computedTiming.mProgress;
|
|
|
|
animation.mCurrentIterationOnLastCompose = computedTiming.mCurrentIteration;
|
|
|
|
animation.mSegmentIndexOnLastCompose = segmentIndex;
|
|
|
|
animation.mPortionInSegmentOnLastCompose.SetValue(portion);
|
2017-01-26 10:04:16 +03:00
|
|
|
}
|
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
return hasInEffectAnimations ? AnimationHelper::SampleResult::Sampled
|
|
|
|
: AnimationHelper::SampleResult::None;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimationHelper::SampleResult AnimationHelper::SampleAnimationForEachNode(
|
|
|
|
TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime,
|
|
|
|
const AnimatedValue* aPreviousValue,
|
|
|
|
nsTArray<PropertyAnimationGroup>& aPropertyAnimationGroups,
|
|
|
|
nsTArray<RefPtr<RawServoAnimationValue>>& aAnimationValues /* out */) {
|
|
|
|
MOZ_ASSERT(!aPropertyAnimationGroups.IsEmpty(),
|
|
|
|
"Should be called with animation data");
|
|
|
|
MOZ_ASSERT(aAnimationValues.IsEmpty(),
|
|
|
|
"Should be called with empty aAnimationValues");
|
|
|
|
|
|
|
|
for (PropertyAnimationGroup& group : aPropertyAnimationGroups) {
|
|
|
|
// Initialize animation value with base style.
|
|
|
|
RefPtr<RawServoAnimationValue> currValue = group.mBaseStyle;
|
|
|
|
|
|
|
|
CanSkipCompose canSkipCompose = aPropertyAnimationGroups.Length() == 1 &&
|
|
|
|
group.mAnimations.Length() == 1
|
|
|
|
? CanSkipCompose::IfPossible
|
|
|
|
: CanSkipCompose::No;
|
|
|
|
SampleResult result = SampleAnimationForProperty(
|
|
|
|
aPreviousFrameTime, aCurrentFrameTime, aPreviousValue, canSkipCompose,
|
|
|
|
group.mAnimations, currValue);
|
|
|
|
|
|
|
|
// FIXME: Bug 1455476: Do optimization for multiple properties. For now,
|
|
|
|
// the result is skipped only if the property count == 1.
|
|
|
|
if (result == SampleResult::Skipped) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
aAnimationValues.AppendElement(std::move(currValue));
|
|
|
|
#endif
|
|
|
|
return SampleResult::Skipped;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result != SampleResult::Sampled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert the interpolation result into the output array.
|
|
|
|
MOZ_ASSERT(currValue);
|
|
|
|
aAnimationValues.AppendElement(std::move(currValue));
|
|
|
|
}
|
|
|
|
|
2017-01-26 10:04:16 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
// Sanity check that all of animation data are the same.
|
2019-03-29 22:54:14 +03:00
|
|
|
const Maybe<TransformData>& lastData =
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
aPropertyAnimationGroups.LastElement().mAnimationData;
|
|
|
|
for (const PropertyAnimationGroup& group : aPropertyAnimationGroups) {
|
2019-03-29 22:54:14 +03:00
|
|
|
const Maybe<TransformData>& data = group.mAnimationData;
|
|
|
|
MOZ_ASSERT(data.isSome() == lastData.isSome(),
|
2017-01-26 10:04:16 +03:00
|
|
|
"The type of AnimationData should be the same");
|
2019-03-29 22:54:14 +03:00
|
|
|
if (data.isNothing()) {
|
2017-01-26 10:04:16 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:54:14 +03:00
|
|
|
MOZ_ASSERT(data.isSome());
|
|
|
|
const TransformData& transformData = data.ref();
|
|
|
|
const TransformData& lastTransformData = lastData.ref();
|
2017-01-26 10:04:16 +03:00
|
|
|
MOZ_ASSERT(transformData.origin() == lastTransformData.origin() &&
|
|
|
|
transformData.transformOrigin() ==
|
|
|
|
lastTransformData.transformOrigin() &&
|
|
|
|
transformData.bounds() == lastTransformData.bounds() &&
|
|
|
|
transformData.appUnitsPerDevPixel() ==
|
|
|
|
lastTransformData.appUnitsPerDevPixel(),
|
|
|
|
"All of members of TransformData should be the same");
|
|
|
|
}
|
|
|
|
#endif
|
2018-04-24 03:27:54 +03:00
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
return aAnimationValues.IsEmpty() ? SampleResult::None
|
|
|
|
: SampleResult::Sampled;
|
2017-01-26 10:04:16 +03:00
|
|
|
}
|
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
static dom::FillMode GetAdjustedFillMode(const Animation& aAnimation) {
|
|
|
|
// Adjust fill mode so that if the main thread is delayed in clearing
|
|
|
|
// this animation we don't introduce flicker by jumping back to the old
|
|
|
|
// underlying value.
|
|
|
|
auto fillMode = static_cast<dom::FillMode>(aAnimation.fillMode());
|
|
|
|
float playbackRate = aAnimation.playbackRate();
|
|
|
|
switch (fillMode) {
|
|
|
|
case dom::FillMode::None:
|
|
|
|
if (playbackRate > 0) {
|
|
|
|
fillMode = dom::FillMode::Forwards;
|
|
|
|
} else if (playbackRate < 0) {
|
|
|
|
fillMode = dom::FillMode::Backwards;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case dom::FillMode::Backwards:
|
|
|
|
if (playbackRate > 0) {
|
|
|
|
fillMode = dom::FillMode::Both;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case dom::FillMode::Forwards:
|
|
|
|
if (playbackRate < 0) {
|
|
|
|
fillMode = dom::FillMode::Both;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return fillMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<PropertyAnimationGroup> AnimationHelper::ExtractAnimations(
|
|
|
|
const AnimationArray& aAnimations) {
|
|
|
|
nsTArray<PropertyAnimationGroup> propertyAnimationGroupArray;
|
2019-03-18 21:04:50 +03:00
|
|
|
|
|
|
|
nsCSSPropertyID prevID = eCSSProperty_UNKNOWN;
|
|
|
|
PropertyAnimationGroup* currData = nullptr;
|
|
|
|
DebugOnly<const layers::Animatable*> currBaseStyle = nullptr;
|
2017-01-25 05:51:30 +03:00
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
for (const Animation& animation : aAnimations) {
|
2019-03-18 21:04:50 +03:00
|
|
|
// Animations with same property are grouped together, so we can just
|
|
|
|
// check if the current property is the same as the previous one for
|
|
|
|
// knowing this is a new group.
|
|
|
|
if (prevID != animation.property()) {
|
|
|
|
// Got a different group, we should create a different array.
|
|
|
|
currData = propertyAnimationGroupArray.AppendElement();
|
|
|
|
currData->mProperty = animation.property();
|
|
|
|
currData->mAnimationData = animation.data();
|
|
|
|
prevID = animation.property();
|
|
|
|
|
|
|
|
// Reset the debug pointer.
|
|
|
|
currBaseStyle = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(currData);
|
2017-01-25 05:51:30 +03:00
|
|
|
if (animation.baseStyle().type() != Animatable::Tnull_t) {
|
2019-03-18 21:04:50 +03:00
|
|
|
MOZ_ASSERT(!currBaseStyle || *currBaseStyle == animation.baseStyle(),
|
|
|
|
"Should be the same base style");
|
|
|
|
|
|
|
|
currData->mBaseStyle = AnimationValue::FromAnimatable(
|
2019-03-18 21:04:44 +03:00
|
|
|
animation.property(), animation.baseStyle());
|
2019-03-18 21:04:50 +03:00
|
|
|
currBaseStyle = &animation.baseStyle();
|
2017-01-25 05:51:30 +03:00
|
|
|
}
|
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
PropertyAnimation* propertyAnimation =
|
2019-03-18 21:04:50 +03:00
|
|
|
currData->mAnimations.AppendElement();
|
2018-04-24 03:27:53 +03:00
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
propertyAnimation->mOriginTime = animation.originTime();
|
|
|
|
propertyAnimation->mStartTime = animation.startTime();
|
|
|
|
propertyAnimation->mHoldTime = animation.holdTime();
|
|
|
|
propertyAnimation->mPlaybackRate = animation.playbackRate();
|
|
|
|
propertyAnimation->mIterationComposite =
|
|
|
|
static_cast<dom::IterationCompositeOperation>(
|
|
|
|
animation.iterationComposite());
|
|
|
|
propertyAnimation->mIsNotPlaying = animation.isNotPlaying();
|
|
|
|
propertyAnimation->mTiming =
|
2018-04-24 03:27:53 +03:00
|
|
|
TimingParams{animation.duration(),
|
|
|
|
animation.delay(),
|
|
|
|
animation.endDelay(),
|
|
|
|
animation.iterations(),
|
|
|
|
animation.iterationStart(),
|
|
|
|
static_cast<dom::PlaybackDirection>(animation.direction()),
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
GetAdjustedFillMode(animation),
|
2018-06-01 18:59:07 +03:00
|
|
|
AnimationUtils::TimingFunctionToComputedTimingFunction(
|
|
|
|
animation.easingFunction())};
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
|
|
|
|
nsTArray<PropertyAnimation::SegmentData>& segmentData =
|
|
|
|
propertyAnimation->mSegments;
|
|
|
|
for (const AnimationSegment& segment : animation.segments()) {
|
|
|
|
segmentData.AppendElement(PropertyAnimation::SegmentData{
|
|
|
|
AnimationValue::FromAnimatable(animation.property(),
|
|
|
|
segment.startState()),
|
|
|
|
AnimationValue::FromAnimatable(animation.property(),
|
|
|
|
segment.endState()),
|
|
|
|
AnimationUtils::TimingFunctionToComputedTimingFunction(
|
|
|
|
segment.sampleFn()),
|
|
|
|
segment.startPortion(), segment.endPortion(),
|
|
|
|
static_cast<dom::CompositeOperation>(segment.startComposite()),
|
|
|
|
static_cast<dom::CompositeOperation>(segment.endComposite())});
|
2017-01-25 05:51:30 +03:00
|
|
|
}
|
|
|
|
}
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
// Sanity check that the grouped animation data is correct by looking at the
|
|
|
|
// property set.
|
|
|
|
if (!propertyAnimationGroupArray.IsEmpty()) {
|
|
|
|
nsCSSPropertyIDSet seenProperties;
|
|
|
|
for (const auto& group : propertyAnimationGroupArray) {
|
|
|
|
nsCSSPropertyID id = group.mProperty;
|
|
|
|
|
|
|
|
MOZ_ASSERT(!seenProperties.HasProperty(id), "Should be a new property");
|
|
|
|
seenProperties.AddProperty(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(
|
|
|
|
seenProperties.IsSubsetOf(LayerAnimationInfo::GetCSSPropertiesFor(
|
|
|
|
DisplayItemType::TYPE_TRANSFORM)) ||
|
|
|
|
seenProperties.IsSubsetOf(LayerAnimationInfo::GetCSSPropertiesFor(
|
|
|
|
DisplayItemType::TYPE_OPACITY)) ||
|
|
|
|
seenProperties.IsSubsetOf(LayerAnimationInfo::GetCSSPropertiesFor(
|
|
|
|
DisplayItemType::TYPE_BACKGROUND_COLOR)),
|
|
|
|
"The property set of output should be the subset of transform-like "
|
|
|
|
"properties, opacity, or background_color.");
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
}
|
2019-03-18 21:04:50 +03:00
|
|
|
#endif
|
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
return propertyAnimationGroupArray;
|
2017-01-25 05:51:30 +03:00
|
|
|
}
|
|
|
|
|
2017-02-08 22:31:45 +03:00
|
|
|
uint64_t AnimationHelper::GetNextCompositorAnimationsId() {
|
|
|
|
static uint32_t sNextId = 0;
|
|
|
|
++sNextId;
|
|
|
|
|
|
|
|
uint32_t procId = static_cast<uint32_t>(base::GetCurrentProcId());
|
|
|
|
uint64_t nextId = procId;
|
|
|
|
nextId = nextId << 32 | sNextId;
|
|
|
|
return nextId;
|
|
|
|
}
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
bool AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
|
2018-05-08 06:58:42 +03:00
|
|
|
TimeStamp aPreviousFrameTime,
|
|
|
|
TimeStamp aCurrentFrameTime) {
|
2017-04-12 11:40:48 +03:00
|
|
|
MOZ_ASSERT(aStorage);
|
2018-05-08 09:48:27 +03:00
|
|
|
bool isAnimating = false;
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
// Do nothing if there are no compositor animations
|
|
|
|
if (!aStorage->AnimationsCount()) {
|
2018-05-08 09:48:27 +03:00
|
|
|
return isAnimating;
|
2017-04-12 11:40:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sample the animations in CompositorAnimationStorage
|
|
|
|
for (auto iter = aStorage->ConstAnimationsTableIter(); !iter.Done();
|
|
|
|
iter.Next()) {
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
auto& propertyAnimationGroups = *iter.UserData();
|
|
|
|
if (propertyAnimationGroups.IsEmpty()) {
|
2018-04-17 07:20:33 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-05-08 09:48:27 +03:00
|
|
|
isAnimating = true;
|
2019-03-18 21:04:50 +03:00
|
|
|
nsTArray<RefPtr<RawServoAnimationValue>> animationValues;
|
2018-05-08 10:58:06 +03:00
|
|
|
AnimatedValue* previousValue = aStorage->GetAnimatedValue(iter.Key());
|
2018-04-24 03:27:54 +03:00
|
|
|
AnimationHelper::SampleResult sampleResult =
|
2018-05-08 06:58:42 +03:00
|
|
|
AnimationHelper::SampleAnimationForEachNode(
|
2019-03-18 21:04:50 +03:00
|
|
|
aPreviousFrameTime, aCurrentFrameTime, previousValue,
|
|
|
|
propertyAnimationGroups, animationValues);
|
2017-04-12 11:40:48 +03:00
|
|
|
|
2018-04-24 03:27:54 +03:00
|
|
|
if (sampleResult != AnimationHelper::SampleResult::Sampled) {
|
2017-04-12 11:40:48 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
const PropertyAnimationGroup& lastPropertyAnimationGroup =
|
|
|
|
propertyAnimationGroups.LastElement();
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
// Store the AnimatedValue
|
Bug 1425837 - Part 3: Don't store AnimationArray (a.k.a. AnimationInfo::mAnimations) on the compositor thread. r=birtles
The original implementation about "setting animations" is a little bit hard
to read. In `SetAnimations()`, we create a new intermediate data,
`AnimData`, and we mutate the original animations. And then iterate this
mutated animations & intermediate data for sampling. In this bug, we are
planning to group the AnimData as a useful data structure for supporting
multiple properties transform-like animations, so it seems the structure
of original animations may be hard to use after that. Therefore,
we decide to do some reworks on this:
First, we do renames,
1. InfalliableTArray to nsTArray. (They are the same.)
2. AnimData to PropertyAnimation.
3. SetAnimations() to ExtractAnimations(), which returns
nsTArray<PropertyAnimationGroup>. Each entry in the array is for one
property. In this patch, there is only one entry. We will extend this
to multiple entries in the next patch.
And then rework `ExtractAnimations()`, which stores all the necessary data
in `PropertyAnimationGroup`. For WR, we store this in
`CompositorAnimationStorage`. For non-WR, we store it in `AnimationInfo`.
So we can just use this organized data structure for supporting multiple
properties animations. (See the next patch.)
Depends on D22563
Differential Revision: https://phabricator.services.mozilla.com/D23062
--HG--
extra : moz-landing-system : lando
2019-03-18 21:04:48 +03:00
|
|
|
switch (lastPropertyAnimationGroup.mProperty) {
|
2017-04-12 11:40:48 +03:00
|
|
|
case eCSSProperty_opacity: {
|
2019-03-18 21:04:50 +03:00
|
|
|
MOZ_ASSERT(animationValues.Length() == 1);
|
2018-04-19 07:50:14 +03:00
|
|
|
aStorage->SetAnimatedValue(
|
2019-03-18 21:04:50 +03:00
|
|
|
iter.Key(), Servo_AnimationValue_GetOpacity(animationValues[0]));
|
2017-04-12 11:40:48 +03:00
|
|
|
break;
|
|
|
|
}
|
2019-03-18 21:04:50 +03:00
|
|
|
case eCSSProperty_rotate:
|
|
|
|
case eCSSProperty_scale:
|
|
|
|
case eCSSProperty_translate:
|
2017-04-12 11:40:48 +03:00
|
|
|
case eCSSProperty_transform: {
|
|
|
|
const TransformData& transformData =
|
2019-03-29 22:54:14 +03:00
|
|
|
lastPropertyAnimationGroup.mAnimationData.ref();
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
gfx::Matrix4x4 transform =
|
2019-03-18 21:04:50 +03:00
|
|
|
ServoAnimationValueToMatrix4x4(animationValues, transformData);
|
2017-04-12 11:40:48 +03:00
|
|
|
gfx::Matrix4x4 frameTransform = transform;
|
2017-04-17 06:35:42 +03:00
|
|
|
// If the parent has perspective transform, then the offset into
|
|
|
|
// reference frame coordinates is already on this transform. If not,
|
2017-04-12 11:40:48 +03:00
|
|
|
// then we need to ask for it to be added here.
|
2017-04-17 06:35:42 +03:00
|
|
|
if (!transformData.hasPerspectiveParent()) {
|
2019-03-18 21:04:46 +03:00
|
|
|
nsLayoutUtils::PostTranslate(transform, transformData.origin(),
|
|
|
|
transformData.appUnitsPerDevPixel(),
|
|
|
|
true);
|
2017-04-17 06:35:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
transform.PostScale(transformData.inheritedXScale(),
|
|
|
|
transformData.inheritedYScale(), 1);
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
aStorage->SetAnimatedValue(iter.Key(), std::move(transform),
|
2018-05-30 22:15:35 +03:00
|
|
|
std::move(frameTransform), transformData);
|
2017-04-12 11:40:48 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
|
|
|
|
}
|
|
|
|
}
|
2018-05-08 09:48:27 +03:00
|
|
|
|
|
|
|
return isAnimating;
|
2017-04-12 11:40:48 +03:00
|
|
|
}
|
|
|
|
|
2019-03-18 21:04:46 +03:00
|
|
|
gfx::Matrix4x4 AnimationHelper::ServoAnimationValueToMatrix4x4(
|
2019-03-18 21:04:50 +03:00
|
|
|
const nsTArray<RefPtr<RawServoAnimationValue>>& aValues,
|
2019-03-18 21:04:46 +03:00
|
|
|
const TransformData& aTransformData) {
|
2019-05-17 02:25:10 +03:00
|
|
|
// This is a bit silly just to avoid the transform list copy from the
|
|
|
|
// animation transform list.
|
|
|
|
auto noneTranslate = StyleTranslate::None();
|
|
|
|
auto noneRotate = StyleRotate::None();
|
|
|
|
auto noneScale = StyleScale::None();
|
|
|
|
const StyleTransform noneTransform;
|
|
|
|
|
|
|
|
const StyleTranslate* translate = nullptr;
|
|
|
|
const StyleRotate* rotate = nullptr;
|
|
|
|
const StyleScale* scale = nullptr;
|
|
|
|
const StyleTransform* transform = nullptr;
|
|
|
|
|
2019-03-18 21:04:50 +03:00
|
|
|
// TODO: Bug 1429305: Support compositor animations for motion-path.
|
|
|
|
for (const auto& value : aValues) {
|
|
|
|
MOZ_ASSERT(value);
|
2019-05-17 02:25:10 +03:00
|
|
|
nsCSSPropertyID id = Servo_AnimationValue_GetPropertyId(value);
|
2019-03-18 21:04:50 +03:00
|
|
|
switch (id) {
|
|
|
|
case eCSSProperty_transform:
|
|
|
|
MOZ_ASSERT(!transform);
|
2019-05-17 02:25:10 +03:00
|
|
|
transform = Servo_AnimationValue_GetTransform(value);
|
2019-03-18 21:04:50 +03:00
|
|
|
break;
|
|
|
|
case eCSSProperty_translate:
|
|
|
|
MOZ_ASSERT(!translate);
|
2019-05-17 02:25:10 +03:00
|
|
|
translate = Servo_AnimationValue_GetTranslate(value);
|
2019-03-18 21:04:50 +03:00
|
|
|
break;
|
|
|
|
case eCSSProperty_rotate:
|
|
|
|
MOZ_ASSERT(!rotate);
|
2019-05-17 02:25:10 +03:00
|
|
|
rotate = Servo_AnimationValue_GetRotate(value);
|
2019-03-18 21:04:50 +03:00
|
|
|
break;
|
|
|
|
case eCSSProperty_scale:
|
|
|
|
MOZ_ASSERT(!scale);
|
2019-05-17 02:25:10 +03:00
|
|
|
scale = Servo_AnimationValue_GetScale(value);
|
2019-03-18 21:04:50 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unsupported transform-like property");
|
|
|
|
}
|
|
|
|
}
|
2019-03-18 21:04:46 +03:00
|
|
|
// We expect all our transform data to arrive in device pixels
|
|
|
|
gfx::Point3D transformOrigin = aTransformData.transformOrigin();
|
2019-03-18 21:04:50 +03:00
|
|
|
nsDisplayTransform::FrameTransformProperties props(
|
2019-05-17 02:25:10 +03:00
|
|
|
translate ? *translate : noneTranslate, rotate ? *rotate : noneRotate,
|
|
|
|
scale ? *scale : noneScale, transform ? *transform : noneTransform,
|
|
|
|
transformOrigin);
|
2019-03-18 21:04:46 +03:00
|
|
|
|
|
|
|
return nsDisplayTransform::GetResultingTransformMatrix(
|
|
|
|
props, aTransformData.origin(), aTransformData.appUnitsPerDevPixel(), 0,
|
|
|
|
&aTransformData.bounds());
|
|
|
|
}
|
|
|
|
|
2017-01-25 05:51:30 +03:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|