This probably should have been done before, but prior to this patch
series, dynamic changes of the declarations on these rules were broken
due to rule immutability violations; now that is no longer the case, but
to benefit from that, I believe we actually need to mark the
declarations as immutable once matched so that dynamic changes will
trigger construction of a new declaration (which thus has a new
nsIStyleRule identity).
--HG--
extra : commitid : 8IsYBd67qQr
Do some minor revisions in struct ComputedTiming.
1. Use Nullable<double> mProgress, so remove the static const kNullProgress.
The generated ComputedTimingProperties dictionary uses "Nullable" variable,
so we replace the origin type in ComputedTiming to make it more consistent
with that in ComputedTimingProperties dictionary.
2. Use scoped enums for AnimationPhase.
--HG--
extra : rebase_source : 31280c867a30e7bcdcfe831cbc72ca08c8ddc762
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
This patch renames AnimationCollection::mNeedsRefreshes to indicate that it
no longer has any relationship to whether or not we observe the refresh driver.
We need to do this so effects can query their owning animation for the current
time and avoid falling out of sync. Furthermore, this pointer is needed
for a number of other bugs (e.g. bug 1166500 comment 12, or bug 1190235)
anyway.
In order to sort between events that have the same timestamp we use the
sort order of the corresponding animations so we need to store a pointer
to the animation along with the event.
--HG--
extra : rebase_source : 2767157135abd5a094d856410cd9c70e46a33b68
The elapsedTime member reported on AnimationEvents measures the time from
the *end* of the delay phase (i.e. the beginning of the active interval) to
when the event occurred. However, the AnimationTimeToTimeStamp method
introduced in the previous patch expects a time relative to the animation's
start time (i.e. the *start* of the delay phase). This patch adds a method
that performs the necessary conversion from an elapsedTime to an animation
time before calling AnimationTimeToTimeStamp. It also provides extra handling
for cases such as when the animation's start time has not yet been resolved or
when animation effect has disappeared.
--HG--
extra : rebase_source : 594f3f12bab3febe592d09b57be72b2ec09b47cf
This patch lines up the parameters of AnimationEventInfo and
TransitionEventInfo constructors so that they are more logical and consistent.
Specifically, it groups the element and pseudo type together since they
form a logical pair denoting the event target. For AnimationEventInfo this
patch also places the type of event before the common event parameters since
the event type seems to be more significant.
This patch also performs some miscelleaneous housekeeping: removing some
unnecessary namespace prefixes, whitespace fixes, and making
TransitionEventInfo use the same concrete type to store the target element
as AnimationEventInfo (dom::Element instead of nsIContent).
--HG--
extra : rebase_source : ce6935f74f31dffadce4d0e7d4fa8859ec213740
Currently we define a helper method, InitialAdvance, on KeyframeEffectReadOnly.
However, this method is only used for filling out the elapsedTime member of
AnimationEvents (which are generated by CSS animations). This patch moves this
method to CSSAnimation since it is unneeded for other types of Animations.
--HG--
extra : rebase_source : 9ab3b81a8272c004aabf26fea557c9a2f5d76caf
The Web Animations specification has replaced the term "sequence number" with
references to a global animation list. This patch applies similar naming
to our animation structures.
As well as ensuring that we don't create animations for elements that are not
part of the document tree, this test also adjusts the assertion that checks
this in the following ways:
* Calls GetComposedDoc() instead of GetCrossShadowCurrentDoc() since the
latter is deprecated.
* Moves it from RequestRestyle to FlushAnimations since, depending on how we
refactor this code in the future, it's possible we might end up calling
RequestRestyle even for animations on elements that have been removed from the
document but we shouldn't call FlushAnimations in this case.
We currently determine if we need refresh driver ticks when composing style
but sometimes we might not need ticks for composing style but we might need
one more tick in order to queue a final end event. Currently, this doesn't
seem to be a problem because FlushAnimations calls Animation::Tick where we
queue up events. When we remove the call to Animation::Tick from
FlushAnimations in order to make FlushAnimations purely responsible for
posting restyles, however, we will create a situation where we might mark an
animation collection as no longer needing refreshes and not simultaneously
queueing the corresponding event. If another animation collection is deleted in
the meantime we may trigger the code that causes us to disassociate from the
refresh driver and the corresponding event will never be dispatched.
Long-term (bug 1195180) we will check if it we can stop observing the refresh
driver and queue events in the same step. Until then, this patch adds a method
to detect this particular situation and uses it to avoid unregistering from
the refresh driver while we still have end events to queue.
In bug 1195180 we plan to tick animations from their timeline where they
are stored in a hashtable. As a result, we will not visit them in order of
their associated target element (indeed, part of the reason we are doing
this is to support animations that do not have, or even have multiple target
elements).
The current animation mutation observer batching mechanism, however, assumes
that we visit each target element in turn and make all the necessary work at
once. In order to support visiting animations in a potentially random order
this patch reworks the animation mutation observer batching mechanism so that
it can support batching multiple elements at once.
Now KeyframeEffect.SetTiming() updates the owning animation timing and relavance, so
we don't need to call each methods respectively for the animation any more.
When updating the cascade results between transitions and animations, if we
detect a change we force an update by taking the following steps:
a. Updating the animation generation on the restyle manager
b. Updating the animation generation on the collection
c. Iterating over all the properties animated by the collection and, for
each property that we can animate on the compositor, posting a restyle
event with the appropriate change hint (nsChangeHint_UpdateTransformLayer
or nsChangeHint_UpdateTransformOpacity)
d. Marking the collection as needing refreshes
e. Clearing the style rule refresh time so we generate a new style rule in
EnsureStyleRuleFor
As it turns out, the newly-added
AnimationCollection::RequestRestyle(RestyleType::Layer) already performs a, b,
d, and e. It also:
* Ensures we are observing the refresh driver if need be (should have no effect
in this case)
* Clears the last animation style update time on the pres context so that
subsequent calls to FlushPendingNotifications will update animation style
(it seems like we probably should have been doing this for changes to cascade
results anyway)
* Posts a restyle event with restyle hint eRestyle_CSSTransitions or
eRestyle_CSSAnimations
* Marks the document as needing a style flush (irrelevant since posting
a restyle event does this anyway)
The only missing piece that would prevent using RequestRestyle in place of this
code when updating cascade results is (c) from the list above. However, (c)
should not be necessary since ElementRestyler::AddLayerChangesForAnimation()
explicitly checks for out-of-date layer animation generation numbers and adds
the appropriate change hints (nsChangeHint_UpdateTransformLayer etc.) to the
change list.
EnsureStyleRuleFor contains logic for performing throttled updates to the style
rule but it is only used in one case: inside
nsTransitionManager::UpdateCascadeResults to determine what properties are
being animated by CSS animations.
We would like to remove throttling logic from EnsureStyleRuleFor altogether but
if that one case where it is currently used is run on every tick then removing
this logic could effectively mean we end up updating the style rule on every
tick. Fortunately nsTransitionManager::UpdateCascadeResults is only called
in the following cases:
1. From nsTransitionManager::StyleContextChanged (via
TransitionManager::UpdateCascadeResultsWithTransitions), when we are
processing style changes for transitions.
2. From AnimationCollection::EnsureStyleRuleFor (via
nsAnimationManager::MaybeUpdateCascadeResults and
nsTransitionManager::UpdateCascadeResultsWithAnimations), when we are
updating the animation style rule from CSS animations.
3. From nsAnimationManager::CheckAnimationRule (via
TransitionManager::UpdateCascadeResultsWithAnimationsToBeDestroyed), when
we are processing style changes for CSS animations.
None of these things should be happenning on a regular throttle-able tick so by
removing this logic we shouldn't be causing any additional work.
I have verified, using a test case that combines transitions and animations on
the same property, that we have the same behavior with regard to calling
EnsureStyleRuleFor both before and after this patch (specifically we avoid
calling it altogether while running only the transition but when the animation
starts and clobbers the transition we end up calling EnsureStyleRuleFor once on
each tick).
We want to move the newly-introduced RequestRestyle call from FlushAnimations
to Animation::Tick. However, nsAnimationManager::CheckAnimationRule calls
Animation::Tick so this would cause us to start posting animation restyles
within a restyle.
Typically, Animations have an effect (currently there is only one type of
effect: KeyframeEffectReadOnly) and when there is any change in timing they
pass it down to their effect. However, the Animation is dependent on the
duration of the effect for determining if it is "finished" or not. As a result,
when an effect's timing changes, the owning Animation needs to know.
(The way this *should* work is that effects should tell their animation or
trigger some chain of events that causes animation's to update themselves.
However, the current implementation of effects is fairly primitive and does
not do this or even have a reference to the owning Animation. When we
implement the script API for updating the timing properties of effects we will
have to fix this but for now it is up to code in layout/style to update the
Animation when it touches the corresponding effect's timing.)
nsAnimationManager::CheckAnimationRule currently does this by calling
Animation::Tick() which ensures the Animation's finished state is updated
accordingly.
Ultimately we want to ensure that Animation::Tick is called exactly once per
frame (and at the appropriate point in that frame) so we'd like to remove this
call from CheckAnimationRule.
This patch achieves that by:
* Making Animation::SetEffect update the animation's timing - this is necessary
for animations that are created by CheckAnimationRule and will be
necessary when once we make Animation.effect writeable from script anyway.
* Calling Animation::SetEffect even for the case when we are updating the
existing effect.
Another side-effect of calling Animation::Tick within
nsAnimationManager::CheckAnimationRule is that CSSAnimation::Tick queues
events. There are some tests (e.g. layout/style/test/test_animations.html) that
assume that animationstart events are dispatched immediately when new
animations are created. That will change with bug 1134163 but for now we
should maintain this existing behavior since changing this might introduce
compatibility issues that are best dealt with as a separate bug rather than
blocking this refactoring. To that end, this patch also explicitly queues
animationstart events for newly-created animations.
nsTransitionManager::WillRefresh and nsAnimationManager::WillRefresh are now
identical and all methods they call exist on CommonAnimationManager so we
can unify them there.
The implementations of FlushAnimations and FlushTransitions should now be all
but equivalent so this patch combines them into a single implementation on
CommonAnimationManager.
Regarding some of the minor differences between the two methods:
* The combined implementation drops the check for an empty list of collections
found only in FlushTransitions. This seems like a very minor optimization
that could possibly cause us to fail to unregister from the refresh driver
if we forgot to do so when removing the last collection.
* The combined implementation uses the loop implementation from FlushAnimations
since it is more compact.
This patch also removes the extra nested scope since it doesn't seem necessary.
This patch moves the additional checks (beyond those of Animation::CanThrottle)
from FlushAnimations/FlushTransitions to AnimationCollection::RequestRestyle.
These checks are on a per-collection basis hence it makes sense for the
collection to perform them. This also moves logic out of the managers which is
needed if we want to support script-based animations without introducing another
manager.
Ultimately we want to move throttling logic to AnimationCollection and
Animation::Tick (and later to KeyframeEffect::SetParentTime). This is so that
we can support script-generated animations without having to introduce yet
another manager.
To that end this patch introduces a method on AnimationCollection that can be
called from Animation::Tick to perform the necessary notifications needed to
update style.
Later in this patch series we will extend RequestRestyle to incorporate more of
the throttling logic and further extend it to cover some of the other
notifications such as updating layers.
This patch tracks whether or not we have already posted a restyle for animation
to avoid making redundant calls. Calls to nsIDocument::SetNeedStyleFlush are
cheap and more difficult to detect when they have completed so we don't filter
redundant calls in the Restyle::Throttled case.
If mHasPendingAnimationRestyle is set and AnimationCommon::EnsureStyleRuleFor
is *never* called then we could arrive at situation where we fail to make post
further restyles for animation.
I have verified that if we fail to reset mHasPendingAnimationRestyle at the
appropriate point (e.g. resetting it at the end of EnsureStyleRuleFor *after*
the early-returns) then a number of existing tests fail.
Furthermore, I have observed that it is reset by the beginning of each tick
in almost every case except for a few instances of browser mochitests such as
browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js.
In this case, during the async cleanup of the test, we have an opacity
transition on a vbox element that becomes display:none and appears to be skipped
during restyling. However, even in this case, EnsureStyleRuleFor is called
within one or at most two ticks and mHasPendingAnimationRestyle flag is cleared
(i.e. it does not get stuck).
In FlushTransitions and FlushAnimations we use different mechanisms to see if a
transition/animation can be throttled on the current tick.
FlushTransitions calls Animation::CanThrottle whilst FlushAnimations calls
EnsureStyleRuleFor and checks if the rule has changed or not. These are not as
completely different as they might seem at first since, internally,
EnsureStyleRuleFor calls Animation::CanThrottle.
We would like to unify this behavior and simply use Animation::CanThrottle in
FlushAnimations as we do in FlushTransitions.
First, however, we have to account for the differences in these approaches:
1. Using the result of EnsureStyleRuleFor means we may *not* call
PostRestyleForAnimation if an animation collection's mNeedsRefreshes member
is false.
This member is false when all animations have finished (or there are no
animations in the collection). In this case EnsureStyleRuleFor will not
update the style rule and we will end up assuming the tick can be throttled.
*However*, in the case that all animations are finished
Animation::CanThrottle will *also* return true (technically it will return
false until we compose style for the first time after becoming finished but
beyond that one moment it will return true) so skipping this check by using
Animation::CanThrottle instead of EnsureStyleRuleFor should not
make a significant difference.
2. Using the result of EnsureStyleRuleFor will mean that if we have already
updated the style rule within a given tick we will avoid calling
PostRestyleForAnimation (and call SetNeedStyleFlush instead). This can
happen the first time we call FlushAnimations from
PresShell::FlushPendingNotifications. (When we call FlushAnimations from
nsAnimationManager::WillRefresh mStyleRuleRefreshTime will be stale and we
won't apply this optimization. Furthermore after the first call to
PresShell::FlushPendingNotifications we will typically skip calling
FlushAnimations since PresShell::StyleUpdateForAllAnimationsIsUpToDate will
typically return true).
This seems like a possibly useful optimization although it is surprising we
don't do the same for transitions. Note that this optimization applies
regardless of whether we are performing a throttleable flush or not. That is,
even if we pass CommonAnimationManager::Cannot_Throttle we will still end up
throttling the tick in this case. Furthermore, we will mark the document as
needing a style flush even though this does not appear to be necessary.
This patch copies this optimization (checking if mStyleRuleRefreshTime) to
FlushAnimations so we can maintain this behavior when calling
Animation::CanThrottle instead of EnsureStyleRuleFor. It also applies the
same behavior to FlushTransitions for consistency (and so we can later
combine FlushAnimations and FlushTransitions).
Note that we apply this optimization *before* calling Tick since it should
only apply once we have already Tick'ed the animations in the collection.
We will first hit FlushAnimations as a result of the refresh driver calling
nsAnimationManager/nsTransitionManager::WillRefresh at which point
mStyleRuleRefreshTime should be stale. Using this order not only saves
redundant work but also makes moving the restyle code to Animation later on
more straightforward.
(In future we will divorce WillRefresh and FlushAnimations and only call
Tick in WillRefresh and only perform this optimization FlushAnimations.)
3. Using the result of EnsureStyleRuleFor means that while checking if we can
throttle or not we also update the style rule in FlushAnimations. That seems
like an odd side-effect particularly since FlushTransitions doesn't do the
same thing.
Prior to this patch, CSSAnimation defined a method for converting an
nsCSSPseudoElements::Type to a nsString (but only for the set of
pseudo-elements that can have animations). We would like to re-use this
when setting up transition events so this patch moves it to
AnimationCollection. Re-using this method more widely means we can make
a few further simplifications to the code.
This patch extracts a utility class for queueing up a series of EventInfo
objects (of templated type) and then dispatching them. This covers the event
queuing behavior in nsAnimationManager so that we can reuse it in
nsTransitionManager.
The long-term plan is to drop the mozilla::css namespace altogether. Before we
go to much further with refactoring code in AnimationCommon, we should drop
usage of the mozilla::css namespace. Specifically, this patch moves the
CommonAnimationManager and AnimValuesStyleRule classes to the mozilla namespace.
This patch prepares the way for script-generated events by making
event dispatch a separate process that happens after sampling animations.
This will allow us to sample animations from their associated timeline
(removing the need for a further manager to tracker script-generated
animations).
Furthermore, once we sample animations from timelines the order in which they
are sampled is likely to be more or less random so by making event dispatch at
separate step, we have an opportunity to sort the events and dispatch in
a consistent and sensible order. It also ensures that event callbacks will
not be run until all animations (including transitions) have been updated
ensuring they see a consistent view of timing properties.
This patch only affects event handling for CSS animations. Transitions will
be dealt with in a subsequent patch.
Prior to this patch, CSSAnimation defined a method for converting an
nsCSSPseudoElements::Type to a nsString (but only for the set of
pseudo-elements that can have animations). We would like to re-use this
when setting up transition events so this patch moves it to
AnimationCollection. Re-using this method more widely means we can make
a few further simplifications to the code.
This patch extracts a utility class for queueing up a series of EventInfo
objects (of templated type) and then dispatching them. This covers the event
queuing behavior in nsAnimationManager so that we can reuse it in
nsTransitionManager.
The long-term plan is to drop the mozilla::css namespace altogether. Before we
go to much further with refactoring code in AnimationCommon, we should drop
usage of the mozilla::css namespace. Specifically, this patch moves the
CommonAnimationManager and AnimValuesStyleRule classes to the mozilla namespace.
This patch prepares the way for script-generated events by making
event dispatch a separate process that happens after sampling animations.
This will allow us to sample animations from their associated timeline
(removing the need for a further manager to tracker script-generated
animations).
Furthermore, once we sample animations from timelines the order in which they
are sampled is likely to be more or less random so by making event dispatch at
separate step, we have an opportunity to sort the events and dispatch in
a consistent and sensible order. It also ensures that event callbacks will
not be run until all animations (including transitions) have been updated
ensuring they see a consistent view of timing properties.
This patch only affects event handling for CSS animations. Transitions will
be dealt with in a subsequent patch.
The connection between an Animation and an AnimationTimeline is optional. That
is, it is possible to have an Animation without an AnimationTimeline. Until now
we have often just assumed the timeline will be set but eventually we need to
support the possibility of the timeline being null. Indeed, later in this patch
series we will set the timeline out-of-band (i.e. not in the constructor) using
SetTimeline which opens up the possibility that timeline will be null for
a period of time.
This patch paves the way for having an optional timeline by storing the global
used for, e.g. creating promises, on the Animation object itself.
--HG--
extra : commitid : Ew9Zp4t36lV
extra : rebase_source : 16c9de9525a3562ff10e41fdf1602384a4e366e3