mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 978712 - Prevent non-running transitions and animations (animations or transitions during their delay period, and animations after they finish) from repeatedly poking layer activity because we think we can run them on the compositor. r=heycam
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).
This commit is contained in:
parent
0461432ae1
commit
38a6cfb99b
@ -327,7 +327,7 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
bool
|
||||
ElementAnimation::IsRunningAt(TimeStamp aTime) const
|
||||
{
|
||||
if (IsPaused()) {
|
||||
if (IsPaused() || mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -398,8 +398,7 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
||||
bool hasTransform = false;
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const ElementAnimation& anim = mAnimations[animIdx];
|
||||
if (anim.mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
// No animation data
|
||||
if (!anim.IsRunningAt(now)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -174,8 +174,21 @@ struct ElementAnimations MOZ_FINAL
|
||||
aPresContext->PresShell()->RestyleForAnimation(mElement, styleHint);
|
||||
}
|
||||
|
||||
// True if this animation can be performed on the compositor thread.
|
||||
// If aFlags contains CanAnimate_AllowPartial, returns whether the
|
||||
// state of this element's animations at the current refresh driver
|
||||
// time contains animation data that can be done on the compositor
|
||||
// thread. (This is useful for determining whether a layer should be
|
||||
// active, or whether to send data to the layer.)
|
||||
// If aFlags does not contain CanAnimate_AllowPartial, returns whether
|
||||
// the state of this element's animations at the current refresh driver
|
||||
// time can be fully represented by data sent to the compositor.
|
||||
// (This is useful for determining whether throttle the animation
|
||||
// (suppress main-thread style updates).)
|
||||
// Note that when CanPerformOnCompositorThread returns true, it also,
|
||||
// as a side-effect, notifies the ActiveLayerTracker. FIXME: This
|
||||
// should probably move to the relevant callers.
|
||||
virtual bool CanPerformOnCompositorThread(CanAnimateFlags aFlags) const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool HasAnimationOfProperty(nsCSSProperty aProperty) const MOZ_OVERRIDE;
|
||||
|
||||
// False when we know that our current style rule is valid
|
||||
|
@ -171,10 +171,10 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
||||
bool existsProperty = false;
|
||||
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
|
||||
const ElementPropertyTransition& pt = mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
if (!pt.IsRunningAt(now)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
existsProperty = true;
|
||||
|
||||
if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(mElement,
|
||||
|
@ -87,6 +87,20 @@ struct ElementTransitions MOZ_FINAL
|
||||
void EnsureStyleRuleFor(mozilla::TimeStamp aRefreshTime);
|
||||
|
||||
virtual bool HasAnimationOfProperty(nsCSSProperty aProperty) const MOZ_OVERRIDE;
|
||||
|
||||
// If aFlags contains CanAnimate_AllowPartial, returns whether the
|
||||
// state of this element's transitions at the current refresh driver
|
||||
// time contains transition data that can be done on the compositor
|
||||
// thread. (This is useful for determining whether a layer should be
|
||||
// active, or whether to send data to the layer.)
|
||||
// If aFlags does not contain CanAnimate_AllowPartial, returns whether
|
||||
// the state of this element's transitions at the current refresh driver
|
||||
// time can be fully represented by data sent to the compositor.
|
||||
// (This is useful for determining whether throttle the transition
|
||||
// (suppress main-thread style updates).)
|
||||
// Note that when CanPerformOnCompositorThread returns true, it also,
|
||||
// as a side-effect, notifies the ActiveLayerTracker. FIXME: This
|
||||
// should probably move to the relevant callers.
|
||||
virtual bool CanPerformOnCompositorThread(CanAnimateFlags aFlags) const MOZ_OVERRIDE;
|
||||
|
||||
// Either zero or one for each CSS property:
|
||||
|
Loading…
x
Reference in New Issue
Block a user