This patch makes ElementAnimations::GetPositionInIteration return
a ComputedTiming object instead of just a time portion (time fraction).
Since the ComputedTiming object includes phase information, we can fix those
parts of EnsureStyleRule and GetEventsAt that were temporarily using the time
portion to guess if the animation might have finished or not.
This patch moves event queuing out of EnsureStyleRuleFor into a separate method.
This is a preparatory step towards making GetPositionInIteration into a more
generic method for calculating the current time fraction.
In order to achieve this, GetPositionInIteration needs to be able to calculate
the correct time portion for times outside the range [0, 1] even when it is not
passed a ElementAnimation object. Specifically, it needs the fill mode of the
animation to be passed in.
(Rather than using FillForwards/FillBackwards this patch just compares the
NS_STYLE_ANIMATION_FILL_MODE_* values directly but FillForwards/FillBackwards
are restored in a subsequent patch when they are added to the struct used to
lump the timing parameters together.)
There are a number of places where positionInIteration is used to determine if
the current sample occurs in the active phase or after. This is sub-optimal but
is fixed in a subsequent patch in this series.
The actual work of removing event queuing from GetPositionInIteration is
deferred to a subsequent patch in order to keep the changes as small as
possible. This patch simply makes separate calls to GetPositionInIteration for
interpolating and for event queuing.
As a result, transitions are now stored using a pointer to the base class,
mozilla::ElementAnimation. We downcast to a transition only when necessary. No
error-checking of the result of AsTransition is performed since we only ever
call it on the mAnimations member of ElementTransitions.
We currently have mozilla::StyleAnimation as well as nsStyleAnimation. This
patch renames StyleAnimation back to ElementAnimation.
Although ElementAnimation is very similar to ElementAnimations, in the near
future we expect to retire ElementAnimations and replace it with a common
AnimationSet-like structure that is covers the features of ElementAnimations and
ElementTransitions.
This patch takes StyleAnimation and makes it ref-counted heap object. This
should allow us to store StyleAnimation and its subclasses (transitions only
currently) in a consistent fashion (an array of base-class pointers).
Furthermore, this will be helpful if we want these things to be pointed to
from Javascript objects that may, for example, preserve their lifetime beyond
that of the element that currently owns them.
This patch also introduces a typedef for an array of refptrs to StyleAnimation
objects (and similarly for the subclass ElementPropertyTransition) to simplify
the code somewhat.
We need a basic representation of animations from which we can derive subclasses
to represent specific cases such as transitions. For now we will retrofit
ElementAnimation for that purpose hence renaming it to StyleAnimation.
This patch removes the "using namespace mozilla::layers" line from
AnimationCommon.cpp since the unified build system concatenates several files
together before compiling making using declarations like this leak into other
files potentially creating ambiguities. Previously, when we were calling
ElementAnimation, 'Animation', there were ambiguities between
mozilla::layers::Animation and this new 'Animation' class. In general, it is
probably a good idea to limit the scope of these using declarations so I've kept
that change.
This patch relocates ElementAnimation from nsAnimationManager.{h,cpp} to
AnimationCommon.{h,cpp} and in the process moves it into the mozilla::css
namespace.
ElementAnimation::HasAnimationOfProperty doesn't seem to be overridden anywhere.
I suspect it was a copy-paste mistake because the methods of the same name on
ElementAnimations, ElementTransitions, and CommonElementAnimationData are
virtual.
As part of moving towards more shared data structures for animation, this patch
makes ElementPropertyTransition inherit from ElementAnimation. At the same time
we switch from storing the target property, start/end values, start time, delay,
and timing function on the transition to the corresponding location in
ElementAnimation.
Since nsDisplayList::AddAnimationsAndTransitionsToLayer was already doing this
conversion in order to create animations to pass to the compositor thread, we
can remove the conversion code from there and just use the ElementAnimation data
structures as-is.
A number of assertions are added to verify that transitions are set up as
expected (namely, they have only a single property-animation with a single
segment). As we move to more generic handling of animations and transitions
these assertions should disappear.
When we have a backwards fill and we sample at *exactly* the start of the
animation on the next refresh driver tick, when we get to
RestyleManager::ComputeStyleChangeFor (or more specifically
ElementRestyler::CaptureChange) we notice that the style hasn't changed (since
the first frame of the animation produces the same value as the backwards fill)
and end up with an empty change list. As a result we never schedule a view
manager flush and rebuild the layer. Hence, the animation never gets sent to the
compositor thread. On the next tick we're already throttling the main thread.
This patch fixes this by applying the same approach as is used for transitions,
that is, explicitly marking which animations are running on the compositor
thread so we know if we need to trigger a layer transaction or not. This should
not only be more robust than the previous code but also facilitate aligning
animations and transitions code (bug 880596).
This changes the behavior of the CanPerformOnCompositorThread methods of
both ElementAnimations and ElementTransitions to check that the
respective animations or transitions are actually running. This is ok
because:
- The main caller is nsLayoutUtils::HasAnimationsForCompositor, and all
of its callers pretty clearly want the more restricted behavior (they're
concerned with layer activity)
- The only other callers of these functions are
nsAnimationManager::FlushAnimations and
nsTransitionManager::FlushTransitions (determining when to do
throttling), nsAnimationManager::GetAnimationsForCompositor (whose
only caller,
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer, also checks
IsRunningAt). I think these also all want or are fine with having
the IsRunningAt check.
As to the actual changes:
- In the animation manager, I think it's a mistake that
ElementAnimation::IsRunningAt didn't already check
mIterationDuration, since we throw out animations with a bad
iteration-duration in ElementAnimations::EnsureStyleRuleFor. So this
makes that change as well.
- In the transition manager, IsRunningAt already checks
!IsRemovedSentinel().
I've confirmed in gdb on a device that this fixes the repeated
nsIFrame::SchedulePaint calls that were the symptom of this bug.
I believe this patch also makes it so that a short animation of a
property that can't be animated on the compositor doesn't prevent the
entire duration of the animation of a property that can from being
throttled (having the main thread style updates suppressed).