Commit 39b28ec3 authored by haozhe's avatar haozhe Committed by Commit Bot

Sort getAnimation result based on the animation classes

Currently, we are sorting animations by creation order. This update the
animation compositing order to first sort by animation class
priority, as per spec
(https://drafts.csswg.org/web-animations/#dom-document-getanimations).

This inter-element composition order is used and tested by
getAnimations.

Bug: 993365
Change-Id: I30dd1c504165baa1120b73ab7e18f0b775df8bff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1993677
Commit-Queue: Hao Sheng <haozhes@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733394}
parent 10869dc2
......@@ -90,6 +90,28 @@ double Min(base::Optional<double> a, double b) {
return b;
}
Animation::AnimationClassPriority AnimationPriority(
const Animation* animation) {
// According to the spec:
// https://drafts.csswg.org/web-animations/#animation-class,
// CSS tranisiton has a lower composite order than the CSS animation, and CSS
// animation has a lower composite order than other animations. Thus,CSS
// transitions are to appear before CSS animations and CSS animations are to
// appear before other animations
// TODO: When animations are disassociated from their element they are sorted
// by their sequence number, i.e. kDefaultPriority. See
// https://drafts.csswg.org/css-animations-2/#animation-composite-order and
// https://drafts.csswg.org/css-transitions-2/#animation-composite-order
Animation::AnimationClassPriority priority;
if (animation->IsCSSTransition())
priority = Animation::AnimationClassPriority::kCssTransitionPriority;
else if (animation->IsCSSAnimation())
priority = Animation::AnimationClassPriority::kCssAnimationPriority;
else
priority = Animation::AnimationClassPriority::kDefaultPriority;
return priority;
}
void RecordCompositorAnimationFailureReasons(
CompositorAnimations::FailureReasons failure_reasons) {
// UMA_HISTOGRAM_ENUMERATION requires that the enum_max must be strictly
......@@ -413,6 +435,15 @@ void Animation::PostCommit(double timeline_time) {
}
}
bool Animation::HasLowerCompositeOrdering(const Animation* animation1,
const Animation* animation2) {
AnimationClassPriority priority1 = AnimationPriority(animation1);
AnimationClassPriority priority2 = AnimationPriority(animation2);
if (priority1 != priority2)
return priority1 < priority2;
return animation1->SequenceNumber() < animation2->SequenceNumber();
}
void Animation::NotifyReady(double ready_time) {
// Complete the pending updates prior to updating the compositor state in
// order to ensure a correct start time for the compositor state without the
......
......@@ -82,6 +82,15 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
kFinished
};
// Priority for sorting getAnimation by Animation class, arranged from lowest
// priority to highest priority as per spec:
// https://drafts.csswg.org/web-animations/#dom-document-getanimations
enum AnimationClassPriority {
kCssTransitionPriority,
kCssAnimationPriority,
kDefaultPriority
};
static Animation* Create(AnimationEffect*,
AnimationTimeline*,
ExceptionState& = ASSERT_NO_EXCEPTION);
......@@ -225,12 +234,11 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void PostCommit(double timeline_time);
unsigned SequenceNumber() const override { return sequence_number_; }
int CompositorGroup() const { return compositor_group_; }
static bool HasLowerPriority(const Animation* animation1,
const Animation* animation2) {
return animation1->SequenceNumber() < animation2->SequenceNumber();
}
static bool HasLowerCompositeOrdering(const Animation* animation1,
const Animation* animation2);
bool EffectSuppressed() const override { return effect_suppressed_; }
void SetEffectSuppressed(bool);
......
......@@ -1029,10 +1029,10 @@ TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) {
EXPECT_TRUE(element->GetElementAnimations()->Animations().IsEmpty());
}
TEST_F(AnimationAnimationTestNoCompositing, HasLowerPriority) {
TEST_F(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) {
Animation* animation1 = timeline->Play(nullptr);
Animation* animation2 = timeline->Play(nullptr);
EXPECT_TRUE(Animation::HasLowerPriority(animation1, animation2));
EXPECT_TRUE(Animation::HasLowerCompositeOrdering(animation1, animation2));
}
TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) {
......
......@@ -81,7 +81,8 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) {
for (Animation* animation : animations_needing_update_)
animations.push_back(animation);
std::sort(animations.begin(), animations.end(), Animation::HasLowerPriority);
std::sort(animations.begin(), animations.end(),
Animation::HasLowerCompositeOrdering);
for (Animation* animation : animations) {
if (!animation->Update(reason))
......
......@@ -84,7 +84,7 @@ bool ConsiderAnimationAsIncompatible(const Animation& animation,
return true;
case Animation::kPaused:
case Animation::kFinished:
if (Animation::HasLowerPriority(&animation, &animation_to_add)) {
if (Animation::HasLowerCompositeOrdering(&animation, &animation_to_add)) {
return effect_to_add.AffectedByUnderlyingAnimations();
}
return true;
......
......@@ -56,7 +56,7 @@ void UpdateAnimationTiming(
bool CompareAnimations(const Member<Animation>& left,
const Member<Animation>& right) {
return Animation::HasLowerPriority(left.Get(), right.Get());
return Animation::HasLowerCompositeOrdering(left.Get(), right.Get());
}
} // namespace
......
......@@ -6,7 +6,7 @@ FAIL Order of CSS Animations - across elements assert_equals: Order of second an
PASS Order of CSS Animations - across and within elements
FAIL Order of CSS Animations - markup-bound vs free animations assert_equals: getAnimations returns markup-bound and free animations expected 2 but got 1
FAIL Order of CSS Animations - free animations assert_equals: getAnimations returns free animations expected 2 but got 0
FAIL Order of CSS Animations and CSS Transitions assert_class_string: Transition comes first expected "[object CSSTransition]" but got "[object CSSAnimation]"
PASS Order of CSS Animations and CSS Transitions
PASS Finished but filling CSS Animations are returned
PASS Finished but not filling CSS Animations are not returned
PASS Yet-to-start CSS Animations are returned
......
......@@ -3,7 +3,7 @@ PASS getAnimations for non-animated content
PASS getAnimations for CSS Animations
PASS getAnimations returns CSSAnimation objects for CSS Animations
PASS getAnimations for multi-property animations
FAIL getAnimations for both CSS Animations and CSS Transitions at once assert_class_string: First-returned animation is the CSS Transition expected "[object CSSTransition]" but got "[object CSSAnimation]"
PASS getAnimations for both CSS Animations and CSS Transitions at once
PASS getAnimations for CSS Animations that have finished
PASS getAnimations for CSS Animations that have finished but are forwards filling
PASS getAnimations for CSS Animations with animation-name: none
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment