diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-26 13:57:00 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-11-02 11:31:01 +0000 |
commit | 1943b3c2a1dcee36c233724fc4ee7613d71b9cf6 (patch) | |
tree | 8c1b5f12357025c197da5427ae02cfdc2f3570d6 /chromium/third_party/blink/renderer/core/animation | |
parent | 21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (diff) | |
download | qtwebengine-chromium-1943b3c2a1dcee36c233724fc4ee7613d71b9cf6.tar.gz |
BASELINE: Update Chromium to 94.0.4606.111
Change-Id: I924781584def20fc800bedf6ff41fdb96c438193
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/animation')
95 files changed, 1931 insertions, 1977 deletions
diff --git a/chromium/third_party/blink/renderer/core/animation/OWNERS b/chromium/third_party/blink/renderer/core/animation/OWNERS index e7571208635..0e56346f40d 100644 --- a/chromium/third_party/blink/renderer/core/animation/OWNERS +++ b/chromium/third_party/blink/renderer/core/animation/OWNERS @@ -1,10 +1,6 @@ flackr@chromium.org kevers@chromium.org -majidvp@chromium.org smcgruer@chromium.org # Legacy owners: alancutter@chromium.org -ericwilligers@chromium.org - -per-file compositor_*=loyso@chromium.org diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.cc b/chromium/third_party/blink/renderer/core/animation/animatable.cc index 3cea3241785..1a4aed042c1 100644 --- a/chromium/third_party/blink/renderer/core/animation/animatable.cc +++ b/chromium/third_party/blink/renderer/core/animation/animatable.cc @@ -4,9 +4,8 @@ #include "third_party/blink/renderer/core/animation/animatable.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_get_animations_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation.h" @@ -45,7 +44,6 @@ void ReportPermissionsPolicyViolationsIfNecessary( } } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* CoerceEffectOptions( const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options) { switch (options->GetContentType()) { @@ -63,18 +61,6 @@ V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* CoerceEffectOptions( NOTREACHED(); return nullptr; } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions( - UnrestrictedDoubleOrKeyframeAnimationOptions options) { - if (options.IsKeyframeAnimationOptions()) { - return UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( - options.GetAsKeyframeAnimationOptions()); - } else { - return UnrestrictedDoubleOrKeyframeEffectOptions::FromUnrestrictedDouble( - options.GetAsUnrestrictedDouble()); - } -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } // namespace @@ -82,11 +68,7 @@ UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions( Animation* Animatable::animate( ScriptState* script_state, const ScriptValue& keyframes, -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - const UnrestrictedDoubleOrKeyframeAnimationOptions& options, -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ExceptionState& exception_state) { if (!script_state->ContextIsValid()) return nullptr; @@ -106,22 +88,12 @@ Animation* Animatable::animate( ReportPermissionsPolicyViolationsIfNecessary(*element->GetExecutionContext(), *effect->Model()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) if (!options->IsKeyframeAnimationOptions()) return element->GetDocument().Timeline().Play(effect); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - if (!options.IsKeyframeAnimationOptions()) - return element->GetDocument().Timeline().Play(effect); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animation; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const KeyframeAnimationOptions* options_dict = options->GetAsKeyframeAnimationOptions(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - const KeyframeAnimationOptions* options_dict = - options.GetAsKeyframeAnimationOptions(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) if (!options_dict->hasTimeline()) { animation = element->GetDocument().Timeline().Play(effect); } else if (AnimationTimeline* timeline = options_dict->timeline()) { diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.h b/chromium/third_party/blink/renderer/core/animation/animatable.h index 5ed319271f4..03d9603b65f 100644 --- a/chromium/third_party/blink/renderer/core/animation/animatable.h +++ b/chromium/third_party/blink/renderer/core/animation/animatable.h @@ -43,7 +43,6 @@ class ExceptionState; class GetAnimationsOptions; class ScriptState; class ScriptValue; -class UnrestrictedDoubleOrKeyframeAnimationOptions; class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble; // https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin @@ -53,18 +52,11 @@ class CORE_EXPORT Animatable { // called on. virtual Element* GetAnimationTarget() = 0; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animate( ScriptState* script_state, const ScriptValue& keyframes, const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, ExceptionState& exception_state); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - Animation* animate(ScriptState*, - const ScriptValue&, - const UnrestrictedDoubleOrKeyframeAnimationOptions&, - ExceptionState&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Animation* animate(ScriptState*, const ScriptValue&, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/core/animation/animation.cc b/chromium/third_party/blink/renderer/core/animation/animation.cc index 4efce95eeaa..f11b55b34cd 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation.cc @@ -36,7 +36,6 @@ #include "base/metrics/histogram_macros.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" @@ -52,6 +51,7 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h" #include "third_party/blink/renderer/core/animation/timing_calculations.h" +#include "third_party/blink/renderer/core/css/cssom/css_unit_values.h" #include "third_party/blink/renderer/core/css/properties/css_property_ref.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" @@ -186,18 +186,6 @@ bool GreaterThanOrEqualWithinTimeTolerance(const AnimationTimeDelta& a, return a_ms > b_ms; } -#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -V8CSSNumberish* CSSNumberishToV8CSSNumberish(const CSSNumberish& value) { - if (value.IsDouble()) { - return MakeGarbageCollected<V8CSSNumberish>(value.GetAsDouble()); - } else if (value.IsCSSNumericValue()) { - return MakeGarbageCollected<V8CSSNumberish>(value.GetAsCSSNumericValue()); - } - DCHECK(value.IsNull()); - return nullptr; -} -#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - } // namespace Animation* Animation::Create(AnimationEffect* effect, @@ -212,29 +200,40 @@ Animation* Animation::Create(AnimationEffect* effect, } DCHECK(IsA<DocumentTimeline>(timeline) || timeline->IsScrollTimeline()); - // TODO(crbug.com/1097041): Support 'auto' value. - if (timeline->IsScrollTimeline()) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - auto* time_range = To<ScrollTimeline>(timeline)->timeRange(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - DoubleOrScrollTimelineAutoKeyword time_range; - To<ScrollTimeline>(timeline)->timeRange(time_range); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - // TODO(crbug.com/1140602): Support progress based animations - // We are currently abusing the intended use of the "auto" keyword. We are - // using it here as a signal to use progress based timeline instead of - // having a range based current time. We are doing this maintain backwards - // compatibility with existing tests. - if ( -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - time_range->IsScrollTimelineAutoKeyword() -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - time_range.IsScrollTimelineAutoKeyword() -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - ) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "progress based animations are not supported"); + if (effect && timeline->IsProgressBasedTimeline()) { + if (effect->timing_.iteration_duration) { + if (effect->timing_.iteration_duration->is_inf()) { + exception_state.ThrowTypeError( + "Effect duration cannot be Infinity when used with Scroll " + "Timelines"); + return nullptr; + } + } else { + // TODO(crbug.com/1216527) + // Eventually we hope to be able to be more flexible with + // iteration_duration "auto" and its interaction with start_delay and + // end_delay. For now we will throw an exception if either delay is set. + // Once the spec (https://github.com/w3c/csswg-drafts/pull/6337) has been + // ratified, we will be able to better handle mixed scenarios like "auto" + // and time based delays. + + // If either delay or end_delay are non-zero, we can't yet handle "auto" + if (!effect->timing_.start_delay.is_zero() || + !effect->timing_.end_delay.is_zero()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Effect duration \"auto\" with delays is not yet implemented when " + "used with Scroll Timelines"); + return nullptr; + } + } + + if (effect->timing_.iteration_count == + std::numeric_limits<double>::infinity()) { + // iteration count of infinity makes no sense for scroll timelines + exception_state.ThrowTypeError( + "Effect iterations cannot be Infinity when used with Scroll " + "Timelines"); return nullptr; } } @@ -287,7 +286,9 @@ Animation::Animation(ExecutionContext* execution_context, compositor_state_(nullptr), compositor_pending_(false), compositor_group_(0), - effect_suppressed_(false) { + effect_suppressed_(false), + compositor_property_animations_have_no_effect_(false), + animation_has_no_effect_(false) { if (content_) { if (content_->GetAnimation()) { content_->GetAnimation()->cancel(); @@ -295,14 +296,16 @@ Animation::Animation(ExecutionContext* execution_context, } content_->Attach(this); } - document_ = timeline_ ? timeline_->GetDocument() - : To<LocalDOMWindow>(execution_context)->document(); - DCHECK(document_); - if (timeline_) + if (timeline_) { + document_ = timeline_->GetDocument(); + DCHECK(document_); timeline_->AnimationAttached(this); - else + } else { + document_ = To<LocalDOMWindow>(execution_context)->document(); + DCHECK(document_); document_->Timeline().AnimationAttached(this); + } probe::DidCreateAnimation(document_, sequence_number_); } @@ -323,7 +326,7 @@ void Animation::Dispose() { } AnimationTimeDelta Animation::EffectEnd() const { - return content_ ? content_->SpecifiedTiming().EndTimeInternal() + return content_ ? content_->NormalizedTiming().end_time : AnimationTimeDelta(); } @@ -346,6 +349,88 @@ absl::optional<double> Animation::TimelineTime() const { return timeline_ ? timeline_->CurrentTimeMilliseconds() : absl::nullopt; } +bool Animation::ConvertCSSNumberishToTime( + const V8CSSNumberish* numberish, + absl::optional<AnimationTimeDelta>& time, + String variable_name, + ExceptionState& exception_state) { + // This function is used to handle the CSSNumberish input for setting + // currentTime and startTime. Spec issue can be found here for this process: + // https://github.com/w3c/csswg-drafts/issues/6458 + + // Handle converting null + if (!numberish) { + time = absl::nullopt; + return true; + } + + if (timeline_ && timeline_->IsProgressBasedTimeline()) { + // Progress based timeline + if (numberish->IsCSSNumericValue()) { + CSSUnitValue* numberish_as_percentage = + numberish->GetAsCSSNumericValue()->to( + CSSPrimitiveValue::UnitType::kPercentage); + if (!numberish_as_percentage) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Invalid " + variable_name + + ". CSSNumericValue must be a percentage for " + "progress based animations."); + return false; + } + time = (numberish_as_percentage->value() / 100) * + timeline_->GetDuration().value(); + return true; + } else { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Invalid " + variable_name + ". Setting " + variable_name + + " using absolute time " + "values is not supported for progress based animations."); + return false; + } + } + + // Document timeline + if (numberish->IsCSSNumericValue()) { + CSSUnitValue* numberish_as_number = numberish->GetAsCSSNumericValue()->to( + CSSPrimitiveValue::UnitType::kNumber); + if (numberish_as_number) { + time = + AnimationTimeDelta::FromMillisecondsD(numberish_as_number->value()); + return true; + } + + CSSUnitValue* numberish_as_milliseconds = + numberish->GetAsCSSNumericValue()->to( + CSSPrimitiveValue::UnitType::kMilliseconds); + if (numberish_as_milliseconds) { + time = AnimationTimeDelta::FromMillisecondsD( + numberish_as_milliseconds->value()); + return true; + } + + CSSUnitValue* numberish_as_seconds = numberish->GetAsCSSNumericValue()->to( + CSSPrimitiveValue::UnitType::kSeconds); + if (numberish_as_seconds) { + time = AnimationTimeDelta::FromSecondsD(numberish_as_seconds->value()); + return true; + } + + // TODO (crbug.com/1232181): Look into allowing document timelines to set + // currentTime and startTime using CSSNumericValues that are percentages. + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Invalid " + variable_name + + ". CSSNumericValue must be either a number or a time value for " + "time based animations."); + return false; + } + + time = AnimationTimeDelta::FromMillisecondsD(numberish->GetAsDouble()); + return true; +} + // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation. void Animation::setCurrentTime(const V8CSSNumberish* current_time, ExceptionState& exception_state) { @@ -358,18 +443,11 @@ void Animation::setCurrentTime(const V8CSSNumberish* current_time, return; } - if (current_time->IsCSSNumericValue()) { - // Throw exception for CSSNumberish that is a CSSNumericValue - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Invalid startTime. CSSNumericValue not yet supported."); + absl::optional<AnimationTimeDelta> new_current_time; + // Failure to convert results in a thrown exception and returning false. + if (!ConvertCSSNumberishToTime(current_time, new_current_time, "currentTime", + exception_state)) return; - } - - DCHECK(current_time->IsDouble()); - // Convert from double to AnimationTimeDelta for internal use. - absl::optional<AnimationTimeDelta> new_current_time = - AnimationTimeDelta::FromMillisecondsD(current_time->GetAsDouble()); DCHECK(new_current_time); SetCurrentTimeInternal(new_current_time.value()); @@ -393,22 +471,6 @@ void Animation::setCurrentTime(const V8CSSNumberish* current_time, NotifyProbe(); } -#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - -// https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation. -void Animation::setCurrentTime(CSSNumberish current_time, - ExceptionState& exception_state) { - // Forward to the new implementation. - setCurrentTime(CSSNumberishToV8CSSNumberish(current_time), exception_state); -} - -void Animation::setCurrentTime(CSSNumberish current_time) { - NonThrowableExceptionState exception_state; - setCurrentTime(current_time, exception_state); -} - -#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation // See steps for silently setting the current time. The preliminary step of // handling an unresolved time are to be handled by the caller. @@ -451,31 +513,27 @@ void Animation::ResetHoldTimeAndPhase() { hold_phase_ = absl::nullopt; } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* Animation::startTime() const { if (start_time_) { - return MakeGarbageCollected<V8CSSNumberish>( - start_time_.value().InMillisecondsF()); + return ConvertTimeToCSSNumberish(start_time_.value()); } return nullptr; } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void Animation::startTime(CSSNumberish& startTime) const { - startTime = - start_time_ - ? CSSNumberish::FromDouble(start_time_.value().InMillisecondsF()) - : CSSNumberish(); + +V8CSSNumberish* Animation::ConvertTimeToCSSNumberish( + AnimationTimeDelta time) const { + if (timeline_ && timeline_->IsProgressBasedTimeline()) { + return To<ScrollTimeline>(*timeline_).ConvertTimeToProgress(time); + } + return MakeGarbageCollected<V8CSSNumberish>(time.InMillisecondsF()); } -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation V8CSSNumberish* Animation::currentTime() const { // 1. If the animation’s hold time is resolved, // The current time is the animation’s hold time. if (hold_time_.has_value()) { - return MakeGarbageCollected<V8CSSNumberish>( - hold_time_.value().InMillisecondsF()); + return ConvertTimeToCSSNumberish(hold_time_.value()); } // 2. If any of the following are true: @@ -497,43 +555,8 @@ V8CSSNumberish* Animation::currentTime() const { AnimationTimeDelta calculated_current_time = (timeline_time.value() - start_time_.value()) * playback_rate_; - return MakeGarbageCollected<V8CSSNumberish>( - calculated_current_time.InMillisecondsF()); -} -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -// https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation -void Animation::currentTime(CSSNumberish& currentTime) const { - // 1. If the animation’s hold time is resolved, - // The current time is the animation’s hold time. - if (hold_time_.has_value()) { - currentTime = - CSSNumberish::FromDouble(hold_time_.value().InMillisecondsF()); - return; - } - - // 2. If any of the following are true: - // * the animation has no associated timeline, or - // * the associated timeline is inactive, or - // * the animation’s start time is unresolved. - // The current time is an unresolved time value. - if (!timeline_ || !timeline_->IsActive() || !start_time_) - return; - - // 3. Otherwise, - // current time = (timeline time - start time) × playback rate - absl::optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime(); - - // An active timeline should always have a value, and since inactive timeline - // is handled in step 2 above, make sure that timeline_time has a value. - DCHECK(timeline_time.has_value()); - - AnimationTimeDelta calculated_current_time = - (timeline_time.value() - start_time_.value()) * playback_rate_; - - currentTime = - CSSNumberish::FromDouble(calculated_current_time.InMillisecondsF()); + return ConvertTimeToCSSNumberish(calculated_current_time); } -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool Animation::ValidateHoldTimeAndPhase() const { return hold_phase_ || @@ -576,6 +599,9 @@ bool Animation::PreCommit( !IsWithinAnimationTimeEpsilon(compositor_state_->start_time.value(), start_time_.value().InSecondsF())); + compositor_property_animations_have_no_effect_ = false; + animation_has_no_effect_ = false; + // FIXME: softChange && !hardChange should generate a Pause/ThenStart, // not a Cancel, but we can't communicate these to the compositor yet. @@ -612,6 +638,14 @@ bool Animation::PreCommit( } else { CancelIncompatibleAnimationsOnCompositor(); } + + compositor_property_animations_have_no_effect_ = + failure_reasons & + CompositorAnimations::kCompositorPropertyAnimationsHaveNoEffect; + animation_has_no_effect_ = + failure_reasons == + CompositorAnimations::kCompositorPropertyAnimationsHaveNoEffect; + DCHECK_EQ(kRunning, CalculateAnimationPlayState()); TRACE_EVENT_NESTABLE_ASYNC_INSTANT1( "blink.animations,devtools.timeline,benchmark,rail", "Animation", @@ -880,6 +914,15 @@ void Animation::setTimeline(AnimationTimeline* timeline) { AnimationPlayState old_play_state = CalculateAnimationPlayState(); absl::optional<AnimationTimeDelta> old_current_time = CurrentTimeInternal(); + // In some cases, we need to preserve the progress of the animation between + // the old timeline and the new one. We do this by storing the progress using + // the old current time and the effect end based on the old timeline. Pending + // spec issue: https://github.com/w3c/csswg-drafts/issues/6452 + double progress = 0; + if (old_current_time && !EffectEnd().is_zero()) { + progress = old_current_time.value() / EffectEnd(); + } + CancelAnimationOnCompositor(); // 3. Let the timeline of the animation be the new timeline. @@ -899,6 +942,11 @@ void Animation::setTimeline(AnimationTimeline* timeline) { document_->Timeline().AnimationAttached(this); SetOutdated(); + // Update content timing to be based on new timeline type. This ensures that + // EffectEnd() is returning a value appropriate to the new timeline. + if (content_ && timeline_) + content_->InvalidateNormalizedTiming(); + reset_current_time_on_resume_ = false; if (timeline) { @@ -921,7 +969,8 @@ void Animation::setTimeline(AnimationTimeline* timeline) { if (old_current_time) { reset_current_time_on_resume_ = true; start_time_ = absl::nullopt; - SetHoldTimeAndPhase(old_current_time, TimelinePhase::kInactive); + SetHoldTimeAndPhase(progress * EffectEnd(), + TimelinePhase::kInactive); } else if (PendingInternal()) { start_time_ = boundary_time; } @@ -932,7 +981,7 @@ void Animation::setTimeline(AnimationTimeline* timeline) { } } else if (old_current_time && old_timeline && !old_timeline->IsMonotonicallyIncreasing()) { - SetCurrentTimeInternal(old_current_time.value()); + SetCurrentTimeInternal(progress * EffectEnd()); } } @@ -994,19 +1043,12 @@ TimelinePhase Animation::CalculateCurrentPhase() const { // https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation void Animation::setStartTime(const V8CSSNumberish* start_time, ExceptionState& exception_state) { - if (start_time && start_time->IsCSSNumericValue()) { - // Throw exception for CSSNumberish that is a CSSNumericValue - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Invalid startTime. CSSNumericValue not yet supported."); - return; - } absl::optional<AnimationTimeDelta> new_start_time; - if (start_time) { - new_start_time = - AnimationTimeDelta::FromMillisecondsD(start_time->GetAsDouble()); - } + // Failure to convert results in a thrown exception and returning false. + if (!ConvertCSSNumberishToTime(start_time, new_start_time, "startTime", + exception_state)) + return; const bool had_start_time = start_time_.has_value(); @@ -1093,22 +1135,6 @@ void Animation::setStartTime(const V8CSSNumberish* start_time, NotifyProbe(); } -#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - -// https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation -void Animation::setStartTime(CSSNumberish start_time, - ExceptionState& exception_state) { - // Forward to the new implementation. - setStartTime(CSSNumberishToV8CSSNumberish(start_time), exception_state); -} - -void Animation::setStartTime(CSSNumberish start_time) { - NonThrowableExceptionState exception_state; - setStartTime(start_time, exception_state); -} - -#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - // https://drafts.csswg.org/web-animations-1/#setting-the-associated-effect void Animation::setEffect(AnimationEffect* new_effect) { // 1. Let old effect be the current associated effect of animation, if any. @@ -1930,24 +1956,19 @@ void Animation::setPlaybackRate(double playback_rate, // 4. If previous time is resolved, set the current time of animation to // previous time pending_playback_rate_ = absl::nullopt; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* previous_current_time = currentTime(); playback_rate_ = playback_rate; if (previous_current_time) { setCurrentTime(previous_current_time, exception_state); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish previous_current_time; - currentTime(previous_current_time); - playback_rate_ = playback_rate; - if (!previous_current_time.IsNull()) { - setCurrentTime(previous_current_time, exception_state); - } -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Adds a UseCounter to check if setting playbackRate causes a compensatory // seek forcing a change in start_time_ - if (start_time_before && start_time_ != start_time_before && + // We use an epsilon (1 microsecond) to handle precision issue. + double epsilon = 1e-6; + if (start_time_before && start_time_ && + fabs(start_time_.value().InMillisecondsF() - + start_time_before.value().InMillisecondsF()) > epsilon && CalculateAnimationPlayState() != kFinished) { UseCounter::Count(GetExecutionContext(), WebFeature::kAnimationSetPlaybackRateCompensatorySeek); @@ -2078,6 +2099,34 @@ base::TimeDelta Animation::ComputeCompositorTimeOffset() const { return base::TimeDelta::FromSecondsD(time_offset_s / fabs(playback_rate)); } +void Animation::MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor* paint_artifact_compositor) { + // |compositor_property_animations_have_no_effect_| will already be calculated + // in |Animation::PreCommit| if the animation is pending. + if (compositor_pending_) + return; + + bool had_no_effect = compositor_property_animations_have_no_effect_; + compositor_property_animations_have_no_effect_ = false; + + auto* keyframe_effect = DynamicTo<KeyframeEffect>(content_.Get()); + if (!keyframe_effect || !keyframe_effect->IsCurrent()) { + // If the animation is not running, we can skip checking for having no + // effect. We can also skip the call to |SetCompositorPending| to avoid + // marking finished animations as pending. + return; + } + + Element* target = keyframe_effect->EffectTarget(); + if (target && keyframe_effect->Model()) { + compositor_property_animations_have_no_effect_ = + CompositorAnimations::CompositorPropertyAnimationsHaveNoEffect( + *target, *keyframe_effect->Model(), paint_artifact_compositor); + } + if (compositor_property_animations_have_no_effect_ != had_no_effect) + SetCompositorPending(); +} + void Animation::StartAnimationOnCompositor( const PaintArtifactCompositor* paint_artifact_compositor) { DCHECK_EQ( @@ -2290,9 +2339,11 @@ absl::optional<AnimationTimeDelta> Animation::TimeToEffectChange() { return -current_time.value() / playback_rate_; } - if (!HasActiveAnimationsOnCompositor() && - (content_->GetPhase() == Timing::kPhaseActive)) + // If this animation has no effect, we can skip ticking it on main. + if (!HasActiveAnimationsOnCompositor() && !animation_has_no_effect_ && + (content_->GetPhase() == Timing::kPhaseActive)) { return AnimationTimeDelta(); + } return (playback_rate_ > 0) ? (content_->TimeToForwardsEffectChange() / playback_rate_) diff --git a/chromium/third_party/blink/renderer/core/animation/animation.h b/chromium/third_party/blink/renderer/core/animation/animation.h index cb2fa53733b..b344716fb32 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation.h +++ b/chromium/third_party/blink/renderer/core/animation/animation.h @@ -33,7 +33,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/time/time.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -147,18 +146,10 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, void cancel(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* currentTime() const; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - void currentTime(CSSNumberish&) const; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) absl::optional<AnimationTimeDelta> CurrentTimeInternal() const; void setCurrentTime(const V8CSSNumberish* current_time, ExceptionState& exception_state); -#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - void setCurrentTime(CSSNumberish, ExceptionState& exception_state); - void setCurrentTime(CSSNumberish); -#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void SetCurrentTimeInternal(AnimationTimeDelta); absl::optional<AnimationTimeDelta> UnlimitedCurrentTime() const; @@ -214,23 +205,16 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, double playbackRate() const; void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION); AnimationTimeline* timeline() { return timeline_; } + AnimationTimeline* timeline() const { return timeline_; } virtual void setTimeline(AnimationTimeline* timeline); Document* GetDocument() const; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* startTime() const; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - void startTime(CSSNumberish&) const; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) absl::optional<AnimationTimeDelta> StartTimeInternal() const { return start_time_; } virtual void setStartTime(const V8CSSNumberish* start_time, ExceptionState& exception_state); -#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - virtual void setStartTime(CSSNumberish, ExceptionState&); - void setStartTime(CSSNumberish); -#endif // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const AnimationEffect* effect() const { return content_.Get(); } AnimationEffect* effect() { return content_.Get(); } @@ -320,6 +304,15 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, base::TimeDelta ComputeCompositorTimeOffset() const; + // Updates |compositor_property_animations_have_no_effect_| and marks the + // animation as pending if it changes. + void MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor*); + bool CompositorPropertyAnimationsHaveNoEffectForTesting() const { + return compositor_property_animations_have_no_effect_; + } + bool AnimationHasNoEffect() const { return animation_has_no_effect_; } + protected: DispatchEventResult DispatchEventInternal(Event&) override; void AddedEventListener(const AtomicString& event_type, @@ -354,6 +347,13 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, absl::optional<AnimationTimeDelta> CalculateCurrentTime() const; TimelinePhase CalculateCurrentPhase() const; + V8CSSNumberish* ConvertTimeToCSSNumberish(AnimationTimeDelta) const; + // Failure to convert results in a thrown exception and returning false. + bool ConvertCSSNumberishToTime(const V8CSSNumberish* numberish, + absl::optional<AnimationTimeDelta>& time, + String variable_name, + ExceptionState& exception_state); + void BeginUpdatingState(); void EndUpdatingState(); @@ -486,12 +486,14 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, playback_rate(animation.EffectivePlaybackRate()), effect_changed(false), pending_action(animation.start_time_ ? kNone : kStart) {} + CompositorState(const CompositorState&) = delete; + CompositorState& operator=(const CompositorState&) = delete; + absl::optional<double> start_time; absl::optional<double> hold_time; double playback_rate; bool effect_changed; CompositorAction pending_action; - DISALLOW_COPY_AND_ASSIGN(CompositorState); }; enum CompositorPendingChange { @@ -544,7 +546,15 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, base::TimeTicks last_display_lock_update_time_ = base::TimeTicks(); bool is_in_display_locked_subtree_ = false; - FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestCompositeAfterPaint, + // True if we animate compositor properties but they would have no effect due + // to being optimized out on the compositor. Updated in |Animation::PreCommit| + // and |MarkPendingIfCompositorPropertyAnimationChanges|. + bool compositor_property_animations_have_no_effect_; + // True if the only reason for not running the animation on the compositor is + // that the animation would have no effect. Updated in |Animation::PreCommit|. + bool animation_has_no_effect_; + + FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestCompositing, NoCompositeWithoutCompositedElementId); FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestNoCompositing, PendingActivityWithFinishedEventListener); diff --git a/chromium/third_party/blink/renderer/core/animation/animation_clock.h b/chromium/third_party/blink/renderer/core/animation/animation_clock.h index 8f10d8b6852..abf6727bcb9 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_clock.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_clock.h @@ -33,7 +33,6 @@ #include <limits> -#include "base/macros.h" #include "base/time/default_tick_clock.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -53,6 +52,8 @@ class CORE_EXPORT AnimationClock { clock_(base::DefaultTickClock::GetInstance()), task_for_which_time_was_calculated_( std::numeric_limits<unsigned>::max()) {} + AnimationClock(const AnimationClock&) = delete; + AnimationClock& operator=(const AnimationClock&) = delete; void UpdateTime(base::TimeTicks time); base::TimeTicks CurrentTime(); @@ -97,8 +98,6 @@ class CORE_EXPORT AnimationClock { // See |NotifyTaskStart| documentation for these members. unsigned task_for_which_time_was_calculated_; static unsigned currently_running_task_; - - DISALLOW_COPY_AND_ASSIGN(AnimationClock); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc index 47ad163d059..7d0acea85ec 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" @@ -49,6 +50,92 @@ AnimationEffect::AnimationEffect(const Timing& timing, needs_update_(true), cancel_time_(AnimationTimeDelta()) { timing_.AssertValid(); + InvalidateNormalizedTiming(); +} + +// Scales all timing values so that end_time == timeline_duration +void AnimationEffect::EnsureNormalizedTiming() const { + // Only run the normalization process if needed + if (normalized_) + return; + + normalized_ = Timing::NormalizedTiming(); + if (GetAnimation() && GetAnimation()->timeline() && + GetAnimation()->timeline()->IsProgressBasedTimeline()) { + // Normalize timings for progress based timelines + normalized_->timeline_duration = GetAnimation()->timeline()->GetDuration(); + DCHECK(normalized_->timeline_duration); + + if (timing_.iteration_duration) { + // Scaling up iteration_duration allows animation effect to be able to + // handle values produced by progress based timelines. At this point it + // can be assumed that EndTimeInternal() will give us a good value. + + const AnimationTimeDelta active_duration = MultiplyZeroAlwaysGivesZero( + timing_.iteration_duration.value(), timing_.iteration_count); + DCHECK_GE(active_duration, AnimationTimeDelta()); + + // Per the spec, the end time has a lower bound of 0.0: + // https://drafts.csswg.org/web-animations-1/#end-time + const AnimationTimeDelta end_time = + std::max(timing_.start_delay + active_duration + timing_.end_delay, + AnimationTimeDelta()); + + // Exceptions should have already been thrown when trying to input values + // that would result in an infinite end_time for progress based timelines. + DCHECK(!end_time.is_inf()); + + // Negative start_delay that is >= iteration_duration or iteration_count + // of 0 will cause end_time to be 0 or negative. + if (end_time.is_zero()) { + // end_time of zero causes division by zero so we handle it here + normalized_->start_delay = AnimationTimeDelta(); + normalized_->end_delay = AnimationTimeDelta(); + normalized_->iteration_duration = AnimationTimeDelta(); + } else { + // convert to percentages then multiply by the timeline_duration + normalized_->start_delay = (timing_.start_delay / end_time) * + normalized_->timeline_duration.value(); + + normalized_->end_delay = (timing_.end_delay / end_time) * + normalized_->timeline_duration.value(); + + normalized_->iteration_duration = + (timing_.iteration_duration.value() / end_time) * + normalized_->timeline_duration.value(); + } + } else { + // Handle iteration_duration value of "auto" + + // TODO(crbug.com/1216527) + // this will change to support percentage delays and possibly mixed + // delays. + DCHECK(normalized_->start_delay.is_zero() && + normalized_->end_delay.is_zero()); + + normalized_->iteration_duration = + GetAnimation()->timeline()->CalculateIntrinsicIterationDuration( + timing_); + // TODO: add support for progress based timelines and "auto" duration + // effects + } + } else { + // Populates normalized values for use with time based timelines. + normalized_->start_delay = timing_.start_delay; + normalized_->end_delay = timing_.end_delay; + normalized_->iteration_duration = + timing_.iteration_duration.value_or(AnimationTimeDelta()); + } + + normalized_->active_duration = MultiplyZeroAlwaysGivesZero( + normalized_->iteration_duration, timing_.iteration_count); + + // Per the spec, the end time has a lower bound of 0.0: + // https://drafts.csswg.org/web-animations-1/#end-time + normalized_->end_time = + std::max(normalized_->start_delay + normalized_->active_duration + + normalized_->end_delay, + AnimationTimeDelta()); } void AnimationEffect::UpdateSpecifiedTiming(const Timing& timing) { @@ -81,6 +168,8 @@ void AnimationEffect::UpdateSpecifiedTiming(const Timing& timing) { if (!timing_.HasTimingOverride(Timing::kOverrideTimingFunction)) timing_.timing_function = timing.timing_function; } + + InvalidateNormalizedTiming(); InvalidateAndNotifyOwner(); } @@ -95,16 +184,61 @@ EffectTiming* AnimationEffect::getTiming() const { } ComputedEffectTiming* AnimationEffect::getComputedTiming() const { - return SpecifiedTiming().getComputedTiming(EnsureCalculated(), - IsA<KeyframeEffect>(this)); + return SpecifiedTiming().getComputedTiming( + EnsureCalculated(), NormalizedTiming(), IsA<KeyframeEffect>(this)); } void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing, ExceptionState& exception_state) { + if (GetAnimation() && GetAnimation()->timeline() && + GetAnimation()->timeline()->IsProgressBasedTimeline()) { + if (optional_timing->hasDuration()) { + if (optional_timing->duration()->IsUnrestrictedDouble()) { + double duration = + optional_timing->duration()->GetAsUnrestrictedDouble(); + if (duration == std::numeric_limits<double>::infinity()) { + exception_state.ThrowTypeError( + "Effect duration cannot be Infinity when used with Scroll " + "Timelines"); + return; + } + } else if (optional_timing->duration()->GetAsString() == "auto") { + // TODO(crbug.com/1216527) + // Eventually we hope to be able to be more flexible with + // iteration_duration "auto" and its interaction with start_delay and + // end_delay. For now we will throw an exception if either delay is set. + // Once delays are changed to CSSNumberish, we will need to adjust logic + // here to allow for percentage values but not time values. + + // If either delay or end_delay are non-zero, we can't handle "auto" + if (!SpecifiedTiming().start_delay.is_zero() || + !SpecifiedTiming().end_delay.is_zero()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Effect duration \"auto\" with delays is not yet implemented " + "when used with Scroll Timelines"); + return; + } + } + } + + if (optional_timing->hasIterations() && + optional_timing->iterations() == + std::numeric_limits<double>::infinity()) { + // iteration count of infinity makes no sense for scroll timelines + exception_state.ThrowTypeError( + "Effect iterations cannot be Infinity when used with Scroll " + "Timelines"); + return; + } + } + // TODO(crbug.com/827178): Determine whether we should pass a Document in here // (and which) to resolve the CSS secure/insecure context against. if (!TimingInput::Update(timing_, optional_timing, nullptr, exception_state)) return; + + InvalidateNormalizedTiming(); InvalidateAndNotifyOwner(); } @@ -154,8 +288,8 @@ void AnimationEffect::UpdateInheritedTime( if (needs_update) { Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings( - inherited_time, timeline_phase, direction, IsA<KeyframeEffect>(this), - playback_rate); + inherited_time, timeline_phase, NormalizedTiming(), direction, + IsA<KeyframeEffect>(this), playback_rate); const bool was_canceled = calculated.phase != calculated_.phase && calculated.phase == Timing::kPhaseNone; diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.h b/chromium/third_party/blink/renderer/core/animation/animation_effect.h index 5763f0cdab8..b04f02e3c98 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.h @@ -104,6 +104,13 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { } const Timing& SpecifiedTiming() const { return timing_; } + + const Timing::NormalizedTiming& NormalizedTiming() const { + EnsureNormalizedTiming(); + return normalized_.value(); + } + void InvalidateNormalizedTiming() { normalized_.reset(); } + void UpdateSpecifiedTiming(const Timing&); void SetIgnoreCssTimingProperties(); @@ -120,7 +127,10 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { } // Attach/Detach the AnimationEffect from its owning animation. - virtual void Attach(AnimationEffectOwner* owner) { owner_ = owner; } + virtual void Attach(AnimationEffectOwner* owner) { + owner_ = owner; + InvalidateNormalizedTiming(); + } virtual void Detach() { DCHECK(owner_); owner_ = nullptr; @@ -169,11 +179,13 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable { Member<EventDelegate> event_delegate_; mutable Timing::CalculatedTiming calculated_; + mutable absl::optional<Timing::NormalizedTiming> normalized_; mutable bool needs_update_; mutable absl::optional<AnimationTimeDelta> last_update_time_; mutable absl::optional<Timing::Phase> last_update_phase_; AnimationTimeDelta cancel_time_; const Timing::CalculatedTiming& EnsureCalculated() const; + void EnsureNormalizedTiming() const; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc index 7628a5a1315..dd84e04a4e0 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc @@ -34,6 +34,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_effect_owner.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -139,7 +140,7 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -150,7 +151,7 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0.5, animation_node->Progress()); animation_node->UpdateInheritedTime(2); @@ -161,7 +162,7 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(3); @@ -172,7 +173,7 @@ TEST(AnimationAnimationEffectTest, Sanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); } @@ -253,13 +254,13 @@ TEST(AnimationAnimationEffectTest, ZeroIteration) { animation_node->UpdateInheritedTime(-1); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(0, animation_node->Progress()); } @@ -276,7 +277,7 @@ TEST(AnimationAnimationEffectTest, InfiniteIteration) { EXPECT_FALSE(animation_node->Progress()); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); animation_node->UpdateInheritedTime(0); EXPECT_EQ(0, animation_node->CurrentIteration()); @@ -383,7 +384,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); animation_node->UpdateInheritedTime(1); @@ -394,7 +395,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) { EXPECT_TRUE(animation_node->IsInEffect()); EXPECT_EQ(0, animation_node->CurrentIteration()); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(1, animation_node->Progress()); } @@ -486,13 +487,13 @@ TEST(AnimationAnimationEffectTest, ZeroDurationInfiniteIteration) { animation_node->UpdateInheritedTime(-1); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_FALSE(animation_node->CurrentIteration()); EXPECT_FALSE(animation_node->Progress()); animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(std::numeric_limits<double>::infinity(), animation_node->CurrentIteration()); EXPECT_EQ(1, animation_node->Progress()); @@ -586,7 +587,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) { animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -597,7 +598,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) { animation_node->UpdateInheritedTime(1); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -616,7 +617,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationZeroIterations) { animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseAfter, animation_node->GetPhase()); EXPECT_FALSE(animation_node->IsInPlay()); EXPECT_FALSE(animation_node->IsCurrent()); @@ -644,7 +645,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) { animation_node->UpdateInheritedTime(0); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -655,7 +656,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) { animation_node->UpdateInheritedTime(1); EXPECT_EQ(AnimationTimeDelta::Max(), - animation_node->SpecifiedTiming().ActiveDuration()); + animation_node->NormalizedTiming().active_duration); EXPECT_EQ(Timing::kPhaseActive, animation_node->GetPhase()); EXPECT_TRUE(animation_node->IsInPlay()); EXPECT_TRUE(animation_node->IsCurrent()); @@ -672,7 +673,7 @@ TEST(AnimationAnimationEffectTest, EndTime) { timing.iteration_count = 2; auto* animation_node = MakeGarbageCollected<TestAnimationEffect>(timing); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(11), - animation_node->SpecifiedTiming().EndTimeInternal()); + animation_node->NormalizedTiming().end_time); } TEST(AnimationAnimationEffectTest, Events) { @@ -790,12 +791,12 @@ TEST(AnimationAnimationEffectTest, UpdateTiming) { effect->updateTiming(effect_timing); EXPECT_EQ("ease-in-out", effect->getTiming()->easing()); - EXPECT_EQ("auto", effect->getTiming()->duration().GetAsString()); + EXPECT_EQ("auto", effect->getTiming()->duration()->GetAsString()); effect_timing = OptionalEffectTiming::Create(); effect_timing->setDuration( - UnrestrictedDoubleOrString::FromUnrestrictedDouble(2.5)); + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>(2.5)); effect->updateTiming(effect_timing); - EXPECT_EQ(2.5, effect->getTiming()->duration().GetAsUnrestrictedDouble()); + EXPECT_EQ(2.5, effect->getTiming()->duration()->GetAsUnrestrictedDouble()); } TEST(AnimationAnimationEffectTest, UpdateTimingThrowsWhenExpected) { @@ -827,14 +828,15 @@ TEST(AnimationAnimationEffectTest, UpdateTimingThrowsWhenExpected) { exception_state.ClearException(); effect_timing = OptionalEffectTiming::Create(); effect_timing->setDuration( - UnrestrictedDoubleOrString::FromUnrestrictedDouble(-100)); + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>(-100)); effect->updateTiming(effect_timing, exception_state); EXPECT_TRUE(exception_state.HadException()); exception_state.ClearException(); effect_timing = OptionalEffectTiming::Create(); - effect_timing->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble( - std::numeric_limits<double>::quiet_NaN())); + effect_timing->setDuration( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( + std::numeric_limits<double>::quiet_NaN())); effect->updateTiming(effect_timing, exception_state); EXPECT_TRUE(exception_state.HadException()); @@ -897,7 +899,7 @@ TEST(AnimationAnimationEffectTest, UpdateTimingNoChange) { effect_timing = OptionalEffectTiming::Create(); effect_timing->setIterations(3); effect_timing->setDuration( - UnrestrictedDoubleOrString::FromUnrestrictedDouble(2000)); + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>(2000)); effect_timing->setDirection("alternate-reverse"); effect->updateTiming(effect_timing); diff --git a/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc b/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc index 86a7a8b13d0..8d713ffc8d9 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" -#include "base/stl_util.h" +#include "base/cxx17_backports.h" #include "third_party/blink/renderer/core/animation/property_handle.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_test.cc index 900360888d6..8acba7e3622 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_test.cc @@ -33,12 +33,15 @@ #include <memory> #include "base/bits.h" +#include "base/macros.h" +#include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h" #include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h" @@ -49,6 +52,7 @@ #include "third_party/blink/renderer/core/animation/pending_animations.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/animation/timing.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -64,6 +68,7 @@ #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/testing/histogram_tester.h" +#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -73,7 +78,8 @@ void ExpectRelativeErrorWithinEpsilon(double expected, double observed) { EXPECT_NEAR(1.0, observed / expected, std::numeric_limits<double>::epsilon()); } -class AnimationAnimationTestNoCompositing : public RenderingTest { +class AnimationAnimationTestNoCompositing : public PaintTestConfigurations, + public RenderingTest { public: AnimationAnimationTestNoCompositing() : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {} @@ -90,12 +96,8 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { timeline = GetDocument().Timeline(); timeline->ResetForTesting(); animation = timeline->Play(nullptr); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation()); } @@ -137,7 +139,9 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { RunDocumentLifecycle(); - SetBodyInnerHTML("<div id='target'></div>"); + SetBodyInnerHTML(R"HTML( + <div id='target' style='width: 1px; height: 1px; background: green'></div> + )HTML"); MakeCompositedAnimation(); } @@ -221,43 +225,19 @@ class AnimationAnimationTestNoCompositing : public RenderingTest { } bool StartTimeIsSet(Animation* animation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) return animation->startTime(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish start_time; - animation->startTime(start_time); - return !start_time.IsNull(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } bool CurrentTimeIsSet(Animation* animation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) return animation->currentTime(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time; - animation->currentTime(current_time); - return !current_time.IsNull(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } double GetStartTimeMs(Animation* animation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) return animation->startTime()->GetAsDouble(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish start_time; - animation->startTime(start_time); - return start_time.GetAsDouble(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } double GetCurrentTimeMs(Animation* animation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) return animation->currentTime()->GetAsDouble(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time; - animation->currentTime(current_time); - return current_time.GetAsDouble(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } #define EXPECT_TIME(expected, observed) \ @@ -308,17 +288,10 @@ class AnimationAnimationTestCompositing } }; -class AnimationAnimationTestCompositeAfterPaint - : public AnimationAnimationTestNoCompositing { - void SetUp() override { - EnableCompositing(); - AnimationAnimationTestNoCompositing::SetUp(); - } - - ScopedCompositeAfterPaintForTest enable_cap{true}; -}; +INSTANTIATE_PAINT_TEST_SUITE_P(AnimationAnimationTestNoCompositing); +INSTANTIATE_PAINT_TEST_SUITE_P(AnimationAnimationTestCompositing); -TEST_F(AnimationAnimationTestNoCompositing, InitialState) { +TEST_P(AnimationAnimationTestNoCompositing, InitialState) { SetUpWithoutStartingTimeline(); animation = timeline->Play(nullptr); EXPECT_TIME(0, GetCurrentTimeMs(animation)); @@ -337,7 +310,7 @@ TEST_F(AnimationAnimationTestNoCompositing, InitialState) { EXPECT_TIME(0, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, CurrentTimeDoesNotSetOutdated) { +TEST_P(AnimationAnimationTestNoCompositing, CurrentTimeDoesNotSetOutdated) { EXPECT_FALSE(animation->Outdated()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); EXPECT_FALSE(animation->Outdated()); @@ -350,14 +323,10 @@ TEST_F(AnimationAnimationTestNoCompositing, CurrentTimeDoesNotSetOutdated) { EXPECT_FALSE(animation->Outdated()); } -TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) { +TEST_P(AnimationAnimationTestNoCompositing, SetCurrentTime) { EXPECT_EQ("running", animation->playState()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -366,25 +335,17 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); SimulateFrame(20000); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); animation->setPlaybackRate(-2); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); // A seek can set current time outside the range [0, EffectEnd()]. EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); @@ -396,7 +357,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) { EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, SetCurrentTimeNegativeWithoutSimultaneousPlaybackRateChange) { SimulateFrame(20000); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); @@ -412,22 +373,14 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TIME(10000, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); } -TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); @@ -437,12 +390,8 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { // Reversing the play direction changes the play state from finished to // running. animation->setPlaybackRate(-2); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); SimulateAwaitReady(); @@ -452,35 +401,23 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) { EXPECT_TIME(10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeMax) { +TEST_P(AnimationAnimationTestCompositing, SetCurrentTimeMax) { ResetWithCompositedAnimation(); EXPECT_EQ(CompositorAnimations::kNoFailure, animation->CheckCanStartAnimationOnCompositor(nullptr)); double limit = std::numeric_limits<double>::max(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit), ASSERT_NO_EXCEPTION); V8CSSNumberish* current_time = animation->currentTime(); ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(limit)); - CSSNumberish current_time; - animation->currentTime(current_time); - ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) & CompositorAnimations::kEffectHasUnsupportedTimingParameters); SimulateFrame(100000); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) current_time = animation->currentTime(); ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->currentTime(current_time); - ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } -TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeAboveMaxTimeDelta) { +TEST_P(AnimationAnimationTestCompositing, SetCurrentTimeAboveMaxTimeDelta) { // Similar to the SetCurrentTimeMax test. The limit is much less, but still // too large to be expressed as a 64-bit int and thus not able to run on the // compositor. @@ -488,27 +425,17 @@ TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeAboveMaxTimeDelta) { EXPECT_EQ(CompositorAnimations::kNoFailure, animation->CheckCanStartAnimationOnCompositor(nullptr)); double limit = 1e30; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit), ASSERT_NO_EXCEPTION); ignore_result(animation->currentTime()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(limit)); - CSSNumberish current_time; - animation->currentTime(current_time); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) & CompositorAnimations::kEffectHasUnsupportedTimingParameters); } -TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) { +TEST_P(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) { EXPECT_TIME(0, GetStartTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(1000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(1000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(-1000, GetStartTimeMs(animation)); SimulateFrame(1000); @@ -516,17 +443,13 @@ TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) { EXPECT_TIME(2000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetStartTime) { +TEST_P(AnimationAnimationTestNoCompositing, SetStartTime) { SimulateFrame(20000); EXPECT_EQ("running", animation->playState()); EXPECT_TIME(0, GetStartTimeMs(animation)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TIME(10000, GetStartTimeMs(animation)); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -534,73 +457,49 @@ TEST_F(AnimationAnimationTestNoCompositing, SetStartTime) { SimulateFrame(30000); EXPECT_TIME(10000, GetStartTimeMs(animation)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-20000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(-20000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); } -TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeLimitsAnimation) { +TEST_P(AnimationAnimationTestNoCompositing, SetStartTimeLimitsAnimation) { // Setting the start time is a seek operation, which is not constrained by the // normal limits on the animation. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(-50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TRUE(animation->Limited()); EXPECT_TIME(50000, GetCurrentTimeMs(animation)); animation->setPlaybackRate(-1); EXPECT_EQ("running", animation->playState()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-100000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(-100000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(-100000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); } -TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeOnLimitedAnimation) { +TEST_P(AnimationAnimationTestNoCompositing, SetStartTimeOnLimitedAnimation) { // The setStartTime method is a seek and thus not constrained by the normal // limits on the animation. SimulateFrame(30000); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(50000, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(-40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(70000, GetCurrentTimeMs(animation)); EXPECT_EQ("finished", animation->playState()); EXPECT_TRUE(animation->Limited()); } -TEST_F(AnimationAnimationTestNoCompositing, StartTimePauseFinish) { +TEST_P(AnimationAnimationTestNoCompositing, StartTimePauseFinish) { NonThrowableExceptionState exception_state; animation->pause(); EXPECT_EQ("paused", animation->playState()); @@ -614,7 +513,7 @@ TEST_F(AnimationAnimationTestNoCompositing, StartTimePauseFinish) { EXPECT_TIME(-30000, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, FinishWhenPaused) { +TEST_P(AnimationAnimationTestNoCompositing, FinishWhenPaused) { NonThrowableExceptionState exception_state; animation->pause(); EXPECT_EQ("paused", animation->playState()); @@ -627,7 +526,7 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishWhenPaused) { EXPECT_EQ("finished", animation->playState()); } -TEST_F(AnimationAnimationTestNoCompositing, StartTimeFinishPause) { +TEST_P(AnimationAnimationTestNoCompositing, StartTimeFinishPause) { NonThrowableExceptionState exception_state; animation->finish(exception_state); EXPECT_TIME(-30000, GetStartTimeMs(animation)); @@ -639,7 +538,7 @@ TEST_F(AnimationAnimationTestNoCompositing, StartTimeFinishPause) { EXPECT_FALSE(StartTimeIsSet(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, StartTimeWithZeroPlaybackRate) { +TEST_P(AnimationAnimationTestNoCompositing, StartTimeWithZeroPlaybackRate) { animation->setPlaybackRate(0); EXPECT_EQ("running", animation->playState()); SimulateAwaitReady(); @@ -650,7 +549,7 @@ TEST_F(AnimationAnimationTestNoCompositing, StartTimeWithZeroPlaybackRate) { EXPECT_TIME(0, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, PausePlay) { +TEST_P(AnimationAnimationTestNoCompositing, PausePlay) { // Pause the animation at the 10s mark. SimulateFrame(10000); animation->pause(); @@ -674,24 +573,16 @@ TEST_F(AnimationAnimationTestNoCompositing, PausePlay) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { +TEST_P(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { // Auto-replay when starting from limit. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(30000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(30000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); // Auto-replay when starting past the upper bound. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); @@ -701,12 +592,8 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { // from a negative value of current time. SimulateFrame(10000); EXPECT_FALSE(animation->pending()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_FALSE(animation->pending()); animation->play(); @@ -718,19 +605,15 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) { EXPECT_FALSE(animation->pending()); } -TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { +TEST_P(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { // Snap to end when playing a reversed animation from the start. animation->setPlaybackRate(-1); animation->play(); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); // Snap to end if playing a reversed animation starting past the upper limit. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); animation->play(); @@ -743,12 +626,8 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { // Snap to the end if playing a reversed animation starting with a negative // value for current time. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); EXPECT_EQ("running", animation->playState()); @@ -759,7 +638,7 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToEnd) { EXPECT_FALSE(animation->pending()); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, PlayWithPlaybackRateZeroDoesNotSeek) { // When playback rate is zero, any value set for the current time effectively // becomes the hold time. @@ -767,26 +646,18 @@ TEST_F(AnimationAnimationTestNoCompositing, animation->play(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->play(); EXPECT_TIME(-10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, PlayAfterPauseWithPlaybackRateZeroUpdatesPlayState) { animation->pause(); animation->setPlaybackRate(0); @@ -798,13 +669,9 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->pending()); } -TEST_F(AnimationAnimationTestNoCompositing, Reverse) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, Reverse) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->pause(); animation->reverse(); EXPECT_EQ("running", animation->playState()); @@ -819,14 +686,10 @@ TEST_F(AnimationAnimationTestNoCompositing, Reverse) { EXPECT_TIME(10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, ReverseHoldsCurrentTimeWithPlaybackRateZero) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(0); animation->pause(); animation->reverse(); @@ -839,55 +702,39 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TIME(10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToStart) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, ReverseSeeksToStart) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->reverse(); EXPECT_TIME(0, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToEnd) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, ReverseSeeksToEnd) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->reverse(); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, ReverseBeyondLimit) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, ReverseBeyondLimit) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->reverse(); EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->reverse(); EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->pending()); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, Finish) { +TEST_P(AnimationAnimationTestNoCompositing, Finish) { NonThrowableExceptionState exception_state; animation->finish(exception_state); // Finished snaps to the end of the animation. @@ -903,50 +750,38 @@ TEST_F(AnimationAnimationTestNoCompositing, Finish) { EXPECT_FALSE(animation->pending()); } -TEST_F(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) { +TEST_P(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) { NonThrowableExceptionState exception_state; // OK to set current time out of bounds. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->finish(exception_state); // The finish method triggers a snap to the upper boundary. EXPECT_TIME(30000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, FinishBeforeStart) { +TEST_P(AnimationAnimationTestNoCompositing, FinishBeforeStart) { NonThrowableExceptionState exception_state; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->finish(exception_state); EXPECT_TIME(0, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, FinishDoesNothingWithPlaybackRateZero) { // Cannot finish an animation that has a playback rate of zero. DummyExceptionStateForTesting exception_state; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(0); animation->finish(exception_state); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); EXPECT_TRUE(exception_state.HadException()); } -TEST_F(AnimationAnimationTestNoCompositing, FinishRaisesException) { +TEST_P(AnimationAnimationTestNoCompositing, FinishRaisesException) { // Cannot finish an animation that has an infinite iteration-count and a // non-zero iteration-duration. Timing timing; @@ -954,12 +789,8 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishRaisesException) { timing.iteration_count = std::numeric_limits<double>::infinity(); animation->setEffect(MakeGarbageCollected<KeyframeEffect>( nullptr, MakeEmptyEffectModel(), timing)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(10000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DummyExceptionStateForTesting exception_state; animation->finish(exception_state); @@ -969,7 +800,7 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishRaisesException) { exception_state.CodeAs<DOMExceptionCode>()); } -TEST_F(AnimationAnimationTestNoCompositing, LimitingAtEffectEnd) { +TEST_P(AnimationAnimationTestNoCompositing, LimitingAtEffectEnd) { SimulateFrame(30000); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); @@ -980,7 +811,7 @@ TEST_F(AnimationAnimationTestNoCompositing, LimitingAtEffectEnd) { EXPECT_FALSE(animation->Paused()); } -TEST_F(AnimationAnimationTestNoCompositing, LimitingAtStart) { +TEST_P(AnimationAnimationTestNoCompositing, LimitingAtStart) { SimulateFrame(30000); animation->setPlaybackRate(-2); SimulateAwaitReady(); @@ -994,14 +825,14 @@ TEST_F(AnimationAnimationTestNoCompositing, LimitingAtStart) { EXPECT_FALSE(animation->Paused()); } -TEST_F(AnimationAnimationTestNoCompositing, LimitingWithNoEffect) { +TEST_P(AnimationAnimationTestNoCompositing, LimitingWithNoEffect) { animation->setEffect(nullptr); EXPECT_TRUE(animation->Limited()); SimulateFrame(30000); EXPECT_TIME(0, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRate) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRate) { animation->setPlaybackRate(2); SimulateAwaitReady(); EXPECT_EQ(2, animation->playbackRate()); @@ -1011,7 +842,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRate) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhilePaused) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRateWhilePaused) { SimulateFrame(10000); animation->pause(); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); @@ -1029,7 +860,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhilePaused) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhileLimited) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRateWhileLimited) { // Animation plays until it hits the upper bound. SimulateFrame(40000); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); @@ -1048,23 +879,19 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateWhileLimited) { EXPECT_TIME(10000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateZero) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRateZero) { SimulateFrame(10000); animation->setPlaybackRate(0); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); SimulateFrame(20000); EXPECT_TIME(10000, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(20000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateMax) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRateMax) { animation->setPlaybackRate(std::numeric_limits<double>::max()); EXPECT_EQ(std::numeric_limits<double>::max(), animation->playbackRate()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); @@ -1074,7 +901,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateMax) { EXPECT_TIME(30000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRate) { +TEST_P(AnimationAnimationTestNoCompositing, UpdatePlaybackRate) { animation->updatePlaybackRate(2); EXPECT_EQ(1, animation->playbackRate()); SimulateAwaitReady(); @@ -1085,7 +912,7 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRate) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhilePaused) { +TEST_P(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhilePaused) { animation->pause(); // Pending playback rate on pending-paused animation is picked up after async @@ -1104,7 +931,7 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhilePaused) { EXPECT_EQ(3, animation->playbackRate()); } -TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileLimited) { +TEST_P(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileLimited) { NonThrowableExceptionState exception_state; animation->finish(exception_state); EXPECT_TIME(30000, GetCurrentTimeMs(animation)); @@ -1118,7 +945,7 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileLimited) { EXPECT_EQ(2, animation->playbackRate()); } -TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileRunning) { +TEST_P(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileRunning) { animation->play(); SimulateFrame(1000); animation->updatePlaybackRate(2); @@ -1132,25 +959,17 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateWhileRunning) { EXPECT_EQ(2, animation->playbackRate()); } -TEST_F(AnimationAnimationTestNoCompositing, SetEffect) { +TEST_P(AnimationAnimationTestNoCompositing, SetEffect) { animation = timeline->Play(nullptr); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) AnimationEffect* effect1 = MakeAnimation(); AnimationEffect* effect2 = MakeAnimation(); animation->setEffect(effect1); EXPECT_EQ(effect1, animation->effect()); EXPECT_TIME(0, GetCurrentTimeMs(animation)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(15000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(effect2); EXPECT_TIME(15000, GetCurrentTimeMs(animation)); EXPECT_EQ(nullptr, effect1->GetAnimationForTesting()); @@ -1158,13 +977,9 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffect) { EXPECT_EQ(effect2, animation->effect()); } -TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(20000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation(10)); EXPECT_TIME(20000, GetCurrentTimeMs(animation)); EXPECT_TRUE(animation->Limited()); @@ -1172,13 +987,9 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) { EXPECT_TIME(20000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +TEST_P(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) { animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(40000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setEffect(MakeAnimation(60)); EXPECT_FALSE(animation->Limited()); EXPECT_TIME(40000, GetCurrentTimeMs(animation)); @@ -1186,7 +997,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) { EXPECT_TIME(50000, GetCurrentTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, EmptyAnimationsDontUpdateEffects) { +TEST_P(AnimationAnimationTestNoCompositing, EmptyAnimationsDontUpdateEffects) { animation = timeline->Play(nullptr); animation->Update(kTimingUpdateOnDemand); EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); @@ -1195,7 +1006,7 @@ TEST_F(AnimationAnimationTestNoCompositing, EmptyAnimationsDontUpdateEffects) { EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } -TEST_F(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) { +TEST_P(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) { AnimationEffect* animation_node = animation->effect(); Animation* animation2 = timeline->Play(animation_node); EXPECT_EQ(nullptr, animation->effect()); @@ -1207,7 +1018,7 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsDisassociateFromEffect) { EXPECT_NEAR(expected.InMillisecondsF(), observed.InMillisecondsF(), \ Animation::kTimeToleranceMs) -TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { +TEST_P(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { Timing timing; timing.start_delay = AnimationTimeDelta::FromSecondsD(1); timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1); @@ -1215,12 +1026,8 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>( nullptr, MakeEmptyEffectModel(), timing); animation = timeline->Play(keyframe_effect); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Next effect change at end of start delay. SimulateFrame(0); @@ -1252,12 +1059,8 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reset to start of animation. Next effect at the end of the start delay. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) SimulateFrame(3000); EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1), animation->TimeToEffectChange().value()); @@ -1274,12 +1077,8 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); // Reversed animation from end time. Next effect after end delay. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(3000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(3000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-1); animation->Update(kTimingUpdateOnDemand); SimulateFrame(3000); @@ -1294,7 +1093,7 @@ TEST_F(AnimationAnimationTestNoCompositing, AnimationsReturnTimeToNextEffect) { animation->TimeToEffectChange().value()); } -TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenPaused) { +TEST_P(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenPaused) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); animation->pause(); @@ -1306,16 +1105,12 @@ TEST_F(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenPaused) { EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenCancelledBeforeStart) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-8000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(-8000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(2); EXPECT_EQ("running", animation->playState()); animation->cancel(); @@ -1327,16 +1122,12 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, TimeToNextEffectWhenCancelledBeforeStartReverse) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(9000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(9000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setPlaybackRate(-3); EXPECT_EQ("running", animation->playState()); animation->cancel(); @@ -1346,7 +1137,7 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, TimeToNextEffectSimpleCancelledBeforeStart) { EXPECT_TIMEDELTA(AnimationTimeDelta(), animation->TimeToEffectChange().value()); @@ -1358,7 +1149,7 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_EQ(absl::nullopt, animation->TimeToEffectChange()); } -TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) { +TEST_P(AnimationAnimationTestNoCompositing, AttachedAnimations) { // Prevent |element| from being collected by |CollectAllGarbageForTesting|. Persistent<Element> element = GetDocument().CreateElementForBinding("foo"); @@ -1375,7 +1166,7 @@ TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) { EXPECT_TRUE(element->GetElementAnimations()->Animations().IsEmpty()); } -TEST_F(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) { +TEST_P(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) { Animation* animation1 = timeline->Play(nullptr); Animation* animation2 = timeline->Play(nullptr); EXPECT_TRUE(Animation::HasLowerCompositeOrdering( @@ -1383,7 +1174,7 @@ TEST_F(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) { Animation::CompareAnimationsOrdering::kPointerOrder)); } -TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) { +TEST_P(AnimationAnimationTestNoCompositing, PlayAfterCancel) { animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(CurrentTimeIsSet(animation)); @@ -1404,14 +1195,10 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) { EXPECT_TIME(0, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) { +TEST_P(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) { animation->setPlaybackRate(-1); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(15000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(animation->pending()); @@ -1434,7 +1221,7 @@ TEST_F(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) { EXPECT_TIME(30000, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, ReverseAfterCancel) { +TEST_P(AnimationAnimationTestNoCompositing, ReverseAfterCancel) { animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(animation->pending()); @@ -1457,7 +1244,7 @@ TEST_F(AnimationAnimationTestNoCompositing, ReverseAfterCancel) { EXPECT_TIME(30000, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, FinishAfterCancel) { +TEST_P(AnimationAnimationTestNoCompositing, FinishAfterCancel) { NonThrowableExceptionState exception_state; animation->cancel(); EXPECT_EQ("idle", animation->playState()); @@ -1470,7 +1257,7 @@ TEST_F(AnimationAnimationTestNoCompositing, FinishAfterCancel) { EXPECT_TIME(-30000, GetStartTimeMs(animation)); } -TEST_F(AnimationAnimationTestNoCompositing, PauseAfterCancel) { +TEST_P(AnimationAnimationTestNoCompositing, PauseAfterCancel) { animation->cancel(); EXPECT_EQ("idle", animation->playState()); EXPECT_FALSE(CurrentTimeIsSet(animation)); @@ -1487,7 +1274,7 @@ TEST_F(AnimationAnimationTestNoCompositing, PauseAfterCancel) { } // crbug.com/1052217 -TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) { +TEST_P(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) { animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS)); animation->finish(); animation->Update(kTimingUpdateOnDemand); @@ -1506,7 +1293,7 @@ TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) { EXPECT_FALSE(animation->Outdated()); } -TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) { +TEST_P(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) { animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS)); animation->finish(); animation->Update(kTimingUpdateOnDemand); @@ -1527,7 +1314,7 @@ TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) { EXPECT_FALSE(animation->Outdated()); } -TEST_F(AnimationAnimationTestCompositeAfterPaint, +TEST_P(AnimationAnimationTestCompositing, NoCompositeWithoutCompositedElementId) { SetBodyInnerHTML( "<div id='foo' style='position: relative; will-change: " @@ -1567,7 +1354,7 @@ TEST_F(AnimationAnimationTestCompositeAfterPaint, // played and then paused before any start time is set (either blink or // compositor side), the pausing must still set compositor pending or the pause // won't be synced. -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, SetCompositorPendingWithUnresolvedStartTimes) { ResetWithCompositedAnimation(); @@ -1585,7 +1372,7 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->CompositorPending()); } -TEST_F(AnimationAnimationTestCompositing, PreCommitWithUnresolvedStartTimes) { +TEST_P(AnimationAnimationTestCompositing, PreCommitWithUnresolvedStartTimes) { ResetWithCompositedAnimation(); // At this point, the animation exists on both the compositor and blink side, @@ -1610,7 +1397,7 @@ int GenerateHistogramValue(CompositorAnimations::FailureReason reason) { } } // namespace -TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) { +TEST_P(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) { const std::string histogram_name = "Blink.Animation.CompositedAnimationFailureReason"; @@ -1675,7 +1462,7 @@ TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) { } // crbug.com/990000. -TEST_F(AnimationAnimationTestCompositing, ReplaceCompositedAnimation) { +TEST_P(AnimationAnimationTestCompositing, ReplaceCompositedAnimation) { const std::string histogram_name = "Blink.Animation.CompositedAnimationFailureReason"; @@ -1690,7 +1477,7 @@ TEST_F(AnimationAnimationTestCompositing, ReplaceCompositedAnimation) { ASSERT_TRUE(animation->HasActiveAnimationsOnCompositor()); } -TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) { +TEST_P(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) { ResetWithCompositedAnimation(); // At this point, the animation exists on both the compositor and blink side, @@ -1720,14 +1507,15 @@ TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) { // crbug.com/1057076 // Infinite duration animations should not run on the compositor. -TEST_F(AnimationAnimationTestCompositing, InfiniteDurationAnimation) { +TEST_P(AnimationAnimationTestCompositing, InfiniteDurationAnimation) { ResetWithCompositedAnimation(); EXPECT_EQ(CompositorAnimations::kNoFailure, animation->CheckCanStartAnimationOnCompositor(nullptr)); OptionalEffectTiming* effect_timing = OptionalEffectTiming::Create(); - effect_timing->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble( - std::numeric_limits<double>::infinity())); + effect_timing->setDuration( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( + std::numeric_limits<double>::infinity())); animation->effect()->updateTiming(effect_timing); EXPECT_EQ(CompositorAnimations::kEffectHasUnsupportedTimingParameters, animation->CheckCanStartAnimationOnCompositor(nullptr)); @@ -1738,14 +1526,14 @@ TEST_F(AnimationAnimationTestCompositing, InfiniteDurationAnimation) { // relative transforms after a size change. In this test, the transform depends // on the width and height of the box and a change to either triggers a restart // of the animation if running. -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, RestartCompositedAnimationOnSizeChange) { // TODO(crbug.com/389359): Remove forced feature enabling once on by // default. ScopedCompositeRelativeKeyframesForTest composite_relative_keyframes(true); SetBodyInnerHTML(R"HTML( - <div id ="target" - style="width: 100px; height: 200px; will-change: transform"> + <div id="target" style="width: 100px; height: 200px; background: blue; + will-change: transform"> </div> )HTML"); @@ -1765,12 +1553,8 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); // Kick the animation out of the play-pending state. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // No size change and animation does not require a restart. keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( @@ -1795,14 +1579,14 @@ TEST_F(AnimationAnimationTestCompositing, // Regression test to ensure proper restart logic for composited animations on // relative transforms after a size change. In this test, the transform only // depends on width and a change to the height does not trigger a restart. -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, RestartCompositedAnimationOnWidthChange) { // TODO(crbug.com/389359): Remove forced feature enabling once on by // default. ScopedCompositeRelativeKeyframesForTest composite_relative_keyframes(true); SetBodyInnerHTML(R"HTML( - <div id ="target" - style="width: 100px; height: 200px; will-change: transform"> + <div id="target" style="width: 100px; height: 200px; background: blue; + will-change: transform"> </div> )HTML"); @@ -1819,12 +1603,8 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( FloatSize(100, 200)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Transform is not height dependent and a change to the height does not force // an animation restart. @@ -1842,14 +1622,14 @@ TEST_F(AnimationAnimationTestCompositing, // Regression test to ensure proper restart logic for composited animations on // relative transforms after a size change. In this test, the transition only // affects height and a change to the width does not trigger a restart. -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, RestartCompositedAnimationOnHeightChange) { // TODO(crbug.com/389359): Remove forced feature enabling once on by // default. ScopedCompositeRelativeKeyframesForTest composite_relative_keyframes(true); SetBodyInnerHTML(R"HTML( - <div id ="target" - style="width: 100px; height: 200px; will-change: transform"> + <div id="target" style="width: 100px; height: 200px; background: blue; + will-change: transform"> </div> )HTML"); @@ -1866,12 +1646,8 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor()); keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment( FloatSize(100, 200)); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Transform is not width dependent and a change to the width does not force // an animation restart. @@ -1885,13 +1661,60 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_FALSE(animation->HasActiveAnimationsOnCompositor()); } -TEST_F(AnimationAnimationTestCompositing, +// This test ensures that a clip-path animation can start on compositor. +TEST_P(AnimationAnimationTestCompositing, ClipPathComposited) { + ScopedCompositeClipPathAnimationForTest composite_clip_path_animation(true); + SetBodyInnerHTML(R"HTML( + <div id ="target" style="width: 100px; height: 100px; clip-path: circle(50% at 50% 50%)"> + </div> + )HTML"); + + // Create KeyframeEffect + Timing timing; + timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); + + Persistent<StringKeyframe> start_keyframe = + MakeGarbageCollected<StringKeyframe>(); + start_keyframe->SetCSSPropertyValue( + CSSPropertyID::kClipPath, "circle(50% at 50% 50%)", + SecureContextMode::kInsecureContext, nullptr); + Persistent<StringKeyframe> end_keyframe = + MakeGarbageCollected<StringKeyframe>(); + end_keyframe->SetCSSPropertyValue( + CSSPropertyID::kClipPath, "(20% at 20% 20%)", + SecureContextMode::kInsecureContext, nullptr); + + StringKeyframeVector keyframes; + keyframes.push_back(start_keyframe); + keyframes.push_back(end_keyframe); + + Element* element = GetElementById("target"); + auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes); + + NonThrowableExceptionState exception_state; + DocumentTimeline* timeline = + MakeGarbageCollected<DocumentTimeline>(&GetDocument()); + Animation* animation = Animation::Create( + MakeGarbageCollected<KeyframeEffect>(element, model, timing), timeline, + exception_state); + + UpdateAllLifecyclePhasesForTest(); + animation->play(); + EXPECT_EQ(animation->CheckCanStartAnimationOnCompositor(nullptr), + CompositorAnimations::kNoFailure); +} + +TEST_P(AnimationAnimationTestCompositing, ScrollLinkedAnimationCanBeComposited) { ResetWithCompositedAnimation(); SetBodyInnerHTML(R"HTML( <style> - #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; } - #target { width: 100px; height: 200px; will-change: opacity;} + #scroller { + will-change: transform; overflow: scroll; width: 100px; height: 100px; + } + #target { + width: 100px; height: 200px; background: blue; will-change: opacity; + } #spacer { width: 200px; height: 2000px; } </style> <div id ='scroller'> @@ -1907,8 +1730,8 @@ TEST_F(AnimationAnimationTestCompositing, scrollable_area->SetScrollOffset(ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -1950,13 +1773,17 @@ TEST_F(AnimationAnimationTestCompositing, CompositorAnimations::kNoFailure); } -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, StartScrollLinkedAnimationWithStartTimeIfApplicable) { ResetWithCompositedAnimation(); SetBodyInnerHTML(R"HTML( <style> - #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; } - #target { width: 100px; height: 200px; will-change: opacity;} + #scroller { + will-change: transform; overflow: scroll; width: 100px; height: 100px; background: blue; + } + #target { + width: 100px; height: 200px; background: blue; will-change: opacity; + } #spacer { width: 200px; height: 700px; } </style> <div id ='scroller'> @@ -1972,8 +1799,8 @@ TEST_F(AnimationAnimationTestCompositing, scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -2013,13 +1840,9 @@ TEST_F(AnimationAnimationTestCompositing, UpdateAllLifecyclePhasesForTest(); const double TEST_START_TIME = 10; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setStartTime( MakeGarbageCollected<V8CSSNumberish>(TEST_START_TIME), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - scroll_animation->setStartTime(CSSNumberish::FromDouble(TEST_START_TIME)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->play(); EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr), CompositorAnimations::kNoFailure); @@ -2038,7 +1861,7 @@ TEST_F(AnimationAnimationTestCompositing, // Verifies correctness of scroll linked animation current and start times in // various animation states. -TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) { +TEST_P(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) { SetBodyInnerHTML(R"HTML( <style> #scroller { overflow: scroll; width: 100px; height: 100px; } @@ -2055,8 +1878,8 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) { scrollable_area->SetScrollOffset(ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -2090,13 +1913,13 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) { // Verifies that finished composited scroll-linked animations restart on // compositor upon reverse scrolling. -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, FinishedScrollLinkedAnimationRestartsOnReverseScrolling) { ResetWithCompositedAnimation(); SetBodyInnerHTML(R"HTML( <style> #scroller { will-change: transform; overflow: scroll; width: 100px; height: 100px; } - #target { width: 100px; height: 200px; will-change: opacity;} + #target { width: 100px; height: 200px; will-change: opacity; background: green;} #spacer { width: 200px; height: 700px; } </style> <div id ='scroller'> @@ -2111,8 +1934,8 @@ TEST_F(AnimationAnimationTestCompositing, // Create ScrollTimeline ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -2156,24 +1979,16 @@ TEST_F(AnimationAnimationTestCompositing, // Advances the animation to "finished" state. The composited animation will // be destroyed accordingly. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - scroll_animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ(scroll_animation->playState(), "finished"); scroll_animation->Update(kTimingUpdateForAnimationFrame); GetDocument().GetPendingAnimations().Update(nullptr, true); EXPECT_FALSE(scroll_animation->HasActiveAnimationsOnCompositor()); // Restarting the animation should create a new compositor animation. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - scroll_animation->setCurrentTime(CSSNumberish::FromDouble(100)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UpdateAllLifecyclePhasesForTest(); EXPECT_EQ(scroll_animation->playState(), "running"); scroll_animation->Update(kTimingUpdateForAnimationFrame); @@ -2181,7 +1996,7 @@ TEST_F(AnimationAnimationTestCompositing, EXPECT_TRUE(scroll_animation->HasActiveAnimationsOnCompositor()); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, RemoveCanceledAnimationFromActiveSet) { EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -2192,7 +2007,7 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, RemoveFinishedAnimationFromActiveSet) { EXPECT_EQ("running", animation->playState()); EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -2210,17 +2025,13 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); // Asynchronous completion. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); } -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, PendingActivityWithFinishedPromise) { // No pending activity even when running if there is no finished promise // or event listener. @@ -2235,12 +2046,8 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->HasPendingActivity()); // Resolving the finished promise clears the pending activity. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); SimulateMicrotask(); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -2265,7 +2072,7 @@ class MockEventListener final : public NativeEventListener { MOCK_METHOD2(Invoke, void(ExecutionContext*, Event*)); }; -TEST_F(AnimationAnimationTestNoCompositing, +TEST_P(AnimationAnimationTestNoCompositing, PendingActivityWithFinishedEventListener) { EXPECT_EQ("running", animation->playState()); EXPECT_FALSE(animation->HasPendingActivity()); @@ -2290,12 +2097,8 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_TRUE(animation->HasPendingActivity()); // Finishing the animation asynchronously clears the pending activity. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(50000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ("finished", animation->playState()); SimulateMicrotask(); EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); @@ -2313,7 +2116,8 @@ TEST_F(AnimationAnimationTestNoCompositing, EXPECT_FALSE(animation->HasPendingActivity()); } -class AnimationPendingAnimationsTest : public RenderingTest { +class AnimationPendingAnimationsTest : public PaintTestConfigurations, + public RenderingTest { public: AnimationPendingAnimationsTest() : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {} @@ -2379,9 +2183,11 @@ class AnimationPendingAnimationsTest : public RenderingTest { Persistent<DocumentTimeline> timeline; }; -TEST_F(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) { +INSTANTIATE_PAINT_TEST_SUITE_P(AnimationPendingAnimationsTest); + +TEST_P(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) { RunDocumentLifecycle(); - SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>"); + SetBodyInnerHTML("<div id='foo'>f</div><div id='bar'>b</div>"); Animation* animA = MakeAnimation("foo", kComposited); Animation* animB = MakeAnimation("bar", kNonComposited); @@ -2397,10 +2203,10 @@ TEST_F(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) { EXPECT_FALSE(animB->pending()); } -TEST_F(AnimationPendingAnimationsTest, +TEST_P(AnimationPendingAnimationsTest, PendingAnimationCancelUnblocksSynchronizedStart) { RunDocumentLifecycle(); - SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>"); + SetBodyInnerHTML("<div id='foo'>f</div><div id='bar'>b</div>"); Animation* animA = MakeAnimation("foo", kComposited); Animation* animB = MakeAnimation("bar", kNonComposited); @@ -2415,11 +2221,11 @@ TEST_F(AnimationPendingAnimationsTest, EXPECT_FALSE(animB->pending()); } -TEST_F(AnimationPendingAnimationsTest, +TEST_P(AnimationPendingAnimationsTest, PendingAnimationOnlySynchronizeStartsOfNewlyPendingAnimations) { RunDocumentLifecycle(); SetBodyInnerHTML( - "<div id='foo'></div><div id='bar'></div><div id='baz'></div>"); + "<div id='foo'>f</div><div id='bar'>b</div><div id='baz'>z</div>"); Animation* animA = MakeAnimation("foo", kComposited); Animation* animB = MakeAnimation("bar", kNonComposited); @@ -2450,7 +2256,7 @@ TEST_F(AnimationPendingAnimationsTest, EXPECT_FALSE(animD->pending()); } -TEST_F(AnimationAnimationTestCompositing, +TEST_P(AnimationAnimationTestCompositing, ScrollLinkedAnimationNotCompositedIfScrollSourceIsNotComposited) { GetDocument().GetSettings()->SetPreferCompositingToLCDTextEnabled(false); SetBodyInnerHTML(R"HTML( @@ -2475,8 +2281,8 @@ TEST_F(AnimationAnimationTestCompositing, scrollable_area->SetScrollOffset(ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -2518,7 +2324,14 @@ TEST_F(AnimationAnimationTestCompositing, CompositorAnimations::kTimelineSourceHasInvalidCompositingState); } -TEST_F(AnimationAnimationTestCompositing, ContentVisibleDisplayLockTest) { +#if defined(OS_MAC) && defined(ARCH_CPU_ARM64) +// https://crbug.com/1222646 +#define MAYBE_ContentVisibleDisplayLockTest \ + DISABLED_ContentVisibleDisplayLockTest +#else +#define MAYBE_ContentVisibleDisplayLockTest ContentVisibleDisplayLockTest +#endif +TEST_P(AnimationAnimationTestCompositing, MAYBE_ContentVisibleDisplayLockTest) { animation->cancel(); RunDocumentLifecycle(); @@ -2576,4 +2389,120 @@ TEST_F(AnimationAnimationTestCompositing, ContentVisibleDisplayLockTest) { EXPECT_EQ(animation->playState(), "running"); } +TEST_P(AnimationAnimationTestCompositing, HiddenAnimationsDoNotTick) { + // This test applies to CompositeAfterPaint only. + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + + SetBodyInnerHTML(R"HTML( + <style> + @keyframes anim { + from { opacity: 0; } + to { opacity: 1; } + } + #target { + width: 10px; + height: 10px; + background: rebeccapurple; + animation: anim 30s; + } + </style> + <div id="visibility" style="visibility: hidden;"> + <div id="target"></div> + </div> + )HTML"); + + Element* target = GetElementById("target"); + ElementAnimations* element_animations = target->GetElementAnimations(); + ASSERT_EQ(1u, element_animations->Animations().size()); + Animation* animation = element_animations->Animations().begin()->key; + + RunDocumentLifecycle(); + + const PaintArtifactCompositor* paint_artifact_compositor = + GetDocument().View()->GetPaintArtifactCompositor(); + ASSERT_TRUE(paint_artifact_compositor); + + // The animation should run on main because compositor properties are missing. + EXPECT_EQ( + animation->CheckCanStartAnimationOnCompositor(paint_artifact_compositor), + CompositorAnimations::kCompositorPropertyAnimationsHaveNoEffect); + EXPECT_TRUE(animation->CompositorPropertyAnimationsHaveNoEffectForTesting()); + EXPECT_TRUE(animation->AnimationHasNoEffect()); + + // The next effect change should be at the end because the animation does not + // tick while hidden. + EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(30), + animation->TimeToEffectChange().value()); +} + +TEST_P(AnimationAnimationTestCompositing, HiddenAnimationsTickWhenVisible) { + // This test applies to CompositeAfterPaint only. + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + + SetBodyInnerHTML(R"HTML( + <style> + @keyframes anim { + from { opacity: 0; } + to { opacity: 1; } + } + #target { + width: 10px; + height: 10px; + background: rebeccapurple; + animation: anim 30s; + } + </style> + <div id="visibility" style="visibility: hidden;"> + <div id="target"></div> + </div> + )HTML"); + + Element* target = GetElementById("target"); + ElementAnimations* element_animations = target->GetElementAnimations(); + ASSERT_EQ(1u, element_animations->Animations().size()); + Animation* animation = element_animations->Animations().begin()->key; + + RunDocumentLifecycle(); + + const PaintArtifactCompositor* paint_artifact_compositor = + GetDocument().View()->GetPaintArtifactCompositor(); + ASSERT_TRUE(paint_artifact_compositor); + + // The animation should run on main because compositor properties are missing. + EXPECT_EQ( + animation->CheckCanStartAnimationOnCompositor(paint_artifact_compositor), + CompositorAnimations::kCompositorPropertyAnimationsHaveNoEffect); + EXPECT_TRUE(animation->CompositorPropertyAnimationsHaveNoEffectForTesting()); + EXPECT_TRUE(animation->AnimationHasNoEffect()); + + // The no-effect animation doesn't count. The one animation is + // AnimationAnimationTestCompositing::animation_. + EXPECT_EQ(1u, animation->timeline()->AnimationsNeedingUpdateCount()); + + // The next effect change should be at the end because the animation does not + // tick while hidden. + EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(30), + animation->TimeToEffectChange().value()); + + Element* visibility = GetElementById("visibility"); + visibility->setAttribute(html_names::kStyleAttr, "visibility: visible;"); + RunDocumentLifecycle(); + + // The animation should run on the compositor after the properties are + // created. + EXPECT_EQ( + animation->CheckCanStartAnimationOnCompositor(paint_artifact_compositor), + CompositorAnimations::kNoFailure); + EXPECT_FALSE(animation->CompositorPropertyAnimationsHaveNoEffectForTesting()); + EXPECT_FALSE(animation->AnimationHasNoEffect()); + EXPECT_EQ(2u, animation->timeline()->AnimationsNeedingUpdateCount()); + + // The next effect change should be at the end because the animation is + // running on the compositor. + EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(30), + animation->TimeToEffectChange().value()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc index 081611af432..3d1e0176b89 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" #include "third_party/blink/renderer/core/animation/css_interpolation_environment.h" #include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h" #include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h" @@ -78,7 +79,8 @@ void EnsureInterpolatedValueCached(ActiveInterpolations* interpolations, // require our callers to properly register every animation they pass in // here, which the current tests do not do. auto style = document.GetStyleResolver().CreateComputedStyle(); - StyleResolverState state(document, *element, StyleRequest(style.get())); + StyleResolverState state(document, *element, StyleRecalcContext(), + StyleRequest(style.get())); state.SetStyle(style); ActiveInterpolationsMap map; @@ -89,21 +91,19 @@ void EnsureInterpolatedValueCached(ActiveInterpolations* interpolations, cascade.Apply(); } -ScrollTimelineOffsetValue OffsetFromString(Document& document, - const String& string) { - ScrollTimelineOffsetValue result; - +V8ScrollTimelineOffset* OffsetFromString(Document& document, + const String& string) { const CSSValue* value = css_test_helpers::ParseValue( document, "<length-percentage> | auto", string); - if (const auto* primitive = DynamicTo<CSSPrimitiveValue>(value)) - result.SetCSSNumericValue(CSSNumericValue::FromCSSValue(*primitive)); - else if (DynamicTo<CSSIdentifierValue>(value)) - result.SetCSSKeywordValue(CSSKeywordValue::Create("auto")); - else - result.SetString(string); - - return result; + if (const auto* primitive = DynamicTo<CSSPrimitiveValue>(value)) { + return MakeGarbageCollected<V8ScrollTimelineOffset>( + CSSNumericValue::FromCSSValue(*primitive)); + } else if (DynamicTo<CSSIdentifierValue>(value)) { + return MakeGarbageCollected<V8ScrollTimelineOffset>( + CSSKeywordValue::Create("auto")); + } + return MakeGarbageCollected<V8ScrollTimelineOffset>(string); } } // namespace animation_test_helpers diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.h b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.h index dd7018198df..6841d213fc8 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_test_helpers.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TEST_HELPERS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TEST_HELPERS_H_ -#include "third_party/blink/renderer/bindings/core/v8/css_numeric_value_or_string_or_css_keyword_value_or_scroll_timeline_element_based_offset.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/core/animation/interpolation.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" @@ -50,7 +50,7 @@ void EnsureInterpolatedValueCached(ActiveInterpolations*, Document&, Element*); // <length-percentage>. // - A CSSKeywordValue. if the incoming string can be parsed as 'auto'. // - Otherwise, the incoming string. -ScrollTimelineOffsetValue OffsetFromString(Document&, const String&); +V8ScrollTimelineOffset* OffsetFromString(Document&, const String&); } // namespace animation_test_helpers } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h index 83d0364413e..cb47f72f02a 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h @@ -7,10 +7,7 @@ #include "third_party/blink/renderer/core/animation/buildflags.h" -#if BUILDFLAG(BLINK_ANIMATION_USE_TIME_DELTA) #include "base/time/time.h" -#endif - #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc index 26237576c55..de96ec3f84a 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc @@ -41,20 +41,12 @@ bool CompareAnimations(const Member<Animation>& left, Animation::CompareAnimationsOrdering::kPointerOrder); } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* AnimationTimeline::currentTime() { const absl::optional<base::TimeDelta>& result = CurrentPhaseAndTime().time; if (result) return MakeGarbageCollected<V8CSSNumberish>(result->InMillisecondsF()); return nullptr; } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void AnimationTimeline::currentTime(CSSNumberish& currentTime) { - absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; - currentTime = result ? CSSNumberish::FromDouble(result->InMillisecondsF()) - : CSSNumberish(); -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) absl::optional<AnimationTimeDelta> AnimationTimeline::CurrentTime() { absl::optional<base::TimeDelta> result = CurrentPhaseAndTime().time; @@ -73,15 +65,9 @@ absl::optional<double> AnimationTimeline::CurrentTimeSeconds() { return result ? absl::make_optional(result->InSecondsF()) : absl::nullopt; } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* AnimationTimeline::duration() { return nullptr; } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void AnimationTimeline::duration(CSSNumberish& duration) { - duration = CSSNumberish(); -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) String AnimationTimeline::phase() { switch (CurrentPhaseAndTime().phase) { @@ -101,6 +87,17 @@ void AnimationTimeline::ClearOutdatedAnimation(Animation* animation) { outdated_animation_count_--; } +wtf_size_t AnimationTimeline::AnimationsNeedingUpdateCount() const { + wtf_size_t count = 0; + for (const auto& animation : animations_needing_update_) { + // This function is for frame sequence tracking for animations. Exclude + // no-effect animations which don't generate frames. + if (!animation->AnimationHasNoEffect()) + count++; + } + return count; +} + bool AnimationTimeline::NeedsAnimationTimingUpdate() { PhaseAndTime current_phase_and_time = CurrentPhaseAndTime(); if (current_phase_and_time == last_current_phase_and_time_) @@ -205,6 +202,14 @@ void AnimationTimeline::MarkAnimationsCompositorPending(bool source_changed) { } } +void AnimationTimeline::MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor* paint_artifact_compositor) { + for (const auto& animation : animations_) { + animation->MarkPendingIfCompositorPropertyAnimationChanges( + paint_artifact_compositor); + } +} + void AnimationTimeline::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(animations_needing_update_); diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h index 0ab43c1998f..082f0547a1c 100644 --- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h @@ -35,20 +35,12 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { AnimationTimeline(Document*); ~AnimationTimeline() override = default; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) virtual V8CSSNumberish* currentTime(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - virtual void currentTime(CSSNumberish&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) absl::optional<AnimationTimeDelta> CurrentTime(); absl::optional<double> CurrentTimeMilliseconds(); absl::optional<double> CurrentTimeSeconds(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) virtual V8CSSNumberish* duration(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - virtual void duration(CSSNumberish&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) String phase(); TimelinePhase Phase() { return CurrentPhaseAndTime().phase; } @@ -56,6 +48,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { virtual bool IsDocumentTimeline() const { return false; } virtual bool IsScrollTimeline() const { return false; } virtual bool IsCSSScrollTimeline() const { return false; } + virtual bool IsProgressBasedTimeline() const { return false; } virtual bool IsActive() const = 0; virtual AnimationTimeDelta ZeroTime() = 0; // https://drafts.csswg.org/web-animations/#monotonically-increasing-timeline @@ -71,6 +64,10 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { // Changing scroll-linked animation start_time initialization is under // consideration here: https://github.com/w3c/csswg-drafts/issues/2075. virtual absl::optional<base::TimeDelta> InitialStartTimeForAnimations() = 0; + virtual AnimationTimeDelta CalculateIntrinsicIterationDuration( + const Timing&) { + return AnimationTimeDelta(); + } Document* GetDocument() { return document_; } virtual void AnimationAttached(Animation*); virtual void AnimationDetached(Animation*); @@ -92,9 +89,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { void SetOutdatedAnimation(Animation*); void ClearOutdatedAnimation(Animation*); - virtual wtf_size_t AnimationsNeedingUpdateCount() const { - return animations_needing_update_.size(); - } + virtual wtf_size_t AnimationsNeedingUpdateCount() const; const HeapHashSet<WeakMember<Animation>>& GetAnimations() const { return animations_; } @@ -107,6 +102,11 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { void MarkAnimationsCompositorPending(bool source_changed = false); + // Checks for animations of composited properties that would have no effect + // and marks them as pending if this changes. + void MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor*); + using ReplaceableAnimationsMap = HeapHashMap<Member<Element>, Member<HeapVector<Member<Animation>>>>; void getReplaceableAnimations( @@ -114,6 +114,10 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { void Trace(Visitor*) const override; + virtual absl::optional<AnimationTimeDelta> GetDuration() const { + return absl::nullopt; + } + protected: virtual PhaseAndTime CurrentPhaseAndTime() = 0; diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc index 4da41e05724..2e1e6decce4 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc @@ -187,8 +187,10 @@ bool IsNoOpBGColorOrVariableAnimation(const PropertyHandle& property, return is_no_op_variable_anim || is_no_op_bgcolor_anim; } -bool CompositedAnimationRequiresProperties(CSSPropertyID property) { - switch (property) { +bool CompositedAnimationRequiresProperties(const PropertyHandle& property) { + if (!property.IsCSSProperty()) + return false; + switch (property.GetCSSProperty().PropertyID()) { case CSSPropertyID::kOpacity: case CSSPropertyID::kBackdropFilter: case CSSPropertyID::kRotate: @@ -200,7 +202,6 @@ bool CompositedAnimationRequiresProperties(CSSPropertyID property) { default: return false; } - return false; } } // namespace @@ -220,6 +221,7 @@ CompositorAnimations::CompositorElementNamespaceForProperty( case CSSPropertyID::kFilter: return CompositorElementIdNamespace::kEffectFilter; case CSSPropertyID::kBackgroundColor: + case CSSPropertyID::kClipPath: case CSSPropertyID::kVariable: // TODO(crbug.com/883721): Variables and background color should not // require the target element to have any composited property tree nodes - @@ -327,12 +329,19 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( bool background_transfers_to_view = false; Animation* compositable_animation = nullptr; if (RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled()) { + // Not having a layout object is a reason for not compositing marked + // in CompositorAnimations::CheckCanStartElementOnCompositor. + if (!layout_object) + continue; BackgroundColorPaintImageGenerator* generator = target_element.GetDocument() .GetFrame() ->GetBackgroundColorPaintImageGenerator(); - compositable_animation = - generator->GetAnimationIfCompositable(&target_element); + // The generator may be null in tests. + if (generator) { + compositable_animation = + generator->GetAnimationIfCompositable(&target_element); + } // When this is true, we have a background-color animation in the // body element, while the view is responsible for painting the // body's background. In this case, we need to let the @@ -348,7 +357,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( // BackgroundColorPaintWorklet, as a result, we should not composite // the background color animation on the table rows or cols. if (!RuntimeEnabledFeatures::CompositeBGColorAnimationEnabled() || - !layout_object || layout_object->IsLayoutTableCol() || + layout_object->IsLayoutTableCol() || layout_object->IsTableRow() || background_transfers_to_view || !compositable_animation) { DefaultToUnsupportedProperty(unsupported_properties, property, @@ -356,6 +365,13 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( } break; } + case CSSPropertyID::kClipPath: { + if (!RuntimeEnabledFeatures::CompositeClipPathAnimationEnabled()) { + DefaultToUnsupportedProperty(unsupported_properties, property, + &reasons); + } + break; + } case CSSPropertyID::kVariable: { // Custom properties are supported only in the case of // OffMainThreadCSSPaintEnabled, and even then only for some specific @@ -391,11 +407,9 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( break; } default: - // We skip the rest of the loop in this case for two reasons: - // i. Getting a CompositorElementId below will DCHECK if we pass it - // an unsupported property. - // ii. GetCompositorKeyframeValue() will be false so we will - // accidentally count this as kInvalidAnimationOrEffect as well. + // We skip the rest of the loop in this case because + // |GetCompositorKeyframeValue()| will be false so we will + // accidentally count this as kInvalidAnimationOrEffect as well. DefaultToUnsupportedProperty(unsupported_properties, property, &reasons); continue; @@ -406,31 +420,14 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( if (!keyframe->GetCompositorKeyframeValue()) { reasons |= kInvalidAnimationOrEffect; } - - if (CompositedAnimationRequiresProperties( - property.GetCSSProperty().PropertyID())) { - if (!paint_artifact_compositor) { - // TODO(pdr): We should return |kTargetHasInvalidCompositingState|. - continue; - } else if (!target_element.GetLayoutObject() || - !target_element.GetLayoutObject() - ->FirstFragment() - .PaintProperties()) { - reasons |= kTargetHasInvalidCompositingState; - } else { - CompositorElementId target_element_id = - CompositorElementIdFromUniqueObjectId( - layout_object->UniqueId(), - CompositorElementNamespaceForProperty( - property.GetCSSProperty().PropertyID())); - DCHECK(target_element_id); - if (!paint_artifact_compositor->HasComposited(target_element_id)) - reasons |= kTargetHasInvalidCompositingState; - } - } } } + if (CompositorPropertyAnimationsHaveNoEffect(target_element, effect, + paint_artifact_compositor)) { + reasons |= kCompositorPropertyAnimationsHaveNoEffect; + } + // TODO: Support multiple transform property animations on the compositor if (transform_property_count > 1) reasons |= kMultipleTransformAnimationsOnSameTarget; @@ -452,6 +449,54 @@ CompositorAnimations::CheckCanStartEffectOnCompositor( return reasons; } +bool CompositorAnimations::CompositorPropertyAnimationsHaveNoEffect( + const Element& target_element, + const EffectModel& effect, + const PaintArtifactCompositor* paint_artifact_compositor) { + LayoutObject* layout_object = target_element.GetLayoutObject(); + if (!layout_object || !layout_object->FirstFragment().PaintProperties()) + return false; + + if (!paint_artifact_compositor) { + // TODO(pdr): This should return true. This likely only affects tests. + return false; + } + + bool any_compositor_properties_missing = false; + bool any_compositor_properties_present = false; + + const auto& keyframe_effect = To<KeyframeEffectModelBase>(effect); + const auto& groups = keyframe_effect.GetPropertySpecificKeyframeGroups(); + for (const PropertyHandle& property : groups.Keys()) { + if (!CompositedAnimationRequiresProperties(property)) + continue; + + CompositorElementId target_element_id = + CompositorElementIdFromUniqueObjectId( + layout_object->UniqueId(), + CompositorAnimations::CompositorElementNamespaceForProperty( + property.GetCSSProperty().PropertyID())); + DCHECK(target_element_id); + if (paint_artifact_compositor->HasComposited(target_element_id)) + any_compositor_properties_present = true; + else + any_compositor_properties_missing = true; + } + + // Because animations are a direct compositing reason for paint properties, + // the only case when we wouldn't have compositor paint properties if when + // they were optimized out due to not having an effect. An example of this is + // hidden animations that do not paint. + if (any_compositor_properties_missing) { + // Because animations create all properties (crbug.com/900241), we should + // either have all properties or be missing all properties. + DCHECK(!any_compositor_properties_present); + return true; + } + + return false; +} + CompositorAnimations::FailureReasons CompositorAnimations::CheckCanStartElementOnCompositor( const Element& target_element, @@ -663,9 +708,20 @@ bool CompositorAnimations::ConvertTimingForCompositor( DCHECK(animation_playback_rate); double delay = animation_playback_rate > 0 ? timing.start_delay.InSecondsF() : 0; - out.scaled_time_offset = - -base::TimeDelta::FromSecondsD(delay / animation_playback_rate) + - time_offset; + + base::TimeDelta scaled_delay = + base::TimeDelta::FromSecondsD(delay / animation_playback_rate); + + // Arithmetic operations involving a value that is effectively +/-infinity + // result in a value that is +/-infinity or undefined. Check before computing + // the scaled time offset to guard against the following: + // infinity - infinity or + // -infinity + infinity + // The result of either of these edge cases is undefined. + if (scaled_delay.is_max() || scaled_delay.is_min()) + return false; + + out.scaled_time_offset = -scaled_delay + time_offset; // Delay is effectively +/- infinity. if (out.scaled_time_offset.is_max() || out.scaled_time_offset.is_min()) return false; @@ -782,9 +838,6 @@ void CompositorAnimations::GetAnimationOnCompositor( PropertyHandleSet properties = effect.Properties(); DCHECK(!properties.IsEmpty()); for (const auto& property : properties) { - AtomicString custom_property_name = ""; - CompositorPaintWorkletInput::NativePropertyType native_property_type = - CompositorPaintWorkletInput::NativePropertyType::kInvalid; // If the animation duration is infinite, it doesn't make sense to scale // the keyframe offset, so use a scale of 1.0. This is connected to // the known issue of how the Web Animations spec handles infinite @@ -795,31 +848,32 @@ void CompositorAnimations::GetAnimationOnCompositor( const PropertySpecificKeyframeVector& values = *effect.GetPropertySpecificKeyframes(property); - compositor_target_property::Type target_property; std::unique_ptr<CompositorAnimationCurve> curve; DCHECK(timing.timing_function); + absl::optional<CompositorKeyframeModel::TargetPropertyId> + target_property_id = absl::nullopt; switch (property.GetCSSProperty().PropertyID()) { case CSSPropertyID::kOpacity: { - target_property = compositor_target_property::OPACITY; auto float_curve = std::make_unique<CompositorFloatAnimationCurve>(); AddKeyframesToCurve(*float_curve, values); float_curve->SetTimingFunction(*timing.timing_function); float_curve->SetScaledDuration(scale); curve = std::move(float_curve); + target_property_id = CompositorKeyframeModel::TargetPropertyId( + compositor_target_property::OPACITY); break; } case CSSPropertyID::kFilter: case CSSPropertyID::kBackdropFilter: { - target_property = compositor_target_property::FILTER; - if (property.GetCSSProperty().PropertyID() == - CSSPropertyID::kBackdropFilter) { - target_property = compositor_target_property::BACKDROP_FILTER; - } auto filter_curve = std::make_unique<CompositorFilterAnimationCurve>(); AddKeyframesToCurve(*filter_curve, values); filter_curve->SetTimingFunction(*timing.timing_function); filter_curve->SetScaledDuration(scale); curve = std::move(filter_curve); + target_property_id = CompositorKeyframeModel::TargetPropertyId( + property.GetCSSProperty().PropertyID() == CSSPropertyID::kFilter + ? compositor_target_property::FILTER + : compositor_target_property::BACKDROP_FILTER); break; } case CSSPropertyID::kRotate: @@ -829,31 +883,35 @@ void CompositorAnimations::GetAnimationOnCompositor( FloatSize box_size = ComputedStyleUtils::ReferenceBoxForTransform( *target_element.GetLayoutObject()) .Size(); - target_property = compositor_target_property::TRANSFORM; auto transform_curve = std::make_unique<CompositorTransformAnimationCurve>(); AddKeyframesToCurve(*transform_curve, values, box_size); transform_curve->SetTimingFunction(*timing.timing_function); transform_curve->SetScaledDuration(scale); curve = std::move(transform_curve); + target_property_id = CompositorKeyframeModel::TargetPropertyId( + compositor_target_property::TRANSFORM); break; } - case CSSPropertyID::kBackgroundColor: { - native_property_type = - CompositorPaintWorkletInput::NativePropertyType::kBackgroundColor; + case CSSPropertyID::kBackgroundColor: + case CSSPropertyID::kClipPath: { + CompositorPaintWorkletInput::NativePropertyType native_property_type = + property.GetCSSProperty().PropertyID() == + CSSPropertyID::kBackgroundColor + ? CompositorPaintWorkletInput::NativePropertyType:: + kBackgroundColor + : CompositorPaintWorkletInput::NativePropertyType::kClipPath; auto float_curve = std::make_unique<CompositorFloatAnimationCurve>(); - target_property = compositor_target_property::NATIVE_PROPERTY; AddKeyframesToCurve(*float_curve, values); float_curve->SetTimingFunction(*timing.timing_function); float_curve->SetScaledDuration(scale); curve = std::move(float_curve); + target_property_id = CompositorKeyframeModel::TargetPropertyId( + compositor_target_property::NATIVE_PROPERTY, native_property_type); break; } case CSSPropertyID::kVariable: { DCHECK(RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()); - custom_property_name = property.CustomPropertyName(); - target_property = compositor_target_property::CSS_CUSTOM_PROPERTY; - // Create curve based on the keyframe value type if (values.front()->GetCompositorKeyframeValue()->IsColor()) { auto color_curve = std::make_unique<CompositorColorAnimationCurve>(); @@ -868,6 +926,9 @@ void CompositorAnimations::GetAnimationOnCompositor( float_curve->SetScaledDuration(scale); curve = std::move(float_curve); } + target_property_id = CompositorKeyframeModel::TargetPropertyId( + compositor_target_property::CSS_CUSTOM_PROPERTY, + property.CustomPropertyName().Utf8().data()); break; } default: @@ -875,19 +936,10 @@ void CompositorAnimations::GetAnimationOnCompositor( continue; } DCHECK(curve.get()); - - std::unique_ptr<CompositorKeyframeModel> keyframe_model; - if (!custom_property_name.IsEmpty()) { - keyframe_model = std::make_unique<CompositorKeyframeModel>( - *curve, target_property, 0, group, std::move(custom_property_name)); - } else if (native_property_type != - CompositorPaintWorkletInput::NativePropertyType::kInvalid) { - keyframe_model = std::make_unique<CompositorKeyframeModel>( - *curve, target_property, 0, group, native_property_type); - } else { - keyframe_model = std::make_unique<CompositorKeyframeModel>( - *curve, target_property, 0, group); - } + DCHECK(target_property_id.has_value()); + std::unique_ptr<CompositorKeyframeModel> keyframe_model = + std::make_unique<CompositorKeyframeModel>( + *curve, 0, group, std::move(target_property_id.value())); if (start_time) keyframe_model->SetStartTime(start_time.value()); diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h index 678215237a4..82743a275db 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h @@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_COMPOSITOR_ANIMATIONS_H_ #include <memory> +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/effect_model.h" #include "third_party/blink/renderer/core/animation/keyframe.h" #include "third_party/blink/renderer/core/animation/timing.h" @@ -98,11 +99,15 @@ class CORE_EXPORT CompositorAnimations { // Cases where the scroll timeline source is not composited. kTimelineSourceHasInvalidCompositingState = 1 << 16, + // Cases where there is an animation of compositor properties but they have + // been optimized out so the animation of those properties has no effect. + kCompositorPropertyAnimationsHaveNoEffect = 1 << 17, + // The maximum number of flags in this enum (excluding itself). New flags // should increment this number but it should never be decremented because // the values are used in UMA histograms. It should also be noted that it // excludes the kNoFailure value. - kFailureReasonCount = 17, + kFailureReasonCount = 18, }; static FailureReasons CheckCanStartAnimationOnCompositor( @@ -113,6 +118,10 @@ class CORE_EXPORT CompositorAnimations { const PaintArtifactCompositor*, double animation_playback_rate, PropertyHandleSet* unsupported_properties = nullptr); + static bool CompositorPropertyAnimationsHaveNoEffect( + const Element& target_element, + const EffectModel& effect, + const PaintArtifactCompositor*); static void CancelIncompatibleAnimationsOnCompositor(const Element&, const Animation&, const EffectModel&); diff --git a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc index 45174540cfe..353a6c76e7e 100644 --- a/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc @@ -52,6 +52,7 @@ #include "third_party/blink/renderer/core/css/css_syntax_definition.h" #include "third_party/blink/renderer/core/css/css_test_helpers.h" #include "third_party/blink/renderer/core/css/mock_css_paint_image_generator.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" @@ -754,6 +755,11 @@ TEST_P(AnimationCompositorAnimationsTest, EXPECT_TRUE( ConvertTimingForCompositor(timing_, compositor_timing_, play_reverse)); EXPECT_DOUBLE_EQ(0.0, compositor_timing_.scaled_time_offset.InSecondsF()); + + // Stress test with an effectively infinite start delay. + timing_.start_delay = AnimationTimeDelta::FromSecondsD(1e19); + EXPECT_FALSE( + ConvertTimingForCompositor(timing_, compositor_timing_, play_forward)); } TEST_P(AnimationCompositorAnimationsTest, @@ -2339,9 +2345,14 @@ TEST_P(AnimationCompositorAnimationsTest, Fragmented) { 0% { transform: translateX(10px); } 100% { transform: translateX(20px); } } + #target { + width: 10px; + height: 150px; + background: green; + } </style> <div style="columns: 2; height: 100px"> - <div id="target" style="height: 150px; animation: move 1s infinite"> + <div id="target" style="animation: move 1s infinite"> </div> </div> )HTML"); diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc index fc5d1f41582..8e69843d00c 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.cc @@ -68,7 +68,8 @@ CompositorKeyframeValue* CompositorKeyframeValueFactory::Create( return CreateFromTransformProperties(style.Scale(), style.EffectiveZoom(), nullptr); } - case CSSPropertyID::kBackgroundColor: { + case CSSPropertyID::kBackgroundColor: + case CSSPropertyID::kClipPath: { return MakeGarbageCollected<CompositorKeyframeDouble>(offset); } case CSSPropertyID::kVariable: { diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc index 34f54d30029..22dc98e467d 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc @@ -13,7 +13,7 @@ namespace blink { CSSAnimation::CSSAnimation(ExecutionContext* execution_context, AnimationTimeline* timeline, AnimationEffect* content, - int animation_index, + wtf_size_t animation_index, const String& animation_name) : Animation(execution_context, timeline, content), animation_index_(animation_index), @@ -60,19 +60,11 @@ void CSSAnimation::setTimeline(AnimationTimeline* timeline) { ignore_css_timeline_ = true; } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void CSSAnimation::setStartTime(const V8CSSNumberish* start_time, ExceptionState& exception_state) { PlayStateTransitionScope scope(*this); Animation::setStartTime(start_time, exception_state); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void CSSAnimation::setStartTime(CSSNumberish start_time_ms, - ExceptionState& exception_state) { - PlayStateTransitionScope scope(*this); - Animation::setStartTime(start_time_ms, exception_state); -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) AnimationEffect::EventDelegate* CSSAnimation::CreateEventDelegate( Element* target, diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h index ad68b5b8c37..a531dac2167 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.h @@ -19,7 +19,7 @@ class CORE_EXPORT CSSAnimation : public Animation { CSSAnimation(ExecutionContext*, AnimationTimeline*, AnimationEffect*, - int animation_index, + wtf_size_t animation_index, const String& animation_name); bool IsCSSAnimation() const final { return true; } @@ -28,7 +28,7 @@ class CORE_EXPORT CSSAnimation : public Animation { Element* OwningElement() const override { return owning_element_; } const String& animationName() const { return animation_name_; } - int AnimationIndex() const { return animation_index_; } + wtf_size_t AnimationIndex() const { return animation_index_; } void SetAnimationIndex(wtf_size_t absolute_position) { animation_index_ = absolute_position; } @@ -51,12 +51,8 @@ class CORE_EXPORT CSSAnimation : public Animation { void play(ExceptionState& = ASSERT_NO_EXCEPTION) override; void reverse(ExceptionState& = ASSERT_NO_EXCEPTION) override; void setTimeline(AnimationTimeline*) override; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void setStartTime(const V8CSSNumberish* start_time, ExceptionState& exception_state) override; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - void setStartTime(CSSNumberish, ExceptionState&) override; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // When set, subsequent changes to animation-play-state no longer affect the // play state. @@ -98,7 +94,7 @@ class CORE_EXPORT CSSAnimation : public Animation { // animation_index_ represents the absolute position of an animation within // the same owning element. This index helps resolve the animation ordering // when comparing two animations with the same owning element. - int animation_index_; + wtf_size_t animation_index_; AtomicString animation_name_; // When set, the web-animation API is overruling the animation-play-state diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.cc index 8fd81d08efe..fcbaa038ca2 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.cc @@ -17,14 +17,10 @@ void CSSAnimationUpdate::Copy(const CSSAnimationUpdate& update) { new_animations_ = update.NewAnimations(); animations_with_updates_ = update.AnimationsWithUpdates(); new_transitions_ = update.NewTransitions(); - active_interpolations_for_custom_animations_ = - update.ActiveInterpolationsForCustomAnimations(); - active_interpolations_for_standard_animations_ = - update.ActiveInterpolationsForStandardAnimations(); - active_interpolations_for_custom_transitions_ = - update.ActiveInterpolationsForCustomTransitions(); - active_interpolations_for_standard_transitions_ = - update.ActiveInterpolationsForStandardTransitions(); + active_interpolations_for_animations_ = + update.ActiveInterpolationsForAnimations(); + active_interpolations_for_transitions_ = + update.ActiveInterpolationsForTransitions(); cancelled_animation_indices_ = update.CancelledAnimationIndices(); animation_indices_with_pause_toggled_ = update.AnimationIndicesWithPauseToggled(); @@ -37,10 +33,8 @@ void CSSAnimationUpdate::Clear() { new_animations_.clear(); animations_with_updates_.clear(); new_transitions_.clear(); - active_interpolations_for_custom_animations_.clear(); - active_interpolations_for_standard_animations_.clear(); - active_interpolations_for_custom_transitions_.clear(); - active_interpolations_for_standard_transitions_.clear(); + active_interpolations_for_animations_.clear(); + active_interpolations_for_transitions_.clear(); cancelled_animation_indices_.clear(); animation_indices_with_pause_toggled_.clear(); cancelled_transitions_.clear(); diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h index d2143017e86..024f65b5583 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATION_UPDATE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATION_UPDATE_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/effect_stack.h" #include "third_party/blink/renderer/core/animation/inert_effect.h" @@ -29,7 +28,7 @@ class NewCSSAnimation { public: NewCSSAnimation(AtomicString name, size_t name_index, - size_t position_index, + wtf_size_t position_index, const InertEffect& effect, Timing timing, StyleRuleKeyframes* style_rule, @@ -53,7 +52,7 @@ class NewCSSAnimation { AtomicString name; size_t name_index; - size_t position_index; + wtf_size_t position_index; Member<const InertEffect> effect; Timing timing; Member<StyleRuleKeyframes> style_rule; @@ -114,6 +113,8 @@ class CORE_EXPORT CSSAnimationUpdate final { public: CSSAnimationUpdate(); + CSSAnimationUpdate(const CSSAnimationUpdate&) = delete; + CSSAnimationUpdate& operator=(const CSSAnimationUpdate&) = delete; ~CSSAnimationUpdate(); void Copy(const CSSAnimationUpdate&); @@ -210,58 +211,35 @@ class CORE_EXPORT CSSAnimationUpdate final { return finished_transitions_; } - void AdoptActiveInterpolationsForCustomAnimations( + void AdoptActiveInterpolationsForAnimations( ActiveInterpolationsMap& new_map) { - new_map.swap(active_interpolations_for_custom_animations_); + new_map.swap(active_interpolations_for_animations_); } - void AdoptActiveInterpolationsForStandardAnimations( + void AdoptActiveInterpolationsForTransitions( ActiveInterpolationsMap& new_map) { - new_map.swap(active_interpolations_for_standard_animations_); + new_map.swap(active_interpolations_for_transitions_); } - void AdoptActiveInterpolationsForCustomTransitions( - ActiveInterpolationsMap& new_map) { - new_map.swap(active_interpolations_for_custom_transitions_); - } - void AdoptActiveInterpolationsForStandardTransitions( - ActiveInterpolationsMap& new_map) { - new_map.swap(active_interpolations_for_standard_transitions_); - } - const ActiveInterpolationsMap& ActiveInterpolationsForCustomAnimations() - const { - return active_interpolations_for_custom_animations_; - } - ActiveInterpolationsMap& ActiveInterpolationsForCustomAnimations() { - return active_interpolations_for_custom_animations_; + const ActiveInterpolationsMap& ActiveInterpolationsForAnimations() const { + return active_interpolations_for_animations_; } - const ActiveInterpolationsMap& ActiveInterpolationsForStandardAnimations() - const { - return active_interpolations_for_standard_animations_; + ActiveInterpolationsMap& ActiveInterpolationsForAnimations() { + return active_interpolations_for_animations_; } - ActiveInterpolationsMap& ActiveInterpolationsForStandardAnimations() { - return active_interpolations_for_standard_animations_; - } - const ActiveInterpolationsMap& ActiveInterpolationsForCustomTransitions() - const { - return active_interpolations_for_custom_transitions_; - } - const ActiveInterpolationsMap& ActiveInterpolationsForStandardTransitions() - const { - return active_interpolations_for_standard_transitions_; + const ActiveInterpolationsMap& ActiveInterpolationsForTransitions() const { + return active_interpolations_for_transitions_; } - bool IsEmpty() const { - return new_animations_.IsEmpty() && - cancelled_animation_indices_.IsEmpty() && - suppressed_animations_.IsEmpty() && - animation_indices_with_pause_toggled_.IsEmpty() && - animations_with_updates_.IsEmpty() && new_transitions_.IsEmpty() && - cancelled_transitions_.IsEmpty() && - finished_transitions_.IsEmpty() && - active_interpolations_for_custom_animations_.IsEmpty() && - active_interpolations_for_standard_animations_.IsEmpty() && - active_interpolations_for_custom_transitions_.IsEmpty() && - active_interpolations_for_standard_transitions_.IsEmpty() && - updated_compositor_keyframes_.IsEmpty(); + bool IsEmpty() const { return !HasUpdates() && !HasActiveInterpolations(); } + + bool HasUpdates() const { + return !new_animations_.IsEmpty() || + !cancelled_animation_indices_.IsEmpty() || + !suppressed_animations_.IsEmpty() || + !animation_indices_with_pause_toggled_.IsEmpty() || + !animations_with_updates_.IsEmpty() || !new_transitions_.IsEmpty() || + !cancelled_transitions_.IsEmpty() || + !finished_transitions_.IsEmpty() || + !updated_compositor_keyframes_.IsEmpty(); } void Trace(Visitor* visitor) const { @@ -270,13 +248,16 @@ class CORE_EXPORT CSSAnimationUpdate final { visitor->Trace(suppressed_animations_); visitor->Trace(animations_with_updates_); visitor->Trace(updated_compositor_keyframes_); - visitor->Trace(active_interpolations_for_custom_animations_); - visitor->Trace(active_interpolations_for_standard_animations_); - visitor->Trace(active_interpolations_for_custom_transitions_); - visitor->Trace(active_interpolations_for_standard_transitions_); + visitor->Trace(active_interpolations_for_animations_); + visitor->Trace(active_interpolations_for_transitions_); } private: + bool HasActiveInterpolations() const { + return !active_interpolations_for_animations_.IsEmpty() || + !active_interpolations_for_transitions_.IsEmpty(); + } + // Order is significant since it defines the order in which new animations // will be started. Note that there may be multiple animations present // with the same name, due to the way in which we split up animations with @@ -292,13 +273,10 @@ class CORE_EXPORT CSSAnimationUpdate final { HashSet<PropertyHandle> cancelled_transitions_; HashSet<PropertyHandle> finished_transitions_; - ActiveInterpolationsMap active_interpolations_for_custom_animations_; - ActiveInterpolationsMap active_interpolations_for_standard_animations_; - ActiveInterpolationsMap active_interpolations_for_custom_transitions_; - ActiveInterpolationsMap active_interpolations_for_standard_transitions_; + ActiveInterpolationsMap active_interpolations_for_animations_; + ActiveInterpolationsMap active_interpolations_for_transitions_; friend class PendingAnimationUpdate; - DISALLOW_COPY_AND_ASSIGN(CSSAnimationUpdate); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc index 37c670acca9..0bc89d41ee9 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.cc @@ -63,6 +63,7 @@ #include "third_party/blink/renderer/core/css/parser/css_variable_parser.h" #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" #include "third_party/blink/renderer/core/css/properties/css_property.h" +#include "third_party/blink/renderer/core/css/properties/css_property_ref.h" #include "third_party/blink/renderer/core/css/property_registry.h" #include "third_party/blink/renderer/core/css/resolver/css_to_style_map.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" @@ -86,7 +87,7 @@ namespace blink { -using PropertySet = HashSet<const CSSProperty*>; +using PropertySet = HashSet<CSSPropertyName>; namespace { @@ -116,11 +117,12 @@ StringKeyframeVector ProcessKeyframesRule( keyframe->SetEasing(default_timing_function); const CSSPropertyValueSet& properties = style_keyframe->Properties(); for (unsigned j = 0; j < properties.PropertyCount(); j++) { - // TODO(crbug.com/980160): Remove access to static Variable instance. - const CSSProperty& property = - CSSProperty::Get(properties.PropertyAt(j).Id()); + CSSPropertyValueSet::PropertyReference property_reference = + properties.PropertyAt(j); + CSSPropertyRef ref(property_reference.Name(), document); + const CSSProperty& property = ref.GetProperty(); if (property.PropertyID() == CSSPropertyID::kAnimationTimingFunction) { - const CSSValue& value = properties.PropertyAt(j).Value(); + const CSSValue& value = property_reference.Value(); scoped_refptr<TimingFunction> timing_function; if (value.IsInheritedValue() && parent_style->Animations()) { timing_function = parent_style->Animations()->TimingFunctionList()[0]; @@ -137,8 +139,8 @@ StringKeyframeVector ProcessKeyframesRule( const CSSProperty& physical_property = property.ResolveDirectionAwareProperty(text_direction, writing_mode); - keyframe->SetCSSPropertyValue(physical_property, - properties.PropertyAt(j).Value()); + const CSSPropertyName& name = physical_property.GetCSSPropertyName(); + keyframe->SetCSSPropertyValue(name, property_reference.Value()); } } keyframes.push_back(keyframe); @@ -315,25 +317,26 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel( // to animated properties. StringKeyframe* keyframe = keyframes[target_index]; for (const auto& property : rule_keyframe->Properties()) { - const CSSProperty& css_property = property.GetCSSProperty(); + CSSPropertyName property_name = property.GetCSSPropertyName(); // Since processing keyframes in reverse order, skipping properties that // have already been inserted prevents overwriting a later merged // keyframe. - if (current_offset_properties.Contains(&css_property)) + if (current_offset_properties.Contains(property_name)) continue; if (source_index != target_index) { keyframe->SetCSSPropertyValue( - css_property, rule_keyframe->CssPropertyValue(property)); + property.GetCSSPropertyName(), + rule_keyframe->CssPropertyValue(property)); } - current_offset_properties.insert(&css_property); - animated_properties.insert(&css_property); + current_offset_properties.insert(property_name); + animated_properties.insert(property_name); if (keyframe_offset == 0) - start_properties.insert(&css_property); + start_properties.insert(property_name); else if (keyframe_offset == 1) - end_properties.insert(&css_property); + end_properties.insert(property_name); } } @@ -405,9 +408,9 @@ AnimationTimeDelta StartTimeFromDelay(AnimationTimeDelta start_delay) { // Timing functions for computing elapsed time of an event. AnimationTimeDelta IntervalStart(const AnimationEffect& effect) { - AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; + AnimationTimeDelta start_delay = effect.NormalizedTiming().start_delay; const AnimationTimeDelta active_duration = - effect.SpecifiedTiming().ActiveDuration(); + effect.NormalizedTiming().active_duration; // This fixes a problem where start_delay could be -0 if (!start_delay.is_zero()) { start_delay = -start_delay; @@ -416,10 +419,10 @@ AnimationTimeDelta IntervalStart(const AnimationEffect& effect) { } AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) { - const AnimationTimeDelta start_delay = effect.SpecifiedTiming().start_delay; - const AnimationTimeDelta end_delay = effect.SpecifiedTiming().end_delay; + const AnimationTimeDelta start_delay = effect.NormalizedTiming().start_delay; + const AnimationTimeDelta end_delay = effect.NormalizedTiming().end_delay; const AnimationTimeDelta active_duration = - effect.SpecifiedTiming().ActiveDuration(); + effect.NormalizedTiming().active_duration; const AnimationTimeDelta target_effect_end = std::max(start_delay + active_duration + end_delay, AnimationTimeDelta()); return std::max(std::min(target_effect_end - start_delay, active_duration), @@ -434,41 +437,12 @@ AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect, : current_iteration; const double iteration_start = effect.SpecifiedTiming().iteration_start; const AnimationTimeDelta iteration_duration = - effect.SpecifiedTiming().IterationDuration(); + effect.NormalizedTiming().iteration_duration; return iteration_duration * (iteration_boundary - iteration_start); } -CSSScrollTimeline* CreateCSSScrollTimeline( - Document& document, - CSSScrollTimeline::Options&& options) { - if (!options.IsValid()) - return nullptr; - auto* scroll_timeline = - MakeGarbageCollected<CSSScrollTimeline>(&document, std::move(options)); - // It's is not allowed for a style resolve to create timelines that - // needs timing updates (i.e. AnimationTimeline::NeedsAnimationTimingUpdate() - // must return false). Servicing animations after creation preserves this - // invariant by ensuring the last-update time of the timeline is equal to - // the current time. - scroll_timeline->ServiceAnimations(kTimingUpdateOnDemand); - return scroll_timeline; -} - -CSSScrollTimeline* FindMatchingCachedTimeline( - Document& document, - const AtomicString& name, - const CSSScrollTimeline::Options& options) { - auto* cached_timeline = DynamicTo<CSSScrollTimeline>( - document.GetDocumentAnimations().FindCachedCSSScrollTimeline(name)); - if (cached_timeline && cached_timeline->Matches(options)) - return cached_timeline; - return nullptr; -} - AnimationTimeline* ComputeTimeline(Element* element, - const StyleNameOrKeyword& timeline_name, - StyleRuleScrollTimeline* rule, - AnimationTimeline* existing_timeline) { + const StyleNameOrKeyword& timeline_name) { Document& document = element->GetDocument(); if (timeline_name.IsKeyword()) { if (timeline_name.GetKeyword() == CSSValueID::kAuto) @@ -476,37 +450,7 @@ AnimationTimeline* ComputeTimeline(Element* element, DCHECK_EQ(timeline_name.GetKeyword(), CSSValueID::kNone); return nullptr; } - if (rule) { - CSSScrollTimeline::Options options(document, *rule); - - const AtomicString& name = timeline_name.GetName().GetValue(); - // When multiple animations refer to the same @scroll-timeline, the same - // CSSScrollTimeline instance should be shared. - if (auto* timeline = FindMatchingCachedTimeline(document, name, options)) - return timeline; - // When the incoming options match the existing timeline (associated with - // an existing animation), we can continue to use the existing timeline, - // since creating a new timeline from the options would just yield an - // identical timeline. - if (auto* timeline = DynamicTo<CSSScrollTimeline>(existing_timeline)) { - if (timeline->Matches(options)) - return existing_timeline; - } - if (auto* timeline = - CreateCSSScrollTimeline(document, std::move(options))) { - document.GetDocumentAnimations().CacheCSSScrollTimeline(*timeline); - return timeline; - } - } - return nullptr; -} - -StyleRuleScrollTimeline* FindScrollTimelineRule( - Document& document, - const StyleNameOrKeyword& timeline_name) { - if (timeline_name.IsKeyword()) - return nullptr; - return document.GetStyleEngine().FindScrollTimelineRule( + return document.GetStyleEngine().FindScrollTimeline( timeline_name.GetName().GetValue()); } @@ -708,9 +652,6 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, const StyleNameOrKeyword& timeline_name = animation_data->GetTimeline(i); - StyleRuleScrollTimeline* scroll_timeline_rule = - FindScrollTimelineRule(element.GetDocument(), timeline_name); - const RunningAnimation* existing_animation = nullptr; wtf_size_t existing_animation_index = 0; @@ -753,10 +694,8 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, toggle_pause_state ? animation->Paused() : animation->Playing(); AnimationTimeline* timeline = existing_animation->Timeline(); - if (!is_animation_style_change && !animation->GetIgnoreCSSTimeline()) { - timeline = ComputeTimeline(&element, timeline_name, - scroll_timeline_rule, timeline); - } + if (!is_animation_style_change && !animation->GetIgnoreCSSTimeline()) + timeline = ComputeTimeline(&element, timeline_name); if (keyframes_rule != existing_animation->style_rule || keyframes_rule->Version() != @@ -795,9 +734,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update, } } else { DCHECK(!is_animation_style_change); - AnimationTimeline* timeline = - ComputeTimeline(&element, timeline_name, scroll_timeline_rule, - nullptr /* existing_timeline */); + AnimationTimeline* timeline = ComputeTimeline(&element, timeline_name); absl::optional<TimelinePhase> inherited_phase; absl::optional<AnimationTimeDelta> inherited_time = AnimationTimeDelta(); @@ -891,15 +828,20 @@ void CSSAnimations::SnapshotCompositorKeyframes( } void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { - previous_active_interpolations_for_custom_animations_.clear(); - previous_active_interpolations_for_standard_animations_.clear(); + previous_active_interpolations_for_animations_.clear(); if (pending_update_.IsEmpty()) return; - previous_active_interpolations_for_custom_animations_.swap( - pending_update_.ActiveInterpolationsForCustomAnimations()); - previous_active_interpolations_for_standard_animations_.swap( - pending_update_.ActiveInterpolationsForStandardAnimations()); + previous_active_interpolations_for_animations_.swap( + pending_update_.ActiveInterpolationsForAnimations()); + + if (!pending_update_.HasUpdates()) { + ClearPendingUpdate(); + return; + } + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) + element->SetNeedsAnimationStyleRecalc(); for (wtf_size_t paused_index : pending_update_.AnimationIndicesWithPauseToggled()) { @@ -933,6 +875,14 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { } running_animations_[entry.index]->Update(entry); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // If the timing was updated, we need to update the animation to get the + // correct result the next time we resolve style. This is not needed + // if CSSIsolatedAnimationUpdates is disabled, since we're "faking" an + // updated animation with InertEffect. + entry.animation->Update(kTimingUpdateOnDemand); + } } const Vector<wtf_size_t>& cancelled_indices = @@ -1006,14 +956,37 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { } } + HashSet<PropertyHandle> suppressed_transitions; + if (!pending_update_.NewTransitions().IsEmpty()) { element->GetDocument() .GetDocumentAnimations() .IncrementTrasitionGeneration(); + + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // We generally do not start transitions if there's an animation + // running for the same property. This is mainly handled by + // CanCalculateTransitionUpdateForProperty. However, that function + // will not take into account newly started or newly updated animations, + // hence we need to check against an updated set of affected properties + // from the EffectStack whenever an animation is created/updated. + if (auto* element_animations = element->GetElementAnimations()) { + if (!pending_update_.NewAnimations().IsEmpty() || + !pending_update_.AnimationsWithUpdates().IsEmpty()) { + suppressed_transitions = + element_animations->GetEffectStack().AffectedProperties( + KeyframeEffect::kDefaultPriority); + } + } + } } for (const auto& entry : pending_update_.NewTransitions()) { const CSSAnimationUpdate::NewTransition* new_transition = entry.value; + const PropertyHandle& property = new_transition->property; + + if (suppressed_transitions.Contains(property)) + continue; RunningTransition* running_transition = MakeGarbageCollected<RunningTransition>(); @@ -1024,7 +997,6 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { running_transition->reversing_shortening_factor = new_transition->reversing_shortening_factor; - const PropertyHandle& property = new_transition->property; const InertEffect* inert_animation = new_transition->effect.Get(); TransitionEventDelegate* event_delegate = MakeGarbageCollected<TransitionEventDelegate>(element, property); @@ -1044,14 +1016,8 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { // Set the current time as the start time for retargeted transitions if (retargeted_compositor_transitions.Contains(property)) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(element->GetDocument().Timeline().currentTime(), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time; - element->GetDocument().Timeline().currentTime(current_time); - animation->setStartTime(current_time); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } animation->Update(kTimingUpdateOnDemand); running_transition->animation = animation; @@ -1060,34 +1026,30 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { ClearPendingUpdate(); } -void CSSAnimations::CalculateTransitionUpdateForProperty( +bool CSSAnimations::CanCalculateTransitionUpdateForProperty( + TransitionUpdateState& state, + const PropertyHandle& property) { + // TODO(crbug.com/1226772): We should transition if an !important property + // changes even when an animation is running. + if (state.update.ActiveInterpolationsForAnimations().Contains(property) || + (state.animating_element.GetElementAnimations() && + state.animating_element.GetElementAnimations() + ->CssAnimations() + .previous_active_interpolations_for_animations_.Contains( + property))) { + return false; + } + return true; +} + +void CSSAnimations::CalculateTransitionUpdateForPropertyHandle( TransitionUpdateState& state, const PropertyHandle& property, size_t transition_index) { state.listed_properties.insert(property); - // FIXME: We should transition if an !important property changes even when an - // animation is running, but this is a bit hard to do with the current - // applyMatchedProperties system. - if (property.IsCSSCustomProperty()) { - if (state.update.ActiveInterpolationsForCustomAnimations().Contains( - property) || - (state.animating_element.GetElementAnimations() && - state.animating_element.GetElementAnimations() - ->CssAnimations() - .previous_active_interpolations_for_custom_animations_.Contains( - property))) { - return; - } - } else if (state.update.ActiveInterpolationsForStandardAnimations().Contains( - property) || - (state.animating_element.GetElementAnimations() && - state.animating_element.GetElementAnimations() - ->CssAnimations() - .previous_active_interpolations_for_standard_animations_ - .Contains(property))) { + if (!CanCalculateTransitionUpdateForProperty(state, property)) return; - } const RunningTransition* interrupted_transition = nullptr; if (state.active_transitions) { @@ -1139,24 +1101,14 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( // Lazy evaluation of the before change style. We only need to update where // we are transitioning from if the final destination is changing. if (!state.before_change_style) { - ElementAnimations* element_animations = - state.animating_element.GetElementAnimations(); - if (element_animations) { - const ComputedStyle* base_style = element_animations->BaseComputedStyle(); - if (base_style) { - state.before_change_style = - CalculateBeforeChangeStyle(state.animating_element, *base_style); - } - } - // Use the style from the previous frame if no base style is found. - // Elements that have not been animated will not have a base style. - // Elements that were previously animated, but where all previously running - // animations have stopped may also be missing a base style. In both cases, - // the old style is equivalent to the base computed style. - if (!state.before_change_style) { - state.before_change_style = - CalculateBeforeChangeStyle(state.animating_element, state.old_style); - } + // By calling GetBaseComputedStyleOrThis, we're using the style from the + // previous frame if no base style is found. Elements that have not been + // animated will not have a base style. Elements that were previously + // animated, but where all previously running animations have stopped may + // also be missing a base style. In both cases, the old style is equivalent + // to the base computed style. + state.before_change_style = CalculateBeforeChangeStyle( + state.animating_element, *state.old_style.GetBaseComputedStyleOrThis()); } if (ComputedValuesEqual(property, *state.before_change_style, state.style)) { @@ -1271,19 +1223,37 @@ void CSSAnimations::CalculateTransitionUpdateForProperty( ->IsAnimationStyleChange()); } +void CSSAnimations::CalculateTransitionUpdateForProperty( + TransitionUpdateState& state, + const CSSTransitionData::TransitionProperty& transition_property, + size_t transition_index, + const ComputedStyle& style) { + switch (transition_property.property_type) { + case CSSTransitionData::kTransitionUnknownProperty: + CalculateTransitionUpdateForCustomProperty(state, transition_property, + transition_index); + break; + case CSSTransitionData::kTransitionKnownProperty: + CalculateTransitionUpdateForStandardProperty(state, transition_property, + transition_index, style); + break; + default: + break; + } +} + void CSSAnimations::CalculateTransitionUpdateForCustomProperty( TransitionUpdateState& state, const CSSTransitionData::TransitionProperty& transition_property, size_t transition_index) { - if (transition_property.property_type != - CSSTransitionData::kTransitionUnknownProperty) { - return; - } + DCHECK_EQ(transition_property.property_type, + CSSTransitionData::kTransitionUnknownProperty); + if (!CSSVariableParser::IsValidVariableName( transition_property.property_string)) { return; } - CalculateTransitionUpdateForProperty( + CalculateTransitionUpdateForPropertyHandle( state, PropertyHandle(transition_property.property_string), transition_index); } @@ -1293,10 +1263,8 @@ void CSSAnimations::CalculateTransitionUpdateForStandardProperty( const CSSTransitionData::TransitionProperty& transition_property, size_t transition_index, const ComputedStyle& style) { - if (transition_property.property_type != - CSSTransitionData::kTransitionKnownProperty) { - return; - } + DCHECK_EQ(transition_property.property_type, + CSSTransitionData::kTransitionKnownProperty); CSSPropertyID resolved_id = ResolveCSSPropertyID(transition_property.unresolved_property); @@ -1321,13 +1289,12 @@ void CSSAnimations::CalculateTransitionUpdateForStandardProperty( continue; } - CalculateTransitionUpdateForProperty(state, property_handle, - transition_index); + CalculateTransitionUpdateForPropertyHandle(state, property_handle, + transition_index); } } void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, - PropertyPass property_pass, Element& animating_element, const ComputedStyle& style) { if (animating_element.GetDocument().FinishingOrIsPrinting()) @@ -1367,34 +1334,21 @@ void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, if (transition_property.unresolved_property == CSSPropertyID::kAll) { any_transition_had_transition_all = true; } - if (property_pass == PropertyPass::kCustom) { - CalculateTransitionUpdateForCustomProperty(state, transition_property, - transition_index); - } else { - DCHECK_EQ(property_pass, PropertyPass::kStandard); - CalculateTransitionUpdateForStandardProperty( - state, transition_property, transition_index, style); - } + CalculateTransitionUpdateForProperty(state, transition_property, + transition_index, style); } } else if (active_transitions && active_transitions->size()) { // !transition_data implies transition: all 0s any_transition_had_transition_all = true; - if (property_pass == PropertyPass::kStandard) { CSSTransitionData::TransitionProperty default_property( CSSPropertyID::kAll); - CalculateTransitionUpdateForStandardProperty(state, default_property, 0, - style); - } + CalculateTransitionUpdateForProperty(state, default_property, 0, style); } } if (active_transitions) { for (const auto& entry : *active_transitions) { const PropertyHandle& property = entry.key; - if (property.IsCSSCustomProperty() != - (property_pass == PropertyPass::kCustom)) { - continue; - } if (!any_transition_had_transition_all && !animation_style_recalc && !listed_properties.Contains(property)) { update.CancelTransition(property); @@ -1404,8 +1358,7 @@ void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update, } } - CalculateTransitionActiveInterpolations(update, property_pass, - animating_element); + CalculateTransitionActiveInterpolations(update, animating_element); } scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( @@ -1435,32 +1388,16 @@ scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle( // Sample animations and add to the interpolatzions map. for (Animation* animation : animations) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* current_time_numberish = animation->currentTime(); if (!current_time_numberish) continue; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time_numberish; - animation->currentTime(current_time_numberish); - if (current_time_numberish.IsNull()) - continue; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // CSSNumericValue is not yet supported, verify that it is not used -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) DCHECK(!current_time_numberish->IsCSSNumericValue()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - DCHECK(!current_time_numberish.IsCSSNumericValue()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) absl::optional<AnimationTimeDelta> current_time = AnimationTimeDelta::FromMillisecondsD( -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - current_time_numberish->GetAsDouble() -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - current_time_numberish.GetAsDouble() -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - ); + current_time_numberish->GetAsDouble()); auto* effect = DynamicTo<KeyframeEffect>(animation->effect()); if (!effect) @@ -1526,9 +1463,8 @@ bool IsFontAffectingPropertyHandle(const PropertyHandle& property) { // the case of effect collisions. // Example: Both 'color' and 'svg-color' set the color on ComputedStyle but are // considered distinct properties in the ActiveInterpolationsMap. -bool IsStandardPropertyHandle(const PropertyHandle& property) { - return (property.IsCSSProperty() && !property.IsCSSCustomProperty()) || - property.IsPresentationAttribute(); +bool IsCSSPropertyHandle(const PropertyHandle& property) { + return property.IsCSSProperty() || property.IsPresentationAttribute(); } void AdoptActiveAnimationInterpolations( @@ -1536,18 +1472,19 @@ void AdoptActiveAnimationInterpolations( CSSAnimationUpdate& update, const HeapVector<Member<const InertEffect>>* new_animations, const HeapHashSet<Member<const Animation>>* suppressed_animations) { - ActiveInterpolationsMap custom_interpolations( - EffectStack::ActiveInterpolations( - effect_stack, new_animations, suppressed_animations, - KeyframeEffect::kDefaultPriority, IsCustomPropertyHandle)); - update.AdoptActiveInterpolationsForCustomAnimations(custom_interpolations); - - ActiveInterpolationsMap standard_interpolations( - EffectStack::ActiveInterpolations( - effect_stack, new_animations, suppressed_animations, - KeyframeEffect::kDefaultPriority, IsStandardPropertyHandle)); - update.AdoptActiveInterpolationsForStandardAnimations( - standard_interpolations); + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // The new/suppressed animations options are not used by + // CSSIsolatedAnimationUpdates. Eventually we want to avoid setting + // that up in the first place, but while this is behind a flag, the least + // intrusive approach is to just nullify here. + new_animations = nullptr; + suppressed_animations = nullptr; + } + + ActiveInterpolationsMap interpolations(EffectStack::ActiveInterpolations( + effect_stack, new_animations, suppressed_animations, + KeyframeEffect::kDefaultPriority, IsCSSPropertyHandle)); + update.AdoptActiveInterpolationsForAnimations(interpolations); } } // namespace @@ -1578,22 +1515,8 @@ void CSSAnimations::CalculateAnimationActiveInterpolations( &update.SuppressedAnimations()); } -namespace { - -EffectStack::PropertyHandleFilter PropertyFilter( - CSSAnimations::PropertyPass property_pass) { - if (property_pass == CSSAnimations::PropertyPass::kCustom) { - return IsCustomPropertyHandle; - } - DCHECK_EQ(property_pass, CSSAnimations::PropertyPass::kStandard); - return IsStandardPropertyHandle; -} - -} // namespace - void CSSAnimations::CalculateTransitionActiveInterpolations( CSSAnimationUpdate& update, - PropertyPass property_pass, const Element& animating_element) { ElementAnimations* element_animations = animating_element.GetElementAnimations(); @@ -1605,7 +1528,7 @@ void CSSAnimations::CalculateTransitionActiveInterpolations( update.CancelledTransitions().IsEmpty()) { active_interpolations_for_transitions = EffectStack::ActiveInterpolations( effect_stack, nullptr, nullptr, KeyframeEffect::kTransitionPriority, - PropertyFilter(property_pass)); + IsCSSPropertyHandle); } else { HeapVector<Member<const InertEffect>> new_transitions; for (const auto& entry : update.NewTransitions()) @@ -1623,15 +1546,20 @@ void CSSAnimations::CalculateTransitionActiveInterpolations( } } + if (RuntimeEnabledFeatures::CSSIsolatedAnimationUpdatesEnabled()) { + // Eventually we should avoid building these in the first place, + // but for now it's less intrusive to clear them after-the-fact. + new_transitions.clear(); + cancelled_animations.clear(); + } + active_interpolations_for_transitions = EffectStack::ActiveInterpolations( effect_stack, &new_transitions, &cancelled_animations, - KeyframeEffect::kTransitionPriority, PropertyFilter(property_pass)); + KeyframeEffect::kTransitionPriority, IsCSSPropertyHandle); } const ActiveInterpolationsMap& animations = - property_pass == PropertyPass::kCustom - ? update.ActiveInterpolationsForCustomAnimations() - : update.ActiveInterpolationsForStandardAnimations(); + update.ActiveInterpolationsForAnimations(); // Properties being animated by animations don't get values from transitions // applied. if (!animations.IsEmpty() && @@ -1640,14 +1568,8 @@ void CSSAnimations::CalculateTransitionActiveInterpolations( active_interpolations_for_transitions.erase(entry.key); } - if (property_pass == PropertyPass::kCustom) { - update.AdoptActiveInterpolationsForCustomTransitions( - active_interpolations_for_transitions); - } else { - DCHECK_EQ(property_pass, PropertyPass::kStandard); - update.AdoptActiveInterpolationsForStandardTransitions( - active_interpolations_for_transitions); - } + update.AdoptActiveInterpolationsForTransitions( + active_interpolations_for_transitions); } EventTarget* CSSAnimations::AnimationEventDelegate::GetEventTarget() const { @@ -1764,7 +1686,7 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( if (previous_phase_ == Timing::kPhaseNone) { EnqueueEvent( event_type_names::kTransitionrun, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } } @@ -1775,14 +1697,14 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( previous_phase_ == Timing::kPhaseBefore)) { EnqueueEvent( event_type_names::kTransitionstart, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } else if ((current_phase == Timing::kPhaseActive || current_phase == Timing::kPhaseBefore) && previous_phase_ == Timing::kPhaseAfter) { // If the transition is progressing backwards it is considered to have // started at the end position. EnqueueEvent(event_type_names::kTransitionstart, - animation_node.SpecifiedTiming().IterationDuration()); + animation_node.NormalizedTiming().iteration_duration); } } @@ -1792,7 +1714,7 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( previous_phase_ == Timing::kPhaseBefore || previous_phase_ == Timing::kPhaseNone)) { EnqueueEvent(event_type_names::kTransitionend, - animation_node.SpecifiedTiming().IterationDuration()); + animation_node.NormalizedTiming().iteration_duration); } else if (current_phase == Timing::kPhaseBefore && (previous_phase_ == Timing::kPhaseActive || previous_phase_ == Timing::kPhaseAfter)) { @@ -1800,7 +1722,7 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( // ended at the start position. EnqueueEvent( event_type_names::kTransitionend, - StartTimeFromDelay(animation_node.SpecifiedTiming().start_delay)); + StartTimeFromDelay(animation_node.NormalizedTiming().start_delay)); } } @@ -1811,10 +1733,9 @@ void CSSAnimations::TransitionEventDelegate::OnEventCondition( // "active time of the animation at the moment it was cancelled, // calculated using a fill mode of both". absl::optional<AnimationTimeDelta> cancel_active_time = - CalculateActiveTime(animation_node.SpecifiedTiming().ActiveDuration(), + CalculateActiveTime(animation_node.NormalizedTiming(), Timing::FillMode::BOTH, - animation_node.LocalTime(), previous_phase_, - animation_node.SpecifiedTiming()); + animation_node.LocalTime(), previous_phase_); // Being the FillMode::BOTH the only possibility to get a null // cancel_active_time is that previous_phase_ is kPhaseNone. This cannot // happen because we know that current_phase == kPhaseNone and @@ -1953,8 +1874,7 @@ void CSSAnimations::Trace(Visitor* visitor) const { visitor->Trace(transitions_); visitor->Trace(pending_update_); visitor->Trace(running_animations_); - visitor->Trace(previous_active_interpolations_for_standard_animations_); - visitor->Trace(previous_active_interpolations_for_custom_animations_); + visitor->Trace(previous_active_interpolations_for_animations_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h index cf367221edc..ccc8b993dde 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations.h @@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATIONS_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/css/css_animation_data.h" #include "third_party/blink/renderer/core/animation/css/css_animation_update.h" #include "third_party/blink/renderer/core/animation/css/css_transition_data.h" @@ -57,6 +56,8 @@ class CORE_EXPORT CSSAnimations final { public: CSSAnimations(); + CSSAnimations(const CSSAnimations&) = delete; + CSSAnimations& operator=(const CSSAnimations&) = delete; static const StylePropertyShorthand& PropertiesForTransitionAll(); static bool IsAnimationAffectingProperty(const CSSProperty&); @@ -91,10 +92,7 @@ class CORE_EXPORT CSSAnimations final { const AtomicString& animation_name, const AnimationEffect::EventDelegate* old_event_delegate); - // Specifies whether to process custom or standard CSS properties. - enum class PropertyPass { kCustom, kStandard }; static void CalculateTransitionUpdate(CSSAnimationUpdate&, - PropertyPass, Element& animating_element, const ComputedStyle&); @@ -173,9 +171,7 @@ class CORE_EXPORT CSSAnimations final { CSSAnimationUpdate pending_update_; - ActiveInterpolationsMap previous_active_interpolations_for_custom_animations_; - ActiveInterpolationsMap - previous_active_interpolations_for_standard_animations_; + ActiveInterpolationsMap previous_active_interpolations_for_animations_; struct TransitionUpdateState { STACK_ALLOCATED(); @@ -192,6 +188,12 @@ class CORE_EXPORT CSSAnimations final { const CSSTransitionData* transition_data; }; + static void CalculateTransitionUpdateForProperty( + TransitionUpdateState&, + const CSSTransitionData::TransitionProperty&, + size_t transition_index, + const ComputedStyle&); + static void CalculateTransitionUpdateForCustomProperty( TransitionUpdateState&, const CSSTransitionData::TransitionProperty&, @@ -203,16 +205,20 @@ class CORE_EXPORT CSSAnimations final { size_t transition_index, const ComputedStyle&); - static void CalculateTransitionUpdateForProperty(TransitionUpdateState&, - const PropertyHandle&, - size_t transition_index); + static bool CanCalculateTransitionUpdateForProperty( + TransitionUpdateState& state, + const PropertyHandle& property); + + static void CalculateTransitionUpdateForPropertyHandle( + TransitionUpdateState&, + const PropertyHandle&, + size_t transition_index); static void CalculateAnimationActiveInterpolations( CSSAnimationUpdate&, const Element& animating_element); static void CalculateTransitionActiveInterpolations( CSSAnimationUpdate&, - PropertyPass, const Element& animating_element); // The before-change style is defined as the computed values of all properties @@ -289,8 +295,6 @@ class CORE_EXPORT CSSAnimations final { PropertyHandle property_; Timing::Phase previous_phase_; }; - - DISALLOW_COPY_AND_ASSIGN(CSSAnimations); }; template <> diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc index 1e2f5ab8eb8..cd3c10158db 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc @@ -350,37 +350,20 @@ TEST_F(CSSAnimationsCompositorSyncTest, SetStartTime) { Animation* animation = GetAnimation(); int compositor_group = animation->CompositorGroup(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* start_time = animation->startTime(); V8CSSNumberish* current_time = animation->currentTime(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish start_time, current_time; - animation->startTime(start_time); - animation->currentTime(current_time); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Partially rewind the animation via setStartTime. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* new_start_time = MakeGarbageCollected<V8CSSNumberish>( start_time->GetAsDouble() + (current_time->GetAsDouble() / 2)); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish new_start_time = CSSNumberish::FromDouble( - start_time.GetAsDouble() + (current_time.GetAsDouble() / 2)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(new_start_time, ASSERT_NO_EXCEPTION); UpdateAllLifecyclePhasesForTest(); // Verify blink updates. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) current_time = animation->currentTime(); EXPECT_TRUE(current_time->IsDouble()); EXPECT_NEAR(250, current_time->GetAsDouble(), kTimeToleranceMilliseconds); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->currentTime(current_time); - EXPECT_TRUE(current_time.IsDouble()); - EXPECT_NEAR(250, current_time.GetAsDouble(), kTimeToleranceMilliseconds); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_NEAR(0.75, element_->GetComputedStyle()->Opacity(), kTolerance); // Compositor animation needs to restart and will have a new compositor group. @@ -411,25 +394,14 @@ TEST_F(CSSAnimationsCompositorSyncTest, SetCurrentTime) { int compositor_group = animation->CompositorGroup(); // Advance current time. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(750), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(750), ASSERT_NO_EXCEPTION); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) UpdateAllLifecyclePhasesForTest(); // Verify blink updates. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* current_time = animation->currentTime(); EXPECT_TRUE(current_time->IsDouble()); EXPECT_NEAR(750, current_time->GetAsDouble(), kTimeToleranceMilliseconds); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time; - animation->currentTime(current_time); - EXPECT_TRUE(current_time.IsDouble()); - EXPECT_NEAR(750, current_time.GetAsDouble(), kTimeToleranceMilliseconds); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_NEAR(0.25, element_->GetComputedStyle()->Opacity(), kTolerance); // Compositor animation needs to restart and will have a new compositor group. diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.cc b/chromium/third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.cc index 5729b43432a..8bc0e717866 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.cc @@ -78,16 +78,11 @@ void ResolveComputedValues(Element* element, StringKeyframe* keyframe) { keyframe->RemoveCustomCSSProperty(property); } else if (property.IsCSSProperty()) { const CSSValue& value = keyframe->CssPropertyValue(property); - const CSSPropertyName property_name = - property.IsCSSCustomProperty() - ? CSSPropertyName(property.CustomPropertyName()) - : CSSPropertyName(property.GetCSSProperty().PropertyID()); + const CSSPropertyName property_name = property.GetCSSPropertyName(); const CSSValue* computed_value = StyleResolver::ComputeValue(element, property_name, value); - if (computed_value) { - keyframe->SetCSSPropertyValue(property.GetCSSProperty(), - *computed_value); - } + if (computed_value) + keyframe->SetCSSPropertyValue(property_name, *computed_value); } } } diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc index 854e05f9707..6f0d6cc1ce1 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/css/css_id_selector_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" +#include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/css/style_rule.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -49,14 +50,15 @@ const cssvalue::CSSIdSelectorValue* GetIdSelectorValue(const CSSValue* value) { return nullptr; } -Element* ComputeScrollSource(Document& document, const CSSValue* value) { +absl::optional<Element*> ComputeScrollSource(Document& document, + const CSSValue* value) { if (const auto* id = GetIdSelectorValue(value)) return document.getElementById(id->Id()); if (IsNone(value)) return nullptr; DCHECK(!value || IsAuto(value)); // TODO(crbug.com/1189101): Respond when the scrolling element changes. - return document.ScrollingElementNoLayout(); + return absl::nullopt; } Element* ComputeElementOffsetTarget(Document& document, const CSSValue* value) { @@ -157,18 +159,21 @@ class ElementReferenceObserver : public IdTargetObserver { const AtomicString& id, CSSScrollTimeline* timeline) : IdTargetObserver(document->GetIdTargetObserverRegistry(), id), + document_(document), timeline_(timeline) {} void Trace(Visitor* visitor) const override { visitor->Trace(timeline_); + visitor->Trace(document_); IdTargetObserver::Trace(visitor); } private: void IdTargetChanged() override { if (timeline_) - timeline_->InvalidateEffectTargetStyle(); + document_->GetStyleEngine().ScrollTimelineInvalidated(*timeline_); } + Member<Document> document_; WeakMember<CSSScrollTimeline> timeline_; }; @@ -217,9 +222,8 @@ CSSScrollTimeline::CSSScrollTimeline(Document* document, Options&& options) options.source_, options.direction_, std::move(options.offsets_), - *options.time_range_), + options.time_range_), rule_(options.rule_) { - DCHECK(options.IsValid()); DCHECK(rule_); } diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h index 013b7f5cc43..b946ac3b870 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h @@ -25,13 +25,10 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { public: Options(Document&, StyleRuleScrollTimeline&); - // TODO(crbug.com/1097041): Support 'auto' value. - bool IsValid() const { return time_range_.has_value(); } - private: friend class CSSScrollTimeline; - Element* source_; + absl::optional<Element*> source_; ScrollTimeline::ScrollDirection direction_; HeapVector<Member<ScrollTimelineOffset>> offsets_; absl::optional<double> time_range_; @@ -42,6 +39,8 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { const AtomicString& Name() const; + StyleRuleScrollTimeline* GetRule() const { return rule_; } + bool Matches(const Options&) const; // AnimationTimeline implementation. diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc index 8de8d872b2c..3b3c46ed417 100644 --- a/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc @@ -32,6 +32,12 @@ class CSSScrollTimelineTest : public PageTestBase, DocumentAnimations& GetDocumentAnimations() const { return GetDocument().GetDocumentAnimations(); } + + void SimulateFrame() { + auto new_time = GetAnimationClock().CurrentTime() + + base::TimeDelta::FromMilliseconds(100); + GetPage().Animator().ServiceScriptedAnimations(new_time); + } }; TEST_F(CSSScrollTimelineTest, IdObserverElementRemoval) { @@ -64,11 +70,13 @@ TEST_F(CSSScrollTimelineTest, IdObserverElementRemoval) { ASSERT_TRUE(element2); element1->remove(); + SimulateFrame(); UpdateAllLifecyclePhasesForTest(); ThreadState::Current()->CollectAllGarbageForTesting(); EXPECT_TRUE(HasObservers("scroller")); element2->remove(); + SimulateFrame(); UpdateAllLifecyclePhasesForTest(); ThreadState::Current()->CollectAllGarbageForTesting(); EXPECT_FALSE(HasObservers("scroller")); @@ -282,20 +290,26 @@ namespace { class AnimationTriggeringDelegate : public ResizeObserver::Delegate { public: - explicit AnimationTriggeringDelegate(Element* element) : element_(element) {} + explicit AnimationTriggeringDelegate(Element* style_element) + : style_element_(style_element) {} void OnResize( const HeapVector<Member<ResizeObserverEntry>>& entries) override { - element_->setAttribute(blink::html_names::kClassAttr, "animate"); + style_element_->setTextContent(R"CSS( + @scroll-timeline timeline { + source: selector(#scroller); + time-range: 10s; + } + )CSS"); } void Trace(Visitor* visitor) const override { ResizeObserver::Delegate::Trace(visitor); - visitor->Trace(element_); + visitor->Trace(style_element_); } private: - Member<Element> element_; + Member<Element> style_element_; }; } // namespace @@ -307,10 +321,6 @@ TEST_F(CSSScrollTimelineTest, ResizeObserverTriggeredTimelines) { from { width: 100px; } to { width: 100px; } } - @scroll-timeline timeline { - source: selector(#scroller); - time-range: 10s; - } #scroller { height: 100px; overflow: scroll; @@ -320,8 +330,6 @@ TEST_F(CSSScrollTimelineTest, ResizeObserverTriggeredTimelines) { } #element { width: 1px; - } - #element.animate { animation: anim 10s timeline; } </style> @@ -338,12 +346,16 @@ TEST_F(CSSScrollTimelineTest, ResizeObserverTriggeredTimelines) { scroller->setAttribute(blink::html_names::kIdAttr, "scroller"); scroller->AppendChild(MakeGarbageCollected<HTMLDivElement>(GetDocument())); + Element* style = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), + CreateElementFlags()); + Element* main = GetDocument().getElementById("main"); ASSERT_TRUE(main); + main->AppendChild(style); main->AppendChild(element); main->AppendChild(scroller); - auto* delegate = MakeGarbageCollected<AnimationTriggeringDelegate>(element); + auto* delegate = MakeGarbageCollected<AnimationTriggeringDelegate>(style); ResizeObserver* observer = ResizeObserver::Create(GetDocument().domWindow(), delegate); observer->observe(element); diff --git a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc index ff399b71577..5112f4fdd2c 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc @@ -99,6 +99,7 @@ CSSColorInterpolationType::MaybeCreateInterpolableColor(const CSSValue& value) { return CreateInterpolableColor(identifier_value->GetValueID()); } +// Spec link: https://www.w3.org/TR/css-color-4/#interpolation-alpha Color CSSColorInterpolationType::GetRGBA(const InterpolableValue& value) { const InterpolableList& list = To<InterpolableList>(value); DCHECK_GE(list.length(), kAlpha); @@ -107,6 +108,9 @@ Color CSSColorInterpolationType::GetRGBA(const InterpolableValue& value) { const InterpolableValue& current_value = *(list.Get(i)); color[i] = To<InterpolableNumber>(current_value).Value(); } + // Prevent dividing 0 + if (color[kAlpha] == 0) + return Color::kTransparent; return Color(MakeRGBA(std::round(color[kRed] / color[kAlpha]), std::round(color[kGreen] / color[kAlpha]), std::round(color[kBlue] / color[kAlpha]), diff --git a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc index 3cc0c4ee5f2..03540ef2d51 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc @@ -29,4 +29,10 @@ TEST(CSSColorInterpolationTypeTest, GetRGBA3) { *CSSColorInterpolationType::CreateInterpolableColor(color))); } +TEST(CSSColorInterpolationTypeTest, GetRGBA4) { + Color color(35, 140, 10, 0); + EXPECT_EQ(Color(MakeRGBA(0, 0, 0, 0)), + CSSColorInterpolationType::GetRGBA( + *CSSColorInterpolationType::CreateInterpolableColor(color))); +} } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc index bfe74bd5d21..aa886124e9b 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc @@ -15,7 +15,7 @@ namespace blink { InterpolationValue CSSCustomListInterpolationType::MaybeConvertNeutral( const InterpolationValue& underlying, ConversionCheckers& conversion_checkers) const { - size_t underlying_length = + wtf_size_t underlying_length = UnderlyingLengthChecker::GetUnderlyingLength(underlying); conversion_checkers.push_back( std::make_unique<UnderlyingLengthChecker>(underlying_length)); @@ -46,7 +46,7 @@ InterpolationValue CSSCustomListInterpolationType::MaybeConvertValue( ConversionCheckers null_checkers; return ListInterpolationFunctions::CreateList( - list->length(), [this, list, state, &null_checkers](size_t index) { + list->length(), [this, list, state, &null_checkers](wtf_size_t index) { return inner_interpolation_type_->MaybeConvertValue( list->Item(index), state, null_checkers); }); @@ -77,7 +77,7 @@ const CSSValue* CSSCustomListInterpolationType::CreateCSSValue( DCHECK(!non_interpolable_list || interpolable_list.length() == non_interpolable_list->length()); - for (size_t i = 0; i < interpolable_list.length(); ++i) { + for (wtf_size_t i = 0; i < interpolable_list.length(); ++i) { const NonInterpolableValue* non_interpolable_single_value = non_interpolable_list ? non_interpolable_list->Get(i) : nullptr; list->Append(*inner_interpolation_type_->CreateCSSValue( diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc index 1d47beba58d..805d46ffbe6 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc @@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/animation/interpolable_length.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_pending_system_font_value.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" @@ -108,18 +109,22 @@ InterpolationValue CSSFontSizeInterpolationType::MaybeConvertValue( const CSSValue& value, const StyleResolverState* state, ConversionCheckers& conversion_checkers) const { + DCHECK(state); + std::unique_ptr<InterpolableValue> result = InterpolableLength::MaybeConvertCSSValue(value); if (result) return InterpolationValue(std::move(result)); - auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); - if (!identifier_value) - return nullptr; + if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { + return MaybeConvertKeyword(identifier_value->GetValueID(), *state, + conversion_checkers); + } - DCHECK(state); - return MaybeConvertKeyword(identifier_value->GetValueID(), *state, - conversion_checkers); + if (auto* system_font = DynamicTo<cssvalue::CSSPendingSystemFontValue>(value)) + return ConvertFontSize(system_font->ResolveFontSize(&state->GetDocument())); + + return nullptr; } InterpolationValue diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc index 3dc54b266e6..a9c686f621f 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc @@ -8,7 +8,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" -#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" +#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -62,39 +62,8 @@ InterpolationValue CSSFontStretchInterpolationType::MaybeConvertValue( const CSSValue& value, const StyleResolverState* state, ConversionCheckers& conversion_checkers) const { - if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) { - return CreateFontStretchValue( - FontSelectionValue(primitive_value->GetFloatValue())); - } - - const auto& identifier_value = To<CSSIdentifierValue>(value); - CSSValueID keyword = identifier_value.GetValueID(); - - switch (keyword) { - case CSSValueID::kInvalid: - return nullptr; - case CSSValueID::kUltraCondensed: - return CreateFontStretchValue(UltraCondensedWidthValue()); - case CSSValueID::kExtraCondensed: - return CreateFontStretchValue(ExtraCondensedWidthValue()); - case CSSValueID::kCondensed: - return CreateFontStretchValue(CondensedWidthValue()); - case CSSValueID::kSemiCondensed: - return CreateFontStretchValue(SemiCondensedWidthValue()); - case CSSValueID::kNormal: - return CreateFontStretchValue(NormalWidthValue()); - case CSSValueID::kSemiExpanded: - return CreateFontStretchValue(SemiExpandedWidthValue()); - case CSSValueID::kExpanded: - return CreateFontStretchValue(ExpandedWidthValue()); - case CSSValueID::kExtraExpanded: - return CreateFontStretchValue(ExtraExpandedWidthValue()); - case CSSValueID::kUltraExpanded: - return CreateFontStretchValue(UltraExpandedWidthValue()); - default: - NOTREACHED(); - return nullptr; - } + return CreateFontStretchValue( + StyleBuilderConverterBase::ConvertFontStretch(value)); } InterpolationValue diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc index 9870c5ec5db..0fd1672cb72 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc @@ -8,7 +8,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" -#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" +#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -62,40 +62,18 @@ InterpolationValue CSSFontWeightInterpolationType::MaybeConvertValue( const CSSValue& value, const StyleResolverState* state, ConversionCheckers& conversion_checkers) const { - if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) { - return CreateFontWeightValue( - FontSelectionValue(primitive_value->GetFloatValue())); - } - - const auto& identifier_value = To<CSSIdentifierValue>(value); - CSSValueID keyword = identifier_value.GetValueID(); - - switch (keyword) { - case CSSValueID::kInvalid: - return nullptr; - case CSSValueID::kNormal: - return CreateFontWeightValue(NormalWeightValue()); - case CSSValueID::kBold: - return CreateFontWeightValue(BoldWeightValue()); - - case CSSValueID::kBolder: - case CSSValueID::kLighter: { - DCHECK(state); - FontSelectionValue inherited_font_weight = - state->ParentStyle()->GetFontWeight(); + DCHECK(state); + FontSelectionValue inherited_font_weight = + state->ParentStyle()->GetFontWeight(); + if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { + CSSValueID keyword = identifier_value->GetValueID(); + if (keyword == CSSValueID::kBolder || keyword == CSSValueID::kLighter) { conversion_checkers.push_back( std::make_unique<InheritedFontWeightChecker>(inherited_font_weight)); - if (keyword == CSSValueID::kBolder) { - return CreateFontWeightValue( - FontDescription::BolderWeight(inherited_font_weight)); - } - return CreateFontWeightValue( - FontDescription::LighterWeight(inherited_font_weight)); } - default: - NOTREACHED(); - return nullptr; } + return CreateFontWeightValue(StyleBuilderConverterBase::ConvertFontWeight( + value, inherited_font_weight)); } InterpolationValue diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc index 9281ca47be8..5af9aada6ec 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc @@ -79,7 +79,7 @@ class InheritedCustomPropertyChecker return DataEquivalent(inherited_value_.Get(), inherited_value); } - const AtomicString& name_; + AtomicString name_; const bool is_inherited_property_; Persistent<const CSSValue> inherited_value_; Persistent<const CSSValue> initial_value_; @@ -89,17 +89,18 @@ class ResolvedRegisteredCustomPropertyChecker : public InterpolationType::ConversionChecker { public: ResolvedRegisteredCustomPropertyChecker( - const CSSCustomPropertyDeclaration& declaration, + const PropertyHandle& property, + const CSSValue& value, scoped_refptr<CSSVariableData> resolved_tokens) - : declaration_(declaration), + : property_(property), + value_(value), resolved_tokens_(std::move(resolved_tokens)) {} private: bool IsValid(const InterpolationEnvironment& environment, const InterpolationValue&) const final { const auto& css_environment = To<CSSInterpolationEnvironment>(environment); - const CSSValue* resolved = css_environment.Resolve( - PropertyHandle(declaration_->GetName()), declaration_); + const CSSValue* resolved = css_environment.Resolve(property_, value_); scoped_refptr<CSSVariableData> resolved_tokens; if (const auto* decl = DynamicTo<CSSCustomPropertyDeclaration>(resolved)) resolved_tokens = decl->Value(); @@ -107,7 +108,8 @@ class ResolvedRegisteredCustomPropertyChecker return DataEquivalent(resolved_tokens, resolved_tokens_); } - Persistent<const CSSCustomPropertyDeclaration> declaration_; + PropertyHandle property_; + Persistent<const CSSValue> value_; scoped_refptr<CSSVariableData> resolved_tokens_; }; @@ -210,8 +212,7 @@ InterpolationValue CSSInterpolationType::MaybeConvertCustomPropertyDeclaration( const auto& css_environment = To<CSSInterpolationEnvironment>(environment); const StyleResolverState& state = css_environment.GetState(); - const AtomicString& name = declaration.GetName(); - DCHECK_EQ(GetProperty().CustomPropertyName(), name); + AtomicString name = GetProperty().CustomPropertyName(); const CSSValue* value = &declaration; value = css_environment.Resolve(GetProperty(), value); @@ -228,7 +229,7 @@ InterpolationValue CSSInterpolationType::MaybeConvertCustomPropertyDeclaration( if (resolved_declaration != &declaration) { conversion_checkers.push_back( std::make_unique<ResolvedRegisteredCustomPropertyChecker>( - declaration, resolved_declaration->Value())); + GetProperty(), declaration, resolved_declaration->Value())); } } @@ -333,7 +334,7 @@ void CSSInterpolationType::ApplyCustomPropertyValue( // TODO(andruud): Avoid making the CSSCustomPropertyDeclaration by allowing // any CSSValue in CustomProperty::ApplyValue. const CSSValue* value = MakeGarbageCollected<CSSCustomPropertyDeclaration>( - property.CustomPropertyName(), std::move(variable_data)); + std::move(variable_data)); StyleBuilder::ApplyProperty(GetProperty().GetCSSPropertyName(), state, ScopedCSSValue(*value, nullptr)); } diff --git a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc index d38c2150c27..8e9a29f6bc5 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc @@ -42,8 +42,7 @@ const CSSValue* CSSNumberInterpolationType::CreateCSSValue( const StyleResolverState&) const { double number = To<InterpolableNumber>(value).Value(); return CSSNumericLiteralValue::Create( - round_to_integer_ ? round(number) : number, - CSSPrimitiveValue::UnitType::kNumber); + round_to_integer_ ? round(number) : number, UnitType()); } InterpolationValue CSSNumberInterpolationType::CreateNumberValue( @@ -111,12 +110,10 @@ void CSSNumberInterpolationType::ApplyStandardPropertyValue( CssProperty(), To<InterpolableNumber>(interpolable_value).Value()); if (!NumberPropertyFunctions::SetNumber(CssProperty(), *state.Style(), clamped_number)) { - StyleBuilder::ApplyProperty( - GetProperty().GetCSSProperty(), state, - ScopedCSSValue( - *CSSNumericLiteralValue::Create( - clamped_number, CSSPrimitiveValue::UnitType::kNumber), - nullptr)); + StyleBuilder::ApplyProperty(GetProperty().GetCSSProperty(), state, + ScopedCSSValue(*CSSNumericLiteralValue::Create( + clamped_number, UnitType()), + nullptr)); } } diff --git a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.h index fbdd09a8c4b..128637e9b5e 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.h +++ b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.h @@ -43,6 +43,11 @@ class CORE_EXPORT CSSNumberInterpolationType : public CSSInterpolationType { const StyleResolverState*, ConversionCheckers&) const final; + CSSPrimitiveValue::UnitType UnitType() const { + return round_to_integer_ ? CSSPrimitiveValue::UnitType::kInteger + : CSSPrimitiveValue::UnitType::kNumber; + } + const bool round_to_integer_; }; diff --git a/chromium/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc index 6dc26c3fa20..9c763e03db6 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc @@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/animation/interpolable_transform_list.h" #include "third_party/blink/renderer/core/animation/length_units_checker.h" #include "third_party/blink/renderer/core/css/css_function_value.h" @@ -24,7 +23,7 @@ namespace blink { namespace { InterpolationValue ConvertTransform(TransformOperations&& transform) { return InterpolationValue( - InterpolableTransformList::Create(std::move(transform))); + std::make_unique<InterpolableTransformList>(std::move(transform))); } InterpolationValue ConvertTransform(const TransformOperations& transform) { diff --git a/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc index 226e20ff0e8..90b0708a8b0 100644 --- a/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc +++ b/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc @@ -21,20 +21,21 @@ namespace blink { class CycleChecker : public InterpolationType::ConversionChecker { public: - CycleChecker(const CSSCustomPropertyDeclaration& declaration, + CycleChecker(const PropertyHandle& property, + const CSSValue& value, bool cycle_detected) - : declaration_(declaration), cycle_detected_(cycle_detected) {} + : property_(property), value_(value), cycle_detected_(cycle_detected) {} private: bool IsValid(const InterpolationEnvironment& environment, const InterpolationValue&) const final { const auto& css_environment = To<CSSInterpolationEnvironment>(environment); - bool cycle_detected = !css_environment.Resolve( - PropertyHandle(declaration_->GetName()), declaration_); + bool cycle_detected = !css_environment.Resolve(property_, value_); return cycle_detected == cycle_detected_; } - Persistent<const CSSCustomPropertyDeclaration> declaration_; + PropertyHandle property_; + Persistent<const CSSValue> value_; const bool cycle_detected_; }; @@ -56,7 +57,6 @@ InterpolationValue CSSVarCycleInterpolationType::MaybeConvertSingle( ConversionCheckers& conversion_checkers) const { const auto& declaration = *To<CSSCustomPropertyDeclaration>( To<CSSPropertySpecificKeyframe>(keyframe).Value()); - DCHECK_EQ(GetProperty().CustomPropertyName(), declaration.GetName()); if ((!declaration.Value() || !declaration.Value()->NeedsVariableResolution()) && !declaration.IsRevert()) { @@ -65,9 +65,10 @@ InterpolationValue CSSVarCycleInterpolationType::MaybeConvertSingle( const auto& css_environment = To<CSSInterpolationEnvironment>(environment); - bool cycle_detected = !css_environment.Resolve(GetProperty(), &declaration); + PropertyHandle property = GetProperty(); + bool cycle_detected = !css_environment.Resolve(property, &declaration); conversion_checkers.push_back( - std::make_unique<CycleChecker>(declaration, cycle_detected)); + std::make_unique<CycleChecker>(property, declaration, cycle_detected)); return cycle_detected ? CreateCycleDetectedValue() : nullptr; } @@ -117,10 +118,9 @@ void CSSVarCycleInterpolationType::Apply( StyleBuilder::ApplyProperty( GetProperty().GetCSSPropertyName(), To<CSSInterpolationEnvironment>(environment).GetState(), - ScopedCSSValue( - *MakeGarbageCollected<CSSCustomPropertyDeclaration>( - GetProperty().CustomPropertyName(), CSSValueID::kUnset), - nullptr)); + ScopedCSSValue(*MakeGarbageCollected<CSSCustomPropertyDeclaration>( + CSSValueID::kUnset), + nullptr)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations.cc b/chromium/third_party/blink/renderer/core/animation/document_animations.cc index c7ed01c694e..6e5b4f97038 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_animations.cc @@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/css/css_scroll_timeline.h" +#include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/pending_animations.h" #include "third_party/blink/renderer/core/animation/worklet_animation_controller.h" @@ -110,9 +111,13 @@ void DocumentAnimations::UpdateAnimationTimingIfNeeded() { void DocumentAnimations::UpdateAnimations( DocumentLifecycle::LifecycleState required_lifecycle_state, - const PaintArtifactCompositor* paint_artifact_compositor) { + const PaintArtifactCompositor* paint_artifact_compositor, + bool compositor_properties_updated) { DCHECK(document_->Lifecycle().GetState() >= required_lifecycle_state); + if (compositor_properties_updated) + MarkPendingIfCompositorPropertyAnimationChanges(paint_artifact_compositor); + if (document_->GetPendingAnimations().Update(paint_artifact_compositor)) { DCHECK(document_->View()); document_->View()->ScheduleAnimation(); @@ -123,6 +128,14 @@ void DocumentAnimations::UpdateAnimations( timeline->ScheduleNextService(); } +void DocumentAnimations::MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor* paint_artifact_compositor) { + for (auto& timeline : timelines_) { + timeline->MarkPendingIfCompositorPropertyAnimationChanges( + paint_artifact_compositor); + } +} + size_t DocumentAnimations::GetAnimationsCount() { wtf_size_t total_animations_count = 0; if (document_->View()) { @@ -169,21 +182,40 @@ void DocumentAnimations::ValidateTimelines() { unvalidated_timelines_.clear(); } -void DocumentAnimations::CacheCSSScrollTimeline(CSSScrollTimeline& timeline) { - // We cache the least seen CSSScrollTimeline for a given name. - cached_css_timelines_.Set(timeline.Name(), &timeline); +DocumentAnimations::AllowAnimationUpdatesScope::AllowAnimationUpdatesScope( + DocumentAnimations& document_animations, + bool value) + : allow_(&document_animations.allow_animation_updates_, + document_animations.allow_animation_updates_.value_or(true) && + value) {} + +void DocumentAnimations::AddElementWithPendingAnimationUpdate( + Element& element) { + DCHECK(AnimationUpdatesAllowed()); + elements_with_pending_updates_.insert(&element); } -CSSScrollTimeline* DocumentAnimations::FindCachedCSSScrollTimeline( - const AtomicString& name) { - return To<CSSScrollTimeline>(cached_css_timelines_.at(name)); +void DocumentAnimations::ApplyPendingElementUpdates() { + HeapHashSet<WeakMember<Element>> pending; + std::swap(pending, elements_with_pending_updates_); + + for (auto& element : pending) { + ElementAnimations* element_animations = element->GetElementAnimations(); + if (!element_animations) + continue; + element_animations->CssAnimations().MaybeApplyPendingUpdate(element.Get()); + } + + DCHECK(elements_with_pending_updates_.IsEmpty()) + << "MaybeApplyPendingUpdate must not mark any elements as having a " + "pending update"; } void DocumentAnimations::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(timelines_); visitor->Trace(unvalidated_timelines_); - visitor->Trace(cached_css_timelines_); + visitor->Trace(elements_with_pending_updates_); } void DocumentAnimations::GetAnimationsTargetingTreeScope( diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations.h b/chromium/third_party/blink/renderer/core/animation/document_animations.h index 5c74f71615f..b57c9b62760 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/document_animations.h @@ -31,6 +31,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_ +#include "base/auto_reset.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -38,7 +40,6 @@ namespace blink { class AnimationTimeline; -class CSSScrollTimeline; class Document; class PaintArtifactCompositor; @@ -64,7 +65,8 @@ class CORE_EXPORT DocumentAnimations final // both composited and non-composited animations. void UpdateAnimations( DocumentLifecycle::LifecycleState required_lifecycle_state, - const PaintArtifactCompositor* paint_artifact_compositor); + const PaintArtifactCompositor*, + bool compositor_properties_updated); size_t GetAnimationsCount(); @@ -88,8 +90,39 @@ class CORE_EXPORT DocumentAnimations final // https://github.com/w3c/csswg-drafts/issues/5261 void ValidateTimelines(); - void CacheCSSScrollTimeline(CSSScrollTimeline&); - CSSScrollTimeline* FindCachedCSSScrollTimeline(const AtomicString&); + // By default, animation updates are *implicitly* disallowed. This object + // can be used to allow or disallow animation updates as follows: + // + // AllowAnimationUpdatesScope(..., true): Allow animation updates, unless + // updates are currently *explicitly* disallowed. + // + // AllowAnimationUpdatesScope(..., false): Explicitly disallow animation + // updates. + class CORE_EXPORT AllowAnimationUpdatesScope { + STACK_ALLOCATED(); + + public: + AllowAnimationUpdatesScope(DocumentAnimations&, bool); + + private: + base::AutoReset<absl::optional<bool>> allow_; + }; + + // Add an element to the set of elements with a pending animation update. + // The elements in the set can be applied later using, + // ApplyPendingElementUpdates. + // + // It's invalid to call this function during if animation updates are not + // allowed (see AnimationUpdatesAllowed). + void AddElementWithPendingAnimationUpdate(Element&); + + // Apply pending updates for any elements previously added during AddElement- + // WithPendingAnimationUpdate + void ApplyPendingElementUpdates(); + + bool AnimationUpdatesAllowed() const { + return allow_animation_updates_.value_or(false); + } const HeapHashSet<WeakMember<AnimationTimeline>>& GetTimelinesForTesting() const { @@ -102,23 +135,29 @@ class CORE_EXPORT DocumentAnimations final uint64_t current_transition_generation_; void Trace(Visitor*) const; +#if DCHECK_IS_ON() + void AssertNoPendingUpdates() { + DCHECK(elements_with_pending_updates_.IsEmpty()); + } +#endif + protected: using ReplaceableAnimationsMap = HeapHashMap<Member<Element>, Member<HeapVector<Member<Animation>>>>; void RemoveReplacedAnimations(ReplaceableAnimationsMap*); private: + friend class AllowAnimationUpdatesScope; + friend class AnimationUpdateScope; + + void MarkPendingIfCompositorPropertyAnimationChanges( + const PaintArtifactCompositor*); + Member<Document> document_; HeapHashSet<WeakMember<AnimationTimeline>> timelines_; HeapHashSet<WeakMember<AnimationTimeline>> unvalidated_timelines_; - - // We cache CSSScrollTimelines by name, such that multiple animations using - // the same timeline can use the same CSSScrollTimeline instance. - // - // Note that timelines present in |cached_css_timelines_| are also present - // in |timelines_|. - HeapHashMap<AtomicString, WeakMember<AnimationTimeline>> - cached_css_timelines_; + HeapHashSet<WeakMember<Element>> elements_with_pending_updates_; + absl::optional<bool> allow_animation_updates_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc index 7dabd7cb713..16e40802b59 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc @@ -142,4 +142,50 @@ TEST_F(DocumentAnimationsTest, UpdateAnimationsUpdatesAllTimelines) { EXPECT_EQ(5u, host->MainThreadAnimationsCount()); } +TEST_F(DocumentAnimationsTest, AllowAnimationUpdatesScope) { + DocumentAnimations& document_animations = document->GetDocumentAnimations(); + auto allowed = [&document_animations]() -> bool { + return document_animations.AnimationUpdatesAllowed(); + }; + + using AllowAnimationUpdatesScope = + DocumentAnimations::AllowAnimationUpdatesScope; + + // Implicitly disallowed by default: + EXPECT_FALSE(allowed()); + + { + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_TRUE(allowed()); + + { + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_TRUE(allowed()); + } + + { + // Disallow explicitly: + AllowAnimationUpdatesScope scope(document_animations, false); + EXPECT_FALSE(allowed()); + + { + // Allowing while explicitly disallowed has no effect: + AllowAnimationUpdatesScope scope(document_animations, true); + EXPECT_FALSE(allowed()); + } + + EXPECT_FALSE(allowed()); + } + + EXPECT_TRUE(allowed()); + } + + { + AllowAnimationUpdatesScope scope(document_animations, false); + EXPECT_FALSE(allowed()); + } + + EXPECT_FALSE(allowed()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc index d42c89dbb3d..490925a7008 100644 --- a/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc @@ -371,22 +371,12 @@ TEST_F(AnimationDocumentTimelineTest, PauseForTesting) { Animation* animation2 = timeline->Play(anim2); timeline->PauseAnimationsForTesting(seek_time); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* current_time = animation1->currentTime(); EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(), Animation::kTimeToleranceMs); current_time = animation2->currentTime(); EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(), Animation::kTimeToleranceMs); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - CSSNumberish current_time; - animation1->currentTime(current_time); - EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(), - Animation::kTimeToleranceMs); - animation2->currentTime(current_time); - EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(), - Animation::kTimeToleranceMs); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) { @@ -421,12 +411,8 @@ TEST_F(AnimationDocumentTimelineTest, UseAnimationAfterTimelineDeref) { Animation* animation = timeline->Play(nullptr); timeline.Clear(); // Test passes if this does not crash. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(0)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) } TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref) { diff --git a/chromium/third_party/blink/renderer/core/animation/effect_input.cc b/chromium/third_party/blink/renderer/core/animation/effect_input.cc index be3c8bca7d5..ee8b9f5f7b8 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_input.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_input.cc @@ -35,9 +35,11 @@ #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/script_iterator.h" -#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h" #include "third_party/blink/renderer/bindings/core/v8/v8_base_keyframe.h" #include "third_party/blink/renderer/bindings/core/v8/v8_base_property_indexed_keyframe.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_compositeoperationorauto_compositeoperationorautosequence.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_doubleornullsequence_null.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/core/animation/compositor_animations.h" #include "third_party/blink/renderer/core/animation/css/css_animations.h" @@ -65,21 +67,25 @@ namespace { // vector of absl::optional<EffectModel::CompositeOperation> enums. Vector<absl::optional<EffectModel::CompositeOperation>> ParseCompositeProperty( const BasePropertyIndexedKeyframe* keyframe) { - const CompositeOperationOrAutoOrCompositeOperationOrAutoSequence& composite = - keyframe->composite(); - - if (composite.IsCompositeOperationOrAuto()) { - return {EffectModel::StringToCompositeOperation( - composite.GetAsCompositeOperationOrAuto())}; - } - - Vector<absl::optional<EffectModel::CompositeOperation>> result; - for (const String& composite_operation_string : - composite.GetAsCompositeOperationOrAutoSequence()) { - result.push_back( - EffectModel::StringToCompositeOperation(composite_operation_string)); + const auto* composite = keyframe->composite(); + switch (composite->GetContentType()) { + case V8UnionCompositeOperationOrAutoOrCompositeOperationOrAutoSequence:: + ContentType::kCompositeOperationOrAuto: + return {EffectModel::StringToCompositeOperation( + composite->GetAsCompositeOperationOrAuto().AsString())}; + case V8UnionCompositeOperationOrAutoOrCompositeOperationOrAutoSequence:: + ContentType::kCompositeOperationOrAutoSequence: { + Vector<absl::optional<EffectModel::CompositeOperation>> result; + for (const auto& composite_operation : + composite->GetAsCompositeOperationOrAutoSequence()) { + result.push_back(EffectModel::StringToCompositeOperation( + composite_operation.AsString())); + } + return result; + } } - return result; + NOTREACHED(); + return {}; } void SetKeyframeValue(Element* element, @@ -414,17 +420,19 @@ bool GetPropertyIndexedKeyframeValues(const v8::Local<v8::Object>& keyframe, return {}; } - StringOrStringSequence string_or_string_sequence; - V8StringOrStringSequence::ToImpl( - script_state->GetIsolate(), v8_value, string_or_string_sequence, - UnionTypeConversionMode::kNotNullable, exception_state); + auto* string_or_string_sequence = + V8UnionStringOrStringSequence::Create(isolate, v8_value, exception_state); if (exception_state.HadException()) return false; - if (string_or_string_sequence.IsString()) - result.push_back(string_or_string_sequence.GetAsString()); - else - result = string_or_string_sequence.GetAsStringSequence(); + switch (string_or_string_sequence->GetContentType()) { + case V8UnionStringOrStringSequence::ContentType::kString: + result.push_back(string_or_string_sequence->GetAsString()); + break; + case V8UnionStringOrStringSequence::ContentType::kStringSequence: + result = string_or_string_sequence->GetAsStringSequence(); + break; + } return true; } @@ -451,20 +459,20 @@ StringKeyframeVector ConvertObjectForm(Element* element, return {}; Vector<absl::optional<double>> offsets; - if (property_indexed_keyframe->offset().IsNull()) + if (property_indexed_keyframe->offset()->IsNull()) offsets.push_back(absl::nullopt); - else if (property_indexed_keyframe->offset().IsDouble()) - offsets.push_back(property_indexed_keyframe->offset().GetAsDouble()); + else if (property_indexed_keyframe->offset()->IsDouble()) + offsets.push_back(property_indexed_keyframe->offset()->GetAsDouble()); else - offsets = property_indexed_keyframe->offset().GetAsDoubleOrNullSequence(); + offsets = property_indexed_keyframe->offset()->GetAsDoubleOrNullSequence(); // The web-animations spec explicitly states that easings should be kept as // DOMStrings here and not parsed into timing functions until later. Vector<String> easings; - if (property_indexed_keyframe->easing().IsString()) - easings.push_back(property_indexed_keyframe->easing().GetAsString()); + if (property_indexed_keyframe->easing()->IsString()) + easings.push_back(property_indexed_keyframe->easing()->GetAsString()); else - easings = property_indexed_keyframe->easing().GetAsStringSequence(); + easings = property_indexed_keyframe->easing()->GetAsStringSequence(); Vector<absl::optional<EffectModel::CompositeOperation>> composite_operations = ParseCompositeProperty(property_indexed_keyframe); @@ -657,6 +665,7 @@ bool HasAdditiveCompositeCSSKeyframe( } return false; } + } // namespace KeyframeEffectModelBase* EffectInput::Convert( @@ -751,4 +760,5 @@ EffectModel::CompositeOperation EffectInput::ResolveCompositeOperation( } return result; } + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/effect_model.h b/chromium/third_party/blink/renderer/core/animation/effect_model.h index 30ca0846f47..3cff2b57fbc 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_model.h +++ b/chromium/third_party/blink/renderer/core/animation/effect_model.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_EFFECT_MODEL_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_EFFECT_MODEL_H_ +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_time_delta.h" #include "third_party/blink/renderer/core/animation/property_handle.h" #include "third_party/blink/renderer/core/core_export.h" diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc index 0b5911bc87d..cee21c61ad7 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc @@ -140,6 +140,20 @@ bool EffectStack::AffectsProperties(const CSSBitset& bitset, return false; } +HashSet<PropertyHandle> EffectStack::AffectedProperties( + KeyframeEffect::Priority priority) const { + HashSet<PropertyHandle> affected; + + for (const auto& sampled_effect : sampled_effects_) { + if (sampled_effect->GetPriority() != priority) + continue; + for (const auto& interpolation : sampled_effect->Interpolations()) + affected.insert(interpolation->GetProperty()); + } + + return affected; +} + bool EffectStack::HasRevert() const { for (const auto& sampled_effect : sampled_effects_) { if (sampled_effect->Effect() && sampled_effect->Effect()->HasRevert()) diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack.h b/chromium/third_party/blink/renderer/core/animation/effect_stack.h index f97e0619a74..7a18409ff1c 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_stack.h +++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.h @@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_EFFECT_STACK_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_EFFECT_STACK_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/effect_model.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" @@ -54,6 +53,8 @@ class CORE_EXPORT EffectStack { public: EffectStack(); + EffectStack(const EffectStack&) = delete; + EffectStack& operator=(const EffectStack&) = delete; void Add(SampledEffect* sampled_effect) { sampled_effects_.push_back(sampled_effect); @@ -67,6 +68,8 @@ class CORE_EXPORT EffectStack { bool AffectsProperties(PropertyHandleFilter) const; bool AffectsProperties(const CSSBitset&, KeyframeEffect::Priority priority) const; + HashSet<PropertyHandle> AffectedProperties( + KeyframeEffect::Priority priority) const; bool HasRevert() const; // Produces a map of properties to active effects. @@ -97,7 +100,6 @@ class CORE_EXPORT EffectStack { HeapVector<Member<SampledEffect>> sampled_effects_; friend class AnimationEffectStackTest; - DISALLOW_COPY_AND_ASSIGN(EffectStack); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc index 13a728cafc9..ce47be151d2 100644 --- a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc @@ -36,13 +36,9 @@ class AnimationEffectStackTest : public PageTestBase { Animation* Play(KeyframeEffect* effect, double start_time) { Animation* animation = timeline->Play(effect); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setStartTime( MakeGarbageCollected<V8CSSNumberish>(start_time * 1000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setStartTime(CSSNumberish::FromDouble(start_time * 1000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->Update(kTimingUpdateOnDemand); return animation; } @@ -291,4 +287,46 @@ TEST_F(AnimationEffectStackTest, AffectsPropertiesCSSBitsetTransitionPriority) { KeyframeEffect::kTransitionPriority)); } +TEST_F(AnimationEffectStackTest, AffectedPropertiesDefaultPriority) { + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kColor, "red")), 10); + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kTop, "1px")), 10); + Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyID::kLeft, "1px")), 10); + + ASSERT_TRUE(element->GetElementAnimations()); + const EffectStack& effect_stack = + element->GetElementAnimations()->GetEffectStack(); + + EXPECT_TRUE( + effect_stack.AffectedProperties(KeyframeEffect::kTransitionPriority) + .IsEmpty()); + + auto set = effect_stack.AffectedProperties(KeyframeEffect::kDefaultPriority); + ASSERT_EQ(3u, set.size()); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyColor()))); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyTop()))); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyLeft()))); +} + +TEST_F(AnimationEffectStackTest, AffectedPropertiesTransitionPriority) { + Element* body = GetDocument().body(); + body->SetInlineStyleProperty(CSSPropertyID::kTransition, "color 10s"); + body->SetInlineStyleProperty(CSSPropertyID::kColor, "red"); + UpdateAllLifecyclePhasesForTest(); + + body->SetInlineStyleProperty(CSSPropertyID::kColor, "blue"); + UpdateAllLifecyclePhasesForTest(); + + ASSERT_TRUE(body->GetElementAnimations()); + const EffectStack& effect_stack = + body->GetElementAnimations()->GetEffectStack(); + + EXPECT_TRUE(effect_stack.AffectedProperties(KeyframeEffect::kDefaultPriority) + .IsEmpty()); + + auto set = + effect_stack.AffectedProperties(KeyframeEffect::kTransitionPriority); + ASSERT_EQ(1u, set.size()); + EXPECT_TRUE(set.Contains(PropertyHandle(GetCSSPropertyColor()))); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/element_animations.cc b/chromium/third_party/blink/renderer/core/animation/element_animations.cc index fa1b98062d0..9ca568de879 100644 --- a/chromium/third_party/blink/renderer/core/animation/element_animations.cc +++ b/chromium/third_party/blink/renderer/core/animation/element_animations.cc @@ -53,6 +53,8 @@ void UpdateAnimationFlagsForEffect(const KeyframeEffect& effect, style.SetHasCurrentBackdropFilterAnimation(true); if (effect.Affects(PropertyHandle(GetCSSPropertyBackgroundColor()))) style.SetHasCurrentBackgroundColorAnimation(true); + if (effect.Affects(PropertyHandle(GetCSSPropertyClipPath()))) + style.SetHasCurrentClipPathAnimation(true); } } // namespace @@ -124,29 +126,6 @@ void ElementAnimations::Trace(Visitor* visitor) const { visitor->Trace(worklet_animations_); } -const ComputedStyle* ElementAnimations::BaseComputedStyle() const { - return base_computed_style_.get(); -} - -const CSSBitset* ElementAnimations::BaseImportantSet() const { - if (IsAnimationStyleChange()) - return base_important_set_.get(); - return nullptr; -} - -void ElementAnimations::UpdateBaseComputedStyle( - const ComputedStyle* computed_style, - std::unique_ptr<CSSBitset> base_important_set) { - DCHECK(computed_style); - base_computed_style_ = ComputedStyle::Clone(*computed_style); - base_important_set_ = std::move(base_important_set); -} - -void ElementAnimations::ClearBaseComputedStyle() { - base_computed_style_ = nullptr; - base_important_set_ = nullptr; -} - bool ElementAnimations::UpdateBoxSizeAndCheckTransformAxisAlignment( const FloatSize& box_size) { bool preserves_axis_alignment = true; diff --git a/chromium/third_party/blink/renderer/core/animation/element_animations.h b/chromium/third_party/blink/renderer/core/animation/element_animations.h index babb8cbff4c..e6e2cf4c8fb 100644 --- a/chromium/third_party/blink/renderer/core/animation/element_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/element_animations.h @@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ELEMENT_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ELEMENT_ANIMATIONS_H_ -#include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/animation/css/css_animations.h" #include "third_party/blink/renderer/core/animation/effect_stack.h" @@ -51,6 +50,8 @@ class CORE_EXPORT ElementAnimations final : public GarbageCollected<ElementAnimations> { public: ElementAnimations(); + ElementAnimations(const ElementAnimations&) = delete; + ElementAnimations& operator=(const ElementAnimations&) = delete; ~ElementAnimations(); // Animations that are currently active for this element, their effects will @@ -82,12 +83,6 @@ class CORE_EXPORT ElementAnimations final } bool IsAnimationStyleChange() const { return animation_style_change_; } - const ComputedStyle* BaseComputedStyle() const; - const CSSBitset* BaseImportantSet() const; - void UpdateBaseComputedStyle(const ComputedStyle*, - std::unique_ptr<CSSBitset> base_important_set); - void ClearBaseComputedStyle(); - bool UpdateBoxSizeAndCheckTransformAxisAlignment(const FloatSize& box_size); bool IsIdentityOrTranslation() const; @@ -105,24 +100,9 @@ class CORE_EXPORT ElementAnimations final // style, we store a cached value of the 'base' computed style (e.g. with no // change from the running animations) and use that during style recalc, // applying only the animation changes on top of it. - bool animation_style_change_; - scoped_refptr<ComputedStyle> base_computed_style_; - // Keeps track of the !important declarations used to build the base - // computed style. These declarations must not be overwritten by animation - // effects, hence we have to disable the base computed style optimization when - // !important declarations conflict with active animations. // - // If there were no !important declarations in the base style, this field - // will be nullptr. - // - // TODO(andruud): We should be able to simply skip applying the animation - // for properties in this set instead of disabling the optimization. - // However, we currently need the cascade to handle the case where - // an !important declaration appears in a :visited selector. - // See https://crbug.com/1062217. - std::unique_ptr<CSSBitset> base_important_set_; - - DISALLOW_COPY_AND_ASSIGN(ElementAnimations); + // See also StyleBaseData. + bool animation_style_change_; FRIEND_TEST_ALL_PREFIXES(StyleEngineTest, PseudoElementBaseComputedStyle); }; diff --git a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc index 94a09d84855..8a3e492bfca 100644 --- a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc @@ -56,7 +56,7 @@ void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const { DCHECK(iteration); DCHECK_GE(iteration.value(), 0); model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), result); + NormalizedTiming().iteration_duration, result); } AnimationTimeDelta InertEffect::CalculateTimeToEffectChange( diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_aspect_ratio.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_aspect_ratio.cc index cfcbc5408f0..7754db3b091 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_aspect_ratio.cc +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_aspect_ratio.cc @@ -13,9 +13,6 @@ namespace blink { // static std::unique_ptr<InterpolableAspectRatio> InterpolableAspectRatio::MaybeCreate( const StyleAspectRatio& aspect_ratio) { - if (!RuntimeEnabledFeatures::CSSAspectRatioInterpolationEnabled()) - return nullptr; - // Auto aspect ratio cannot be interpolated to / from. if (aspect_ratio.IsAuto()) return nullptr; diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.cc index 92c9fbab3bb..92a6b85d05b 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.cc +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.cc @@ -10,12 +10,6 @@ namespace blink { // static -std::unique_ptr<InterpolableTransformList> InterpolableTransformList::Create( - TransformOperations&& operations) { - return std::make_unique<InterpolableTransformList>(std::move(operations)); -} - -// static std::unique_ptr<InterpolableTransformList> InterpolableTransformList::ConvertCSSValue(const CSSValue& css_value, const StyleResolverState* state) { diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.h b/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.h index 9275a2e0fc9..65f9ca508f4 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_transform_list.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_TRANSFORM_LIST_H_ #include <memory> + #include "third_party/blink/renderer/core/animation/interpolable_value.h" #include "third_party/blink/renderer/platform/transforms/transform_operations.h" #include "third_party/blink/renderer/platform/wtf/casting.h" @@ -22,8 +23,6 @@ class CORE_EXPORT InterpolableTransformList final : public InterpolableValue { InterpolableTransformList(TransformOperations&& operations) : operations_(std::move(operations)) {} - static std::unique_ptr<InterpolableTransformList> Create( - TransformOperations&&); static std::unique_ptr<InterpolableTransformList> ConvertCSSValue( const CSSValue&, const StyleResolverState*); diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h index 0fe3e2eb890..54cb5f25e93 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h @@ -8,11 +8,10 @@ #include <memory> #include <utility> -#include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { @@ -104,22 +103,15 @@ class CORE_EXPORT InterpolableNumber final : public InterpolableValue { double value_; }; -class CORE_EXPORT InterpolableList : public InterpolableValue { +class CORE_EXPORT InterpolableList final : public InterpolableValue { public: - // Explicitly delete operator= because MSVC automatically generate - // copy constructors and operator= for dll-exported classes. - // Since InterpolableList is not copyable, automatically generated - // operator= causes MSVC compiler error. - // However, we cannot use DISALLOW_COPY_AND_ASSIGN because InterpolableList - // has its own copy constructor. So just delete operator= here. - InterpolableList& operator=(const InterpolableList&) = delete; - explicit InterpolableList(wtf_size_t size) : values_(size) {} - InterpolableList(const InterpolableList& other) : values_(other.length()) { - for (wtf_size_t i = 0; i < length(); i++) - Set(i, other.values_[i]->Clone()); - } + // Move-only; use Clone() to make a copy. + InterpolableList(const InterpolableList&) = delete; + InterpolableList& operator=(const InterpolableList&) = delete; + InterpolableList(InterpolableList&&) = default; + InterpolableList& operator=(InterpolableList&&) = default; const InterpolableValue* Get(wtf_size_t position) const { return values_[position].get(); @@ -146,7 +138,10 @@ class CORE_EXPORT InterpolableList : public InterpolableValue { private: InterpolableList* RawClone() const final { - return new InterpolableList(*this); + auto* result = new InterpolableList(length()); + for (wtf_size_t i = 0; i < length(); i++) + result->Set(i, values_[i]->Clone()); + return result; } InterpolableList* RawCloneAndZero() const final; diff --git a/chromium/third_party/blink/renderer/core/animation/interpolated_svg_path_source.h b/chromium/third_party/blink/renderer/core/animation/interpolated_svg_path_source.h index e7cdaf7159c..0eb69b39f3b 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolated_svg_path_source.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolated_svg_path_source.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATED_SVG_PATH_SOURCE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATED_SVG_PATH_SOURCE_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.h" #include "third_party/blink/renderer/core/svg/svg_path_data.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -24,6 +23,10 @@ class InterpolatedSVGPathSource { DCHECK_EQ(interpolable_path_segs_.length(), path_seg_types_.size()); } + InterpolatedSVGPathSource(const InterpolatedSVGPathSource&) = delete; + InterpolatedSVGPathSource& operator=(const InterpolatedSVGPathSource&) = + delete; + bool HasMoreData() const; PathSegmentData ParseSegment(); @@ -32,7 +35,6 @@ class InterpolatedSVGPathSource { wtf_size_t current_index_; const InterpolableList& interpolable_path_segs_; const Vector<SVGPathSegType>& path_seg_types_; - DISALLOW_COPY_AND_ASSIGN(InterpolatedSVGPathSource); }; bool InterpolatedSVGPathSource::HasMoreData() const { diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation.h b/chromium/third_party/blink/renderer/core/animation/interpolation.h index 228bab31669..d57ab9d2bd9 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolation.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolation.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATION_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLATION_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/interpolable_value.h" #include "third_party/blink/renderer/core/animation/property_handle.h" #include "third_party/blink/renderer/core/core_export.h" @@ -57,6 +56,8 @@ namespace blink { // the subclass documentation for more. class CORE_EXPORT Interpolation : public GarbageCollected<Interpolation> { public: + Interpolation(const Interpolation&) = delete; + Interpolation& operator=(const Interpolation&) = delete; virtual ~Interpolation() {} virtual void Interpolate(int iteration, double fraction) = 0; @@ -76,7 +77,6 @@ class CORE_EXPORT Interpolation : public GarbageCollected<Interpolation> { protected: Interpolation() = default; - DISALLOW_COPY_AND_ASSIGN(Interpolation); }; using ActiveInterpolations = HeapVector<Member<Interpolation>, 1>; diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/interpolation_type.h index 431d50dd590..b2567c485df 100644 --- a/chromium/third_party/blink/renderer/core/animation/interpolation_type.h +++ b/chromium/third_party/blink/renderer/core/animation/interpolation_type.h @@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/interpolation_value.h" #include "third_party/blink/renderer/core/animation/keyframe.h" #include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h" @@ -33,6 +32,8 @@ class CORE_EXPORT InterpolationType { USING_FAST_MALLOC(InterpolationType); public: + InterpolationType(const InterpolationType&) = delete; + InterpolationType& operator=(const InterpolationType&) = delete; virtual ~InterpolationType() = default; PropertyHandle GetProperty() const { return property_; } @@ -45,6 +46,8 @@ class CORE_EXPORT InterpolationType { USING_FAST_MALLOC(ConversionChecker); public: + ConversionChecker(const ConversionChecker&) = delete; + ConversionChecker& operator=(const ConversionChecker&) = delete; virtual ~ConversionChecker() = default; void SetType(const InterpolationType& type) { type_ = &type; } const InterpolationType& GetType() const { return *type_; } @@ -54,7 +57,6 @@ class CORE_EXPORT InterpolationType { protected: ConversionChecker() : type_(nullptr) {} const InterpolationType* type_; - DISALLOW_COPY_AND_ASSIGN(ConversionChecker); }; using ConversionCheckers = Vector<std::unique_ptr<ConversionChecker>>; @@ -121,7 +123,6 @@ class CORE_EXPORT InterpolationType { explicit InterpolationType(PropertyHandle property) : property_(property) {} const PropertyHandle property_; - DISALLOW_COPY_AND_ASSIGN(InterpolationType); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.h b/chromium/third_party/blink/renderer/core/animation/keyframe.h index a70ac6cd969..b4064141803 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe.h +++ b/chromium/third_party/blink/renderer/core/animation/keyframe.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_KEYFRAME_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_KEYFRAME_H_ -#include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" @@ -62,6 +61,8 @@ class V8ObjectBuilder; // FIXME: Make Keyframe immutable class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { public: + Keyframe(const Keyframe&) = delete; + Keyframe& operator=(const Keyframe&) = delete; virtual ~Keyframe() = default; // TODO(smcgruer): The keyframe offset should be immutable. @@ -124,6 +125,9 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { PropertySpecificKeyframe(double offset, scoped_refptr<TimingFunction> easing, EffectModel::CompositeOperation); + PropertySpecificKeyframe(const PropertySpecificKeyframe&) = delete; + PropertySpecificKeyframe& operator=(const PropertySpecificKeyframe&) = + delete; virtual ~PropertySpecificKeyframe() = default; double Offset() const { return offset_; } TimingFunction& Easing() const { return *easing_; } @@ -165,8 +169,6 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { double offset_; scoped_refptr<TimingFunction> easing_; EffectModel::CompositeOperation composite_; - - DISALLOW_COPY_AND_ASSIGN(PropertySpecificKeyframe); }; // Construct and return a property-specific keyframe for this keyframe. @@ -202,7 +204,6 @@ class CORE_EXPORT Keyframe : public GarbageCollected<Keyframe> { // absl::nullopt value represents 'auto'. absl::optional<EffectModel::CompositeOperation> composite_; scoped_refptr<TimingFunction> easing_; - DISALLOW_COPY_AND_ASSIGN(Keyframe); }; using PropertySpecificKeyframe = Keyframe::PropertySpecificKeyframe; diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc index 68f1663432f..3b1953b375b 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc @@ -30,7 +30,7 @@ #include "third_party/blink/renderer/core/animation/keyframe_effect.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" @@ -88,11 +88,7 @@ KeyframeEffect* KeyframeEffect::Create( ScriptState* script_state, Element* element, const ScriptValue& keyframes, -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - const UnrestrictedDoubleOrKeyframeEffectOptions& options, -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) ExceptionState& exception_state) { Document* document = element ? &element->GetDocument() : nullptr; Timing timing = TimingInput::Convert(options, document, exception_state); @@ -101,18 +97,8 @@ KeyframeEffect* KeyframeEffect::Create( EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace; String pseudo = String(); - if ( -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - options->IsKeyframeEffectOptions() -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - options.IsKeyframeEffectOptions() -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - ) { -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + if (options->IsKeyframeEffectOptions()) { auto* effect_options = options->GetAsKeyframeEffectOptions(); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - auto* effect_options = options.GetAsKeyframeEffectOptions(); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) composite = EffectModel::StringToCompositeOperation(effect_options->composite()) .value(); @@ -585,12 +571,12 @@ void KeyframeEffect::ApplyEffects() { if (sampled_effect_) { changed = model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), + NormalizedTiming().iteration_duration, sampled_effect_->MutableInterpolations()); } else { HeapVector<Member<Interpolation>> interpolations; model_->Sample(clampTo<int>(iteration.value(), 0), Progress().value(), - SpecifiedTiming().IterationDuration(), interpolations); + NormalizedTiming().iteration_duration, interpolations); if (!interpolations.IsEmpty()) { auto* sampled_effect = MakeGarbageCollected<SampledEffect>(this, owner_->SequenceNumber()); @@ -672,11 +658,14 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange( bool forwards, absl::optional<AnimationTimeDelta> local_time, AnimationTimeDelta time_to_next_iteration) const { - const AnimationTimeDelta start_time = SpecifiedTiming().start_delay; + const AnimationTimeDelta start_time = NormalizedTiming().start_delay; + const AnimationTimeDelta end_time_minus_end_delay = - start_time + SpecifiedTiming().ActiveDuration(); + start_time + NormalizedTiming().active_duration; + const AnimationTimeDelta end_time = - end_time_minus_end_delay + SpecifiedTiming().end_delay; + end_time_minus_end_delay + NormalizedTiming().end_delay; + const AnimationTimeDelta after_time = std::min(end_time_minus_end_delay, end_time); diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h index ea23ee7f945..702db6ae8d5 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h @@ -46,7 +46,6 @@ class ExceptionState; class KeyframeEffectModelBase; class PaintArtifactCompositor; class SampledEffect; -class UnrestrictedDoubleOrKeyframeEffectOptions; class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble; // Represents the effect of an Animation on an Element's properties. @@ -58,21 +57,12 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect { enum Priority { kDefaultPriority, kTransitionPriority }; // Web Animations API Bindings constructors. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static KeyframeEffect* Create( ScriptState* script_state, Element* element, const ScriptValue& keyframes, const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, ExceptionState& exception_state); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - static KeyframeEffect* Create( - ScriptState*, - Element*, - const ScriptValue&, - const UnrestrictedDoubleOrKeyframeEffectOptions&, - ExceptionState&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static KeyframeEffect* Create(ScriptState*, Element*, const ScriptValue&, diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc index 88ec4bdb326..bbc8e7c2746 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc @@ -41,7 +41,6 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/style/computed_style.h" -#include "third_party/blink/renderer/platform/animation/animation_utilities.h" #include "third_party/blink/renderer/platform/geometry/float_box.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -96,7 +95,7 @@ bool KeyframeEffectModelBase::Sample( namespace { -static const size_t num_compositable_properties = 8; +static const size_t num_compositable_properties = 9; const CSSProperty** CompositableProperties() { static const CSSProperty* @@ -104,7 +103,8 @@ const CSSProperty** CompositableProperties() { &GetCSSPropertyOpacity(), &GetCSSPropertyRotate(), &GetCSSPropertyScale(), &GetCSSPropertyTransform(), &GetCSSPropertyTranslate(), &GetCSSPropertyFilter(), - &GetCSSPropertyBackdropFilter(), &GetCSSPropertyBackgroundColor()}; + &GetCSSPropertyBackdropFilter(), &GetCSSPropertyBackgroundColor(), + &GetCSSPropertyClipPath()}; return kCompositableProperties; } @@ -211,11 +211,12 @@ bool KeyframeEffectModelBase::SnapshotCompositorKeyFrames( if (!should_snapshot_property_callback(property)) return false; - PropertySpecificKeyframeGroup* keyframe_group = - keyframe_groups_->at(property); - if (!keyframe_group) + auto it = keyframe_groups_->find(property); + if (it == keyframe_groups_->end()) return false; + PropertySpecificKeyframeGroup* keyframe_group = it->value; + bool updated = false; for (auto& keyframe : keyframe_group->keyframes_) { if (!should_snapshot_keyframe_callback(*keyframe)) @@ -357,7 +358,8 @@ bool KeyframeEffectModelBase::RequiresPropertyNode() const { if (!property.IsCSSProperty() || (property.GetCSSProperty().PropertyID() != CSSPropertyID::kVariable && property.GetCSSProperty().PropertyID() != - CSSPropertyID::kBackgroundColor)) + CSSPropertyID::kBackgroundColor && + property.GetCSSProperty().PropertyID() != CSSPropertyID::kClipPath)) return true; } } diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc index 990602e28c8..1c229edbcb5 100644 --- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc @@ -8,7 +8,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" @@ -16,6 +15,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" @@ -90,13 +90,8 @@ class AnimationKeyframeEffectV8Test : public KeyframeEffectTest { NonThrowableExceptionState exception_state; return KeyframeEffect::Create( script_state, element, keyframe_object, -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( timing_input), -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeEffectOptions::FromUnrestrictedDouble( - timing_input), -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) exception_state); } static KeyframeEffect* CreateAnimationFromOption( @@ -107,13 +102,8 @@ class AnimationKeyframeEffectV8Test : public KeyframeEffectTest { NonThrowableExceptionState exception_state; return KeyframeEffect::Create( script_state, element, keyframe_object, -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( const_cast<KeyframeEffectOptions*>(timing_input)), -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( - const_cast<KeyframeEffectOptions*>(timing_input)), -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) exception_state); } static KeyframeEffect* CreateAnimation(ScriptState* script_state, @@ -315,10 +305,10 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) { timing_input_dictionary_with_duration); EffectTiming* specified_with_duration = animation_with_duration->getTiming(); - UnrestrictedDoubleOrString duration = specified_with_duration->duration(); - EXPECT_TRUE(duration.IsUnrestrictedDouble()); - EXPECT_EQ(2.5, duration.GetAsUnrestrictedDouble()); - EXPECT_FALSE(duration.IsString()); + auto* duration = specified_with_duration->duration(); + EXPECT_TRUE(duration->IsUnrestrictedDouble()); + EXPECT_EQ(2.5, duration->GetAsUnrestrictedDouble()); + EXPECT_FALSE(duration->IsString()); v8::Local<v8::Object> timing_input_no_duration = v8::Object::New(scope.GetIsolate()); @@ -332,10 +322,10 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) { timing_input_dictionary_no_duration); EffectTiming* specified_no_duration = animation_no_duration->getTiming(); - UnrestrictedDoubleOrString duration2 = specified_no_duration->duration(); - EXPECT_FALSE(duration2.IsUnrestrictedDouble()); - EXPECT_TRUE(duration2.IsString()); - EXPECT_EQ("auto", duration2.GetAsString()); + auto* duration2 = specified_no_duration->duration(); + EXPECT_FALSE(duration2->IsUnrestrictedDouble()); + EXPECT_TRUE(duration2->IsString()); + EXPECT_EQ("auto", duration2->GetAsString()); } TEST_F(AnimationKeyframeEffectV8Test, SetKeyframesAdditiveCompositeOperation) { @@ -390,48 +380,32 @@ TEST_F(KeyframeEffectTest, TimeToEffectChange) { keyframe_effect->TimeToReverseEffectChange()); // End of the before phase. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(100000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // Nearing the end of the active phase. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(199000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(199000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // End of the active phase. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(200000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(200000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta(), keyframe_effect->TimeToReverseEffectChange()); // End of the animation. -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(300000), ASSERT_NO_EXCEPTION); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - animation->setCurrentTime(CSSNumberish::FromDouble(300000)); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) EXPECT_EQ(AnimationTimeDelta::Max(), keyframe_effect->TimeToForwardsEffectChange()); EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100), diff --git a/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc b/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc index 498f66ba252..3cd0a544662 100644 --- a/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc +++ b/chromium/third_party/blink/renderer/core/animation/length_property_functions.cc @@ -457,8 +457,6 @@ bool LengthPropertyFunctions::SetLength(const CSSProperty& property, case CSSPropertyID::kTabSize: return false; - return false; - default: return false; } diff --git a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc index 09218341b00..ff54bfdfccf 100644 --- a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc @@ -16,9 +16,9 @@ namespace blink { namespace { -class TestNonInterpolableValue : public NonInterpolableValue { +class TestNonInterpolableValue final : public NonInterpolableValue { public: - ~TestNonInterpolableValue() final = default; + ~TestNonInterpolableValue() override = default; static scoped_refptr<TestNonInterpolableValue> Create(int value) { DCHECK_GE(value, 1); @@ -78,7 +78,7 @@ class TestUnderlyingValue : public UnderlyingValue { InterpolationValue CreateInterpolableList( const Vector<std::pair<double, int>>& values) { return ListInterpolationFunctions::CreateList( - values.size(), [&values](size_t i) { + values.size(), [&values](wtf_size_t i) { return InterpolationValue( std::make_unique<InterpolableNumber>(values[i].first), TestNonInterpolableValue::Create(values[i].second)); @@ -89,7 +89,7 @@ InterpolationValue CreateInterpolableList( // but a non-interpolable list of nullptrs. InterpolationValue CreateInterpolableList(const Vector<double>& values) { return ListInterpolationFunctions::CreateList( - values.size(), [&values](size_t i) { + values.size(), [&values](wtf_size_t i) { return InterpolationValue( std::make_unique<InterpolableNumber>(values[i]), nullptr); }); @@ -99,7 +99,7 @@ InterpolationValue CreateInterpolableList(const Vector<double>& values) { // values, but an interpolable list of zeroes. InterpolationValue CreateNonInterpolableList(const Vector<int>& values) { return ListInterpolationFunctions::CreateList( - values.size(), [&values](size_t i) { + values.size(), [&values](wtf_size_t i) { return InterpolationValue(std::make_unique<InterpolableNumber>(0), TestNonInterpolableValue::Create(values[i])); }); diff --git a/chromium/third_party/blink/renderer/core/animation/pending_animations.h b/chromium/third_party/blink/renderer/core/animation/pending_animations.h index ff8a6fe2f0d..e4b794621fd 100644 --- a/chromium/third_party/blink/renderer/core/animation/pending_animations.h +++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.h @@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PENDING_ANIMATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_PENDING_ANIMATIONS_H_ -#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/core_export.h" diff --git a/chromium/third_party/blink/renderer/core/animation/primitive_interpolation.h b/chromium/third_party/blink/renderer/core/animation/primitive_interpolation.h index e50e7cd7c01..e2627eac4a4 100644 --- a/chromium/third_party/blink/renderer/core/animation/primitive_interpolation.h +++ b/chromium/third_party/blink/renderer/core/animation/primitive_interpolation.h @@ -10,10 +10,9 @@ #include <memory> #include <utility> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/animation/typed_interpolation_value.h" -#include "third_party/blink/renderer/platform/animation/animation_utilities.h" +#include "third_party/blink/renderer/platform/geometry/blend.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { @@ -25,6 +24,8 @@ class PrimitiveInterpolation { USING_FAST_MALLOC(PrimitiveInterpolation); public: + PrimitiveInterpolation(const PrimitiveInterpolation&) = delete; + PrimitiveInterpolation& operator=(const PrimitiveInterpolation&) = delete; virtual ~PrimitiveInterpolation() = default; virtual void InterpolateValue( @@ -37,7 +38,6 @@ class PrimitiveInterpolation { protected: PrimitiveInterpolation() = default; - DISALLOW_COPY_AND_ASSIGN(PrimitiveInterpolation); }; // Represents a pair of keyframes that are compatible for "smooth" interpolation diff --git a/chromium/third_party/blink/renderer/core/animation/property_handle.h b/chromium/third_party/blink/renderer/core/animation/property_handle.h index d540ad6e044..8597f4b2ffc 100644 --- a/chromium/third_party/blink/renderer/core/animation/property_handle.h +++ b/chromium/third_party/blink/renderer/core/animation/property_handle.h @@ -27,11 +27,23 @@ class CORE_EXPORT PropertyHandle { DCHECK_NE(CSSPropertyID::kVariable, property.PropertyID()); } + // TODO(crbug.com/980160): Eliminate call to GetCSSPropertyVariable(). explicit PropertyHandle(const AtomicString& property_name) : handle_type_(kHandleCSSCustomProperty), css_property_(&GetCSSPropertyVariable()), property_name_(property_name) {} + // TODO(crbug.com/980160): Eliminate call to GetCSSPropertyVariable(). + explicit PropertyHandle(const CSSPropertyName& property_name) + : handle_type_(property_name.IsCustomProperty() ? kHandleCSSCustomProperty + : kHandleCSSProperty), + css_property_(property_name.IsCustomProperty() + ? &GetCSSPropertyVariable() + : &CSSProperty::Get(property_name.Id())), + property_name_(property_name.IsCustomProperty() + ? property_name.ToAtomicString() + : g_null_atom) {} + explicit PropertyHandle(const QualifiedName& attribute_name) : handle_type_(kHandleSVGAttribute), svg_attribute_(&attribute_name) {} diff --git a/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc b/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc index f4bf0734b7c..e0202437f53 100644 --- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc +++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc @@ -29,7 +29,8 @@ void SampledEffect::RemoveReplacedInterpolations( [&](const auto& interpolation) { return replaced_properties.Contains(interpolation->GetProperty()); }); - interpolations_.Shrink(new_end - interpolations_.begin()); + interpolations_.Shrink( + static_cast<wtf_size_t>(new_end - interpolations_.begin())); } void SampledEffect::UpdateReplacedProperties( diff --git a/chromium/third_party/blink/renderer/core/animation/sampled_effect.h b/chromium/third_party/blink/renderer/core/animation/sampled_effect.h index 5f9a5dff41d..ed21e02330d 100644 --- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.h +++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SAMPLED_EFFECT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SAMPLED_EFFECT_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/animation.h" #include "third_party/blink/renderer/core/animation/interpolation.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" @@ -19,6 +18,8 @@ namespace blink { class SampledEffect final : public GarbageCollected<SampledEffect> { public: SampledEffect(KeyframeEffect*, unsigned sequence_number); + SampledEffect(const SampledEffect&) = delete; + SampledEffect& operator=(const SampledEffect&) = delete; void Clear(); @@ -43,7 +44,6 @@ class SampledEffect final : public GarbageCollected<SampledEffect> { HeapVector<Member<Interpolation>> interpolations_; const unsigned sequence_number_; KeyframeEffect::Priority priority_; - DISALLOW_COPY_AND_ASSIGN(SampledEffect); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc index f5b2ce5a0e0..769e1accad3 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc @@ -31,12 +31,6 @@ namespace blink { namespace { -constexpr double kScrollTimelineDuration = 100.0; -// Animation times are tracked as TimeDeltas which are stored internally as an -// integer number of microseconds. Multiplying by 1000 converts this into a -// value equivalent to Milliseconds. -constexpr double kScrollTimelineDurationMs = kScrollTimelineDuration * 1000.0; - using ScrollTimelineSet = HeapHashMap<WeakMember<Node>, Member<HeapHashSet<WeakMember<ScrollTimeline>>>>; @@ -90,25 +84,23 @@ ScrollOrientation ToPhysicalScrollOrientation( } } -// Note that the resolution process may trigger document lifecycle to clean -// style and layout. Node* ResolveScrollSource(Element* scroll_source) { - // When in quirks mode we need the style to be clean, so we don't use - // |ScrollingElementNoLayout|. if (scroll_source && - scroll_source == scroll_source->GetDocument().scrollingElement()) { + scroll_source == + scroll_source->GetDocument().ScrollingElementNoLayout()) { return &scroll_source->GetDocument(); } return scroll_source; } + } // namespace ScrollTimeline* ScrollTimeline::Create(Document& document, ScrollTimelineOptions* options, ExceptionState& exception_state) { - Element* scroll_source = options->hasScrollSource() - ? options->scrollSource() - : document.scrollingElement(); + absl::optional<Element*> scroll_source = + options->hasScrollSource() ? absl::make_optional(options->scrollSource()) + : absl::nullopt; ScrollDirection orientation; if (!StringToScrollDirection(options->orientation(), orientation)) { @@ -139,22 +131,29 @@ ScrollTimeline* ScrollTimeline::Create(Document& document, } absl::optional<double> time_range; - if (options->timeRange().IsDouble()) { - time_range = absl::make_optional(options->timeRange().GetAsDouble()); + if (options->timeRange()->IsDouble()) { + time_range = absl::make_optional(options->timeRange()->GetAsDouble()); } + // The scrollingElement depends on style/layout-tree in quirks mode. Update + // such that subsequent calls to ScrollingElementNoLayout returns up-to-date + // information. + if (document.InQuirksMode()) + document.UpdateStyleAndLayoutTree(); + return MakeGarbageCollected<ScrollTimeline>( &document, scroll_source, orientation, scroll_offsets, time_range); } ScrollTimeline::ScrollTimeline( Document* document, - Element* scroll_source, + absl::optional<Element*> scroll_source, ScrollDirection orientation, HeapVector<Member<ScrollTimelineOffset>> scroll_offsets, absl::optional<double> time_range) : AnimationTimeline(document), - scroll_source_(scroll_source), + scroll_source_( + scroll_source.value_or(document->ScrollingElementNoLayout())), resolved_scroll_source_(ResolveScrollSource(scroll_source_)), orientation_(orientation), scroll_offsets_(std::move(scroll_offsets)), @@ -289,15 +288,20 @@ bool ScrollTimeline::ScrollOffsetsEqual( const HeapVector<Member<ScrollTimelineOffset>>& other) const { if (scroll_offsets_.size() != other.size()) return false; - size_t size = scroll_offsets_.size(); - for (size_t i = 0; i < size; ++i) { + wtf_size_t size = scroll_offsets_.size(); + for (wtf_size_t i = 0; i < size; ++i) { if (!DataEquivalent(scroll_offsets_.at(i), other.at(i))) return false; } return true; } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) +V8CSSNumberish* ScrollTimeline::ConvertTimeToProgress( + AnimationTimeDelta time) const { + return MakeGarbageCollected<V8CSSNumberish>( + CSSUnitValues::percent((time / GetDuration().value()) * 100)); +} + V8CSSNumberish* ScrollTimeline::currentTime() { // time returns either in milliseconds or a 0 to 100 value representing the // progress of the timeline @@ -307,7 +311,7 @@ V8CSSNumberish* ScrollTimeline::currentTime() { // We are currently abusing the intended use of the "auto" keyword. We are // using it here as a signal to use progress based timeline instead of having // a range based current time. - // We are doing this maintain backwards compatibility with existing tests. + // We are doing this to maintain backwards compatibility with existing tests. if (time_range_) { // not using progress based, return time as double if (current_time) { @@ -317,55 +321,21 @@ V8CSSNumberish* ScrollTimeline::currentTime() { return nullptr; } else { if (current_time) { - return MakeGarbageCollected<V8CSSNumberish>( - CSSUnitValues::percent(current_time->InSecondsF())); + return ConvertTimeToProgress(AnimationTimeDelta(current_time.value())); } return nullptr; } } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void ScrollTimeline::currentTime(CSSNumberish& currentTime) { - // time returns either in milliseconds or a 0 to 100 value representing the - // progress of the timeline - auto current_time = timeline_state_snapshotted_.current_time; - // TODO(crbug.com/1140602): Support progress based animations - // We are currently abusing the intended use of the "auto" keyword. We are - // using it here as a signal to use progress based timeline instead of having - // a range based current time. - // We are doing this maintain backwards compatibility with existing tests. - if (time_range_) { - // not using progress based, return time as double - currentTime = - current_time ? CSSNumberish::FromDouble(current_time->InMillisecondsF()) - : CSSNumberish(); - } else { - currentTime = current_time - ? CSSNumberish::FromCSSNumericValue( - CSSUnitValues::percent(current_time->InSecondsF())) - : CSSNumberish(); - } -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* ScrollTimeline::duration() { + // TODO (crbug.com/1216655): Time range should be removed from ScrollTimeline. + // Currently still left in for the sake of backwards compatibility with + // existing tests. if (time_range_) { return MakeGarbageCollected<V8CSSNumberish>(time_range_.value()); } - return MakeGarbageCollected<V8CSSNumberish>( - CSSUnitValues::percent(kScrollTimelineDuration)); + return MakeGarbageCollected<V8CSSNumberish>(CSSUnitValues::percent(100)); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void ScrollTimeline::duration(CSSNumberish& duration) { - if (time_range_) { - duration = CSSNumberish::FromDouble(time_range_.value()); - } else { - duration = CSSNumberish::FromCSSNumericValue( - CSSUnitValues::percent(kScrollTimelineDuration)); - } -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // https://drafts.csswg.org/scroll-animations-1/#current-time-algorithm ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { @@ -409,8 +379,12 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { return {TimelinePhase::kBefore, base::TimeDelta(), resolved_offsets}; } - double duration = - time_range_ ? time_range_.value() : kScrollTimelineDurationMs; + // TODO (crbug.com/1216655): Time range should be removed from ScrollTimeline. + // Currently still left in for the sake of backwards compatibility with + // existing tests. + base::TimeDelta duration = + time_range_ ? base::TimeDelta::FromMillisecondsD(time_range_.value()) + : base::TimeDelta::FromSecondsD(GetDuration()->InSecondsF()); // 3.2 If current scroll offset is greater than or equal to effective end // offset: @@ -421,8 +395,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { // after phase. TimelinePhase phase = end_offset >= max_offset ? TimelinePhase::kActive : TimelinePhase::kAfter; - return {phase, base::TimeDelta::FromMillisecondsD(duration), - resolved_offsets}; + return {phase, duration, resolved_offsets}; } // 3.3 Otherwise, @@ -434,7 +407,7 @@ ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const { absl::optional<base::TimeDelta> calculated_current_time = base::TimeDelta::FromMillisecondsD(scroll_timeline_util::ComputeProgress( current_offset, resolved_offsets) * - duration); + duration.InMillisecondsF()); return {TimelinePhase::kActive, calculated_current_time, resolved_offsets}; } @@ -444,6 +417,24 @@ ScrollTimeline::InitialStartTimeForAnimations() { return base::TimeDelta(); } +AnimationTimeDelta ScrollTimeline::CalculateIntrinsicIterationDuration( + const Timing& timing) { + absl::optional<AnimationTimeDelta> duration = GetDuration(); + + // Only run calculation for progress based scroll timelines + if (duration) { + // if iteration_duration == "auto" and iterations > 0 + if (!timing.iteration_duration && timing.iteration_count > 0) { + // duration represents 100% so we divide it by iteration count to + // calculate the iteration duration. TODO: (crbug.com/1216527) Once + // delays can be percentages we will include them in the calculation: + // ((100% - start_delay% - end_delay%) / iterations) * duration + return duration.value() / timing.iteration_count; + } + } + return AnimationTimeDelta(); +} + void ScrollTimeline::ServiceAnimations(TimingUpdateReason reason) { // Snapshot timeline state once at top of animation frame. if (reason == kTimingUpdateForAnimationFrame) @@ -500,7 +491,6 @@ String ScrollTimeline::orientation() { } } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const HeapVector<Member<V8ScrollTimelineOffset>> ScrollTimeline::scrollOffsets() const { HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets; @@ -511,20 +501,7 @@ const HeapVector<Member<V8ScrollTimelineOffset>> ScrollTimeline::scrollOffsets() } return scroll_offsets; } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets() - const { - HeapVector<ScrollTimelineOffsetValue> scroll_offsets; - for (auto& offset : scroll_offsets_) { - scroll_offsets.push_back(offset->ToScrollTimelineOffsetValue()); - // 'auto' can only be the end offset. - DCHECK(!offset->IsDefaultValue() || scroll_offsets.size() == 2); - } - return scroll_offsets; -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8UnionDoubleOrScrollTimelineAutoKeyword* ScrollTimeline::timeRange() const { // TODO(crbug.com/1140602): Support progress based animations // We are currently abusing the intended use of the "auto" keyword. We are @@ -538,20 +515,6 @@ V8UnionDoubleOrScrollTimelineAutoKeyword* ScrollTimeline::timeRange() const { return MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( V8ScrollTimelineAutoKeyword(V8ScrollTimelineAutoKeyword::Enum::kAuto)); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) { - // TODO(crbug.com/1140602): Support progress based animations - // We are currently abusing the intended use of the "auto" keyword. We are - // using it here as a signal to use progress based timeline instead of having - // a range based current time. - // We are doing this maintain backwards compatibility with existing tests. - if (time_range_) { - result.SetDouble(time_range_.value()); - } else { - result.SetScrollTimelineAutoKeyword("auto"); - } -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box, double& current_offset, diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h index 7c5a2fc7c72..0fb0db92843 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h @@ -15,7 +15,6 @@ namespace blink { -class DoubleOrScrollTimelineAutoKeyword; class ScrollTimelineOptions; class V8UnionDoubleOrScrollTimelineAutoKeyword; @@ -44,17 +43,23 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ExceptionState&); ScrollTimeline(Document*, - Element*, + absl::optional<Element*> scroll_source, ScrollDirection, HeapVector<Member<ScrollTimelineOffset>>, absl::optional<double>); bool IsScrollTimeline() const override { return true; } + // TODO (crbug.com/1216655): Time range should be removed from ScrollTimeline + // at which point this function becomes redundant as all scroll timelines will + // then be progress based timelines. + bool IsProgressBasedTimeline() const override { return !time_range_; } // ScrollTimeline is not active if scrollSource is null, does not currently // have a CSS layout box, or if its layout box is not a scroll container. // https://github.com/WICG/scroll-animations/issues/31 bool IsActive() const override; absl::optional<base::TimeDelta> InitialStartTimeForAnimations() override; + AnimationTimeDelta CalculateIntrinsicIterationDuration( + const Timing&) override; AnimationTimeDelta ZeroTime() override { return AnimationTimeDelta(); } void ServiceAnimations(TimingUpdateReason) override; @@ -63,21 +68,12 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { // IDL API implementation. Element* scrollSource() const; String orientation(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) const HeapVector<Member<V8ScrollTimelineOffset>> scrollOffsets() const; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - const HeapVector<ScrollTimelineOffsetValue> scrollOffsets() const; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8CSSNumberish* currentTime() override; V8CSSNumberish* duration() override; V8UnionDoubleOrScrollTimelineAutoKeyword* timeRange() const; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - void currentTime(CSSNumberish&) override; - void duration(CSSNumberish&) override; - void timeRange(DoubleOrScrollTimelineAutoKeyword&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) + V8CSSNumberish* ConvertTimeToProgress(AnimationTimeDelta time) const; // Returns the Node that should actually have the ScrollableArea (if one // exists). This can differ from |scrollSource| when |scroll_source_| is the @@ -128,9 +124,22 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { // overflow, adding and removal of scrollable area. static void Invalidate(Node* node); + // TODO (crbug.com/1216655): Time range should be removed from ScrollTimeline. + // Currently still left in for the sake of backwards compatibility with + // existing tests. + double GetTimeRange() const { return time_range_ ? time_range_.value() : 0; } + + // Duration is the maximum value a timeline may generate for current time. + // Used to convert time values to proportional values. + absl::optional<AnimationTimeDelta> GetDuration() const override { + return time_range_ + ? absl::nullopt + // Any arbitrary value should be able to be used here. + : absl::make_optional(AnimationTimeDelta::FromSecondsD(100)); + } + protected: PhaseAndTime CurrentPhaseAndTime() override; - double GetTimeRange() const { return time_range_ ? time_range_.value() : 0; } bool ScrollOffsetsEqual( const HeapVector<Member<ScrollTimelineOffset>>& other) const; @@ -179,6 +188,9 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ScrollDirection orientation_; HeapVector<Member<ScrollTimelineOffset>> scroll_offsets_; + // TODO (crbug.com/1216655): Time range should be removed from ScrollTimeline. + // Currently still left in for the sake of backwards compatibility with + // existing tests. absl::optional<double> time_range_; // Snapshotted value produced by the last SnapshotState call. diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc index 4e4d8405464..dc38a92cd3d 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/renderer/bindings/core/v8/css_numeric_value_or_string_or_css_keyword_value_or_scroll_timeline_element_based_offset.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -22,7 +21,8 @@ namespace blink { namespace { -bool ValidateElementBasedOffset(ScrollTimelineElementBasedOffset* offset) { +bool ValidateElementBasedOffset( + const ScrollTimelineElementBasedOffset* offset) { if (!offset->hasTarget()) return false; @@ -66,45 +66,45 @@ bool ElementBasedOffsetsEqual(ScrollTimelineElementBasedOffset* o1, o1->threshold() == o2->threshold(); } -CSSKeywordValue* GetCSSKeywordValue(const ScrollTimelineOffsetValue& offset) { - if (offset.IsCSSKeywordValue()) - return offset.GetAsCSSKeywordValue(); - // CSSKeywordish: - if (offset.IsString() && !offset.GetAsString().IsEmpty()) - return CSSKeywordValue::Create(offset.GetAsString()); - return nullptr; -} - } // namespace // static ScrollTimelineOffset* ScrollTimelineOffset::Create( - const ScrollTimelineOffsetValue& input_offset) { - if (input_offset.IsCSSNumericValue()) { - auto* numeric = input_offset.GetAsCSSNumericValue(); - const auto& offset = To<CSSPrimitiveValue>(*numeric->ToCSSValue()); - bool matches_length_percentage = offset.IsLength() || - offset.IsPercentage() || - offset.IsCalculatedPercentageWithLength(); - if (!matches_length_percentage) - return nullptr; - return MakeGarbageCollected<ScrollTimelineOffset>(&offset); - } - - if (input_offset.IsScrollTimelineElementBasedOffset()) { - auto* offset = input_offset.GetAsScrollTimelineElementBasedOffset(); - if (!ValidateElementBasedOffset(offset)) - return nullptr; - - return MakeGarbageCollected<ScrollTimelineOffset>(offset); - } - - if (auto* keyword = GetCSSKeywordValue(input_offset)) { - if (keyword->KeywordValueID() != CSSValueID::kAuto) - return nullptr; - return MakeGarbageCollected<ScrollTimelineOffset>(); + const V8ScrollTimelineOffset* offset) { + switch (offset->GetContentType()) { + case V8ScrollTimelineOffset::ContentType::kCSSKeywordValue: { + const auto* keyword = offset->GetAsCSSKeywordValue(); + if (keyword->KeywordValueID() != CSSValueID::kAuto) + return nullptr; + return MakeGarbageCollected<ScrollTimelineOffset>(); + } + case V8ScrollTimelineOffset::ContentType::kCSSNumericValue: { + const auto* value = + To<CSSPrimitiveValue>(offset->GetAsCSSNumericValue()->ToCSSValue()); + bool matches_length_percentage = + value->IsLength() || value->IsPercentage() || + value->IsCalculatedPercentageWithLength(); + if (!matches_length_percentage) + return nullptr; + return MakeGarbageCollected<ScrollTimelineOffset>(value); + } + case V8ScrollTimelineOffset::ContentType:: + kScrollTimelineElementBasedOffset: { + auto* value = offset->GetAsScrollTimelineElementBasedOffset(); + if (!ValidateElementBasedOffset(value)) + return nullptr; + return MakeGarbageCollected<ScrollTimelineOffset>(value); + } + case V8ScrollTimelineOffset::ContentType::kString: { + if (offset->GetAsString().IsEmpty()) + return nullptr; + const auto* keyword = CSSKeywordValue::Create(offset->GetAsString()); + if (keyword->KeywordValueID() != CSSValueID::kAuto) + return nullptr; + return MakeGarbageCollected<ScrollTimelineOffset>(); + } } - + NOTREACHED(); return nullptr; } @@ -125,9 +125,10 @@ absl::optional<double> ScrollTimelineOffset::ResolveOffset( ? document.documentElement()->GetComputedStyle() : document.GetComputedStyle(); + // TOOD(crbug.com/1223030): Handle container relative units. CSSToLengthConversionData conversion_data = CSSToLengthConversionData( &computed_style, root_style, document.GetLayoutView(), - computed_style.EffectiveZoom()); + /* nearest_container */ nullptr, computed_style.EffectiveZoom()); double resolved = FloatValueForLength( length_based_offset_->ConvertToLength(conversion_data), max_offset); @@ -210,7 +211,6 @@ absl::optional<double> ScrollTimelineOffset::ResolveOffset( } } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8ScrollTimelineOffset* ScrollTimelineOffset::ToV8ScrollTimelineOffset() const { if (length_based_offset_) { return MakeGarbageCollected<V8ScrollTimelineOffset>( @@ -222,23 +222,6 @@ V8ScrollTimelineOffset* ScrollTimelineOffset::ToV8ScrollTimelineOffset() const { return MakeGarbageCollected<V8ScrollTimelineOffset>( CSSKeywordValue::Create("auto")); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -ScrollTimelineOffsetValue ScrollTimelineOffset::ToScrollTimelineOffsetValue() - const { - ScrollTimelineOffsetValue result; - if (length_based_offset_) { - result.SetCSSNumericValue( - CSSNumericValue::FromCSSValue(*length_based_offset_.Get())); - } else if (element_based_offset_) { - result.SetScrollTimelineElementBasedOffset(element_based_offset_); - } else { - // This is the default value (i.e., 'auto' value) - result.SetCSSKeywordValue(CSSKeywordValue::Create("auto")); - } - - return result; -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool ScrollTimelineOffset::operator==(const ScrollTimelineOffset& o) const { return DataEquivalent(length_based_offset_, o.length_based_offset_) && diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h index 5cf0c9e4611..55ba05de76d 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_OFFSET_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_OFFSET_H_ +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h" #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" #include "third_party/blink/renderer/core/css/css_style_sheet.h" @@ -13,18 +14,12 @@ namespace blink { -class - CSSNumericValueOrStringOrCSSKeywordValueOrScrollTimelineElementBasedOffset; - -using ScrollTimelineOffsetValue = - CSSNumericValueOrStringOrCSSKeywordValueOrScrollTimelineElementBasedOffset; - // Represent a scroll timeline start/end offset which can be an // scroll offset or an element based offset class CORE_EXPORT ScrollTimelineOffset final : public GarbageCollected<ScrollTimelineOffset> { public: - static ScrollTimelineOffset* Create(const ScrollTimelineOffsetValue& offset); + static ScrollTimelineOffset* Create(const V8ScrollTimelineOffset* offset); // Create a default offset representing 'auto'. ScrollTimelineOffset() = default; @@ -53,11 +48,7 @@ class CORE_EXPORT ScrollTimelineOffset final double max_offset, double default_offset); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) V8ScrollTimelineOffset* ToV8ScrollTimelineOffset() const; -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - ScrollTimelineOffsetValue ToScrollTimelineOffsetValue() const; -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) bool IsDefaultValue() const { return !length_based_offset_ && !element_based_offset_; } diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset_test.cc index fb883616c30..41b620e3bb5 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_offset_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h" #include "third_party/blink/renderer/core/css/parser/css_parser_context.h" @@ -27,8 +28,7 @@ class ScrollTimelineOffsetTest : public PageTestBase { auto* inner = CreateElementBasedOffset(target, edge, threshold); if (!inner) return nullptr; - ScrollTimelineOffsetValue param; - param.SetScrollTimelineElementBasedOffset(inner); + auto* param = MakeGarbageCollected<V8ScrollTimelineOffset>(inner); return ScrollTimelineOffset::Create(param); } diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc index bdc9d1c9dd8..a126710d7d0 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc @@ -6,6 +6,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/core/animation/document_animations.h" #include "third_party/blink/renderer/core/animation/keyframe_effect.h" @@ -91,7 +93,7 @@ class ScrollTimelineTest : public RenderingTest { return count; } - ScrollTimelineOffsetValue OffsetFromString(const String& value) { + V8ScrollTimelineOffset* OffsetFromString(const String& value) { return animation_test_helpers::OffsetFromString(GetDocument(), value); } }; @@ -134,8 +136,8 @@ TEST_F(ScrollTimelineTest, CurrentTimeIsNullIfScrollSourceIsNotScrollable) { ASSERT_TRUE(scroller); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); ScrollTimeline* scroll_timeline = @@ -164,8 +166,8 @@ TEST_F(ScrollTimelineTest, PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); ASSERT_TRUE(scrollable_area); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); options->setScrollOffsets( @@ -173,7 +175,6 @@ TEST_F(ScrollTimelineTest, ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - bool current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 5), mojom::blink::ScrollType::kProgrammatic); // Simulate a new animation frame which allows the timeline to compute new @@ -182,34 +183,30 @@ TEST_F(ScrollTimelineTest, EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 0); EXPECT_EQ("before", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 10), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 0); EXPECT_EQ("active", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), 50); EXPECT_EQ("active", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 90), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), - time_range.GetAsDouble()); + time_range->GetAsDouble()); EXPECT_EQ("after", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); EXPECT_EQ(scroll_timeline->CurrentTimeMilliseconds(), - time_range.GetAsDouble()); + time_range->GetAsDouble()); EXPECT_EQ("after", scroll_timeline->phase()); EXPECT_TRUE(scroll_timeline->IsActive()); } @@ -233,8 +230,8 @@ TEST_F(ScrollTimelineTest, PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); ASSERT_TRUE(scrollable_area); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); options->setScrollOffsets( @@ -242,7 +239,6 @@ TEST_F(ScrollTimelineTest, ScrollTimeline* scroll_timeline = ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION); - bool current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic); // Simulate a new animation frame which allows the timeline to compute new @@ -251,18 +247,16 @@ TEST_F(ScrollTimelineTest, EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("before", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 60), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); EXPECT_EQ(0, scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("before", scroll_timeline->phase()); - current_time_is_null = true; scrollable_area->SetScrollOffset(ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic); SimulateFrame(); - EXPECT_EQ(time_range.GetAsDouble(), + EXPECT_EQ(time_range->GetAsDouble(), scroll_timeline->CurrentTimeMilliseconds()); EXPECT_EQ("after", scroll_timeline->phase()); EXPECT_TRUE(scroll_timeline->IsActive()); @@ -286,8 +280,8 @@ TEST_F(ScrollTimelineTest, PhasesAreCorrectWhenUsingOffsets) { PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); ASSERT_TRUE(scrollable_area); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); options->setScrollOffsets( @@ -333,8 +327,8 @@ TEST_F(ScrollTimelineTest, // Create the ScrollTimeline with Document.scrollingElement() as source. The // resolved scroll source should be the Document. ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetDocument().scrollingElement()); ScrollTimeline* scroll_timeline = @@ -359,8 +353,8 @@ TEST_F(ScrollTimelineTest, // Create the ScrollTimeline with Document.scrollingElement() as source. The // resolved scroll source should be the Document. ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetDocument().scrollingElement()); ScrollTimeline* scroll_timeline = @@ -724,8 +718,8 @@ TEST_F(ScrollTimelineTest, CurrentTimeUpdateAfterNewAnimationFrame) { PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea(); ASSERT_TRUE(scrollable_area); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(GetElementById("scroller")); @@ -934,10 +928,11 @@ TEST_F(ScrollTimelineTest, ResolveScrollOffsets) { double time_range = 100.0; ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); options->setTimeRange( - DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + time_range)); options->setScrollSource(GetElementById("scroller")); // Empty scroll offsets resolve into [0, 100%]. - HeapVector<ScrollTimelineOffsetValue> scroll_offsets = {}; + HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets = {}; options->setScrollOffsets(scroll_offsets); ScrollTimeline* scroll_timeline = @@ -1001,9 +996,10 @@ TEST_F(ScrollTimelineTest, MultipleScrollOffsetsCurrentTimeCalculations) { double time_range = 100.0; ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); options->setTimeRange( - DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + time_range)); options->setScrollSource(GetElementById("scroller")); - HeapVector<ScrollTimelineOffsetValue> scroll_offsets; + HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets; scroll_offsets.push_back(OffsetFromString("10px")); scroll_offsets.push_back(OffsetFromString("20px")); scroll_offsets.push_back(OffsetFromString("40px")); @@ -1092,9 +1088,10 @@ TEST_F(ScrollTimelineTest, OverlappingScrollOffsets) { double time_range = 100.0; ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); options->setTimeRange( - DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + time_range)); options->setScrollSource(GetElementById("scroller")); - HeapVector<ScrollTimelineOffsetValue> scroll_offsets = { + HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets = { OffsetFromString("90px"), OffsetFromString("40px"), OffsetFromString("10px")}; options->setScrollOffsets(scroll_offsets); diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc index 714034716e1..a33ffa18b67 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc @@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h" -#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_timeline.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" @@ -26,16 +25,6 @@ scoped_refptr<CompositorScrollTimeline> ToCompositorScrollTimeline( absl::optional<CompositorElementId> element_id = GetCompositorScrollElementId(scroll_source); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - auto* time_range = scroll_timeline->timeRange(); - DCHECK(time_range); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - DoubleOrScrollTimelineAutoKeyword time_range; - scroll_timeline->timeRange(time_range); - // TODO(smcgruer): Handle 'auto' time range value. - DCHECK(time_range.IsDouble()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - LayoutBox* box = scroll_timeline->IsActive() ? scroll_source->GetLayoutBox() : nullptr; @@ -44,12 +33,7 @@ scoped_refptr<CompositorScrollTimeline> ToCompositorScrollTimeline( return CompositorScrollTimeline::Create( element_id, orientation, scroll_timeline->GetResolvedScrollOffsets(), -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - time_range->GetAsDouble() -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - time_range.GetAsDouble() -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - ); + scroll_timeline->GetTimeRange()); } absl::optional<CompositorElementId> GetCompositorScrollElementId( diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc index 223443d5116..8f111114fde 100644 --- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc @@ -6,8 +6,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h" #include "third_party/blink/renderer/core/animation/animation_test_helpers.h" #include "third_party/blink/renderer/core/animation/document_timeline.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -61,7 +64,8 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimeline) { options->setScrollSource(scroller); const double time_range = 100; options->setTimeRange( - DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range)); + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>( + time_range)); options->setOrientation("block"); options->setScrollOffsets({OffsetFromString(GetDocument(), "50px"), OffsetFromString(GetDocument(), "auto")}); @@ -115,8 +119,8 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullLayoutBox) { ASSERT_FALSE(div->GetLayoutBox()); ScrollTimelineOptions* options = ScrollTimelineOptions::Create(); - DoubleOrScrollTimelineAutoKeyword time_range = - DoubleOrScrollTimelineAutoKeyword::FromDouble(100); + auto* time_range = + MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(100); options->setTimeRange(time_range); options->setScrollSource(div); ScrollTimeline* timeline = diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc index 4503d3bb652..f0db35c5666 100644 --- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc +++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc @@ -19,17 +19,6 @@ namespace blink { namespace { -// Returns handle for the given CSSProperty. -// |value| is required only for custom properties. -PropertyHandle ToPropertyHandle(const CSSProperty& property, - const CSSValue* value) { - if (property.IDEquals(CSSPropertyID::kVariable)) { - return PropertyHandle(To<CSSCustomPropertyDeclaration>(*value).GetName()); - } else { - return PropertyHandle(property, false); - } -} - bool IsLogicalProperty(CSSPropertyID property_id) { const CSSProperty& property = CSSProperty::Get(property_id); const CSSProperty& resolved_property = property.ResolveDirectionAwareProperty( @@ -135,15 +124,20 @@ MutableCSSPropertyValueSet::SetResult StringKeyframe::SetCSSPropertyValue( return result; } -void StringKeyframe::SetCSSPropertyValue(const CSSProperty& property, +void StringKeyframe::SetCSSPropertyValue(const CSSPropertyName& name, const CSSValue& value) { - CSSPropertyID property_id = property.PropertyID(); + CSSPropertyID property_id = name.Id(); DCHECK_NE(property_id, CSSPropertyID::kInvalid); - DCHECK(!CSSAnimations::IsAnimationAffectingProperty(property)); - DCHECK(!property.IsShorthand()); +#if DCHECK_IS_ON() + if (property_id != CSSPropertyID::kVariable) { + const CSSProperty& property = CSSProperty::Get(property_id); + DCHECK(!CSSAnimations::IsAnimationAffectingProperty(property)); + DCHECK(!property.IsShorthand()); + } +#endif // DCHECK_IS_ON() DCHECK(!IsLogicalProperty(property_id)); input_properties_.Set( - ToPropertyHandle(property, &value), + PropertyHandle(name), MakeGarbageCollected<PropertyResolver>(property_id, value)); InvalidateCssPropertyMap(); } @@ -181,12 +175,12 @@ PropertyHandleSet StringKeyframe::Properties() const { for (unsigned i = 0; i < css_property_map_->PropertyCount(); ++i) { CSSPropertyValueSet::PropertyReference property_reference = css_property_map_->PropertyAt(i); - // TODO(crbug.com/980160): Remove access to static Variable instance. - const CSSProperty& property = CSSProperty::Get(property_reference.Id()); - DCHECK(!property.IsShorthand()) + const CSSPropertyName& name = property_reference.Name(); + DCHECK(!name.IsCustomProperty() || + !CSSProperty::Get(name.Id()).IsShorthand()) << "Web Animations: Encountered unexpanded shorthand CSS property (" - << static_cast<int>(property.PropertyID()) << ")."; - properties.insert(ToPropertyHandle(property, &property_reference.Value())); + << static_cast<int>(name.Id()) << ")."; + properties.insert(PropertyHandle(name)); } for (unsigned i = 0; i < presentation_attribute_map_->PropertyCount(); ++i) { diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h index a46dbc5e87a..7928e8cbe41 100644 --- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h +++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h @@ -12,6 +12,7 @@ namespace blink { +class CSSPropertyName; class StyleSheetContents; // An implementation of Keyframe used for CSS Animations, web-animations, and @@ -41,7 +42,7 @@ class CORE_EXPORT StringKeyframe : public Keyframe { const String& value, SecureContextMode, StyleSheetContents*); - void SetCSSPropertyValue(const CSSProperty&, const CSSValue&); + void SetCSSPropertyValue(const CSSPropertyName&, const CSSValue&); void RemoveCustomCSSProperty(const PropertyHandle& property); void SetPresentationAttributeValue(const CSSProperty&, diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html b/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html index 22e197dc79d..4e4fec2df0e 100644 --- a/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html +++ b/chromium/third_party/blink/renderer/core/animation/test_data/scale-animation.html @@ -8,6 +8,9 @@ .animate { animation-name: test; animation-duration: 1s; + width: 10px; + height: 10px; + background: green; } </style> <div id="target" class="animate">TARGET</div> diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation-update.html b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation-update.html index 4f011a80917..399e3bf576d 100644 --- a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation-update.html +++ b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation-update.html @@ -7,6 +7,7 @@ #target { width: 100px; height: 100px; + background: green; animation: rotate 9999s linear 0s infinite; } .backface-visible { diff --git a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html index 9bfccc43f9a..33d682b33b4 100644 --- a/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html +++ b/chromium/third_party/blink/renderer/core/animation/test_data/transform-animation.html @@ -8,6 +8,9 @@ .animate { animation-name: test; animation-duration: 1s; + width: 10px; + height: 10px; + background: green; } </style> <div id="target" class="animate">TARGET</div> diff --git a/chromium/third_party/blink/renderer/core/animation/timing.cc b/chromium/third_party/blink/renderer/core/animation/timing.cc index c1cec54438f..5138547f32e 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing.cc @@ -6,8 +6,10 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/timing_calculations.h" -#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" +#include "third_party/blink/renderer/core/css/cssom/css_unit_values.h" namespace blink { @@ -66,39 +68,21 @@ Timing::FillMode Timing::ResolvedFillMode(bool is_keyframe_effect) const { return Timing::FillMode::BOTH; } -AnimationTimeDelta Timing::IterationDuration() const { - AnimationTimeDelta result = iteration_duration.value_or(AnimationTimeDelta()); - DCHECK_GE(result, AnimationTimeDelta()); - return result; -} - -AnimationTimeDelta Timing::ActiveDuration() const { - const AnimationTimeDelta result = - MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_count); - DCHECK_GE(result, AnimationTimeDelta()); - return result; -} - -AnimationTimeDelta Timing::EndTimeInternal() const { - // Per the spec, the end time has a lower bound of 0.0: - // https://drafts.csswg.org/web-animations-1/#end-time - return std::max(start_delay + ActiveDuration() + end_delay, - AnimationTimeDelta()); -} - EffectTiming* Timing::ConvertToEffectTiming() const { EffectTiming* effect_timing = EffectTiming::Create(); + // Specified values used here so that inputs match outputs for JS API calls effect_timing->setDelay(start_delay.InMillisecondsF()); effect_timing->setEndDelay(end_delay.InMillisecondsF()); effect_timing->setFill(FillModeString(fill_mode)); effect_timing->setIterationStart(iteration_start); effect_timing->setIterations(iteration_count); - UnrestrictedDoubleOrString duration; + V8UnionStringOrUnrestrictedDouble* duration; if (iteration_duration) { - duration.SetUnrestrictedDouble(iteration_duration->InMillisecondsF()); + duration = MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( + iteration_duration->InMillisecondsF()); } else { - duration.SetString("auto"); + duration = MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>("auto"); } effect_timing->setDuration(duration); effect_timing->setDirection(PlaybackDirectionString(direction)); @@ -107,23 +91,38 @@ EffectTiming* Timing::ConvertToEffectTiming() const { return effect_timing; } +// Converts values to CSSNumberish based on corresponding timeline type +V8CSSNumberish* Timing::ToComputedValue( + absl::optional<AnimationTimeDelta> time, + absl::optional<AnimationTimeDelta> max_time) const { + if (time) { + // A valid timeline_duration indicates use of progress based timeline. We + // need to convert values to percentages using timeline_duration as 100% + if (max_time) { + return MakeGarbageCollected<V8CSSNumberish>( + CSSUnitValues::percent((time.value() / max_time.value()) * 100)); + } else { + // For time based timeline, simply return the value in milliseconds. + return MakeGarbageCollected<V8CSSNumberish>( + time.value().InMillisecondsF()); + } + } + return nullptr; +} + ComputedEffectTiming* Timing::getComputedTiming( const CalculatedTiming& calculated_timing, + const NormalizedTiming& normalized_timing, bool is_keyframe_effect) const { ComputedEffectTiming* computed_timing = ComputedEffectTiming::Create(); // ComputedEffectTiming members. - computed_timing->setEndTime( - CSSNumberish::FromDouble(EndTimeInternal().InMillisecondsF())); - computed_timing->setActiveDuration( - CSSNumberish::FromDouble(ActiveDuration().InMillisecondsF())); - - if (calculated_timing.local_time) { - computed_timing->setLocalTime(CSSNumberish::FromDouble( - calculated_timing.local_time->InMillisecondsF())); - } else { - computed_timing->setLocalTime(CSSNumberish()); - } + computed_timing->setEndTime(ToComputedValue( + normalized_timing.end_time, normalized_timing.timeline_duration)); + computed_timing->setActiveDuration(ToComputedValue( + normalized_timing.active_duration, normalized_timing.timeline_duration)); + computed_timing->setLocalTime(ToComputedValue( + calculated_timing.local_time, normalized_timing.timeline_duration)); if (calculated_timing.is_in_effect) { DCHECK(calculated_timing.current_iteration); @@ -132,14 +131,17 @@ ComputedEffectTiming* Timing::getComputedTiming( computed_timing->setCurrentIteration( calculated_timing.current_iteration.value()); } else { - computed_timing->setProgressToNull(); - computed_timing->setCurrentIterationToNull(); + computed_timing->setProgress(absl::nullopt); + computed_timing->setCurrentIteration(absl::nullopt); } // For the EffectTiming members, getComputedTiming is equivalent to getTiming // except that the fill and duration must be resolved. // // https://drafts.csswg.org/web-animations-1/#dom-animationeffect-getcomputedtiming + + // TODO(crbug.com/1216527): Animation effect timing members start_delay and + // end_delay should be CSSNumberish computed_timing->setDelay(start_delay.InMillisecondsF()); computed_timing->setEndDelay(end_delay.InMillisecondsF()); computed_timing->setFill( @@ -147,9 +149,22 @@ ComputedEffectTiming* Timing::getComputedTiming( computed_timing->setIterationStart(iteration_start); computed_timing->setIterations(iteration_count); - UnrestrictedDoubleOrString duration; - duration.SetUnrestrictedDouble(IterationDuration().InMillisecondsF()); - computed_timing->setDuration(duration); + // TODO(crbug.com/1219008): Animation effect computed iteration_duration + // should return CSSNumberish, which will simplify this logic. + V8CSSNumberish* computed_duration = + ToComputedValue(normalized_timing.iteration_duration, + normalized_timing.timeline_duration); + if (computed_duration->IsCSSNumericValue()) { + computed_timing->setDuration( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( + computed_duration->GetAsCSSNumericValue() + ->to(CSSPrimitiveValue::UnitType::kPercentage) + ->value())); + } else { + computed_timing->setDuration( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( + computed_duration->GetAsDouble())); + } computed_timing->setDirection(Timing::PlaybackDirectionString(direction)); computed_timing->setEasing(timing_function->ToString()); @@ -160,23 +175,24 @@ ComputedEffectTiming* Timing::getComputedTiming( Timing::CalculatedTiming Timing::CalculateTimings( absl::optional<AnimationTimeDelta> local_time, absl::optional<Phase> timeline_phase, + const NormalizedTiming& normalized_timing, AnimationDirection animation_direction, bool is_keyframe_effect, absl::optional<double> playback_rate) const { - const AnimationTimeDelta active_duration = ActiveDuration(); + const AnimationTimeDelta active_duration = normalized_timing.active_duration; + const AnimationTimeDelta duration = normalized_timing.iteration_duration; Timing::Phase current_phase = CalculatePhase( - active_duration, local_time, timeline_phase, animation_direction, *this); + normalized_timing, local_time, timeline_phase, animation_direction); - const absl::optional<AnimationTimeDelta> active_time = - CalculateActiveTime(active_duration, ResolvedFillMode(is_keyframe_effect), - local_time, current_phase, *this); + const absl::optional<AnimationTimeDelta> active_time = CalculateActiveTime( + normalized_timing, ResolvedFillMode(is_keyframe_effect), local_time, + current_phase); absl::optional<double> progress; - const absl::optional<double> overall_progress = - CalculateOverallProgress(current_phase, active_time, IterationDuration(), - iteration_count, iteration_start); + const absl::optional<double> overall_progress = CalculateOverallProgress( + current_phase, active_time, duration, iteration_count, iteration_start); const absl::optional<double> simple_iteration_progress = CalculateSimpleIterationProgress(current_phase, overall_progress, iteration_start, active_time, @@ -196,20 +212,19 @@ Timing::CalculatedTiming Timing::CalculateTimings( AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); // Conditionally compute the time to next iteration, which is only // applicable if the iteration duration is non-zero. - if (!IterationDuration().is_zero()) { + if (!duration.is_zero()) { const AnimationTimeDelta start_offset = - MultiplyZeroAlwaysGivesZero(IterationDuration(), iteration_start); + MultiplyZeroAlwaysGivesZero(duration, iteration_start); DCHECK_GE(start_offset, AnimationTimeDelta()); const absl::optional<AnimationTimeDelta> offset_active_time = CalculateOffsetActiveTime(active_duration, active_time, start_offset); const absl::optional<AnimationTimeDelta> iteration_time = - CalculateIterationTime(IterationDuration(), active_duration, - offset_active_time, start_offset, current_phase, - *this); + CalculateIterationTime(duration, active_duration, offset_active_time, + start_offset, current_phase, *this); if (iteration_time) { // active_time cannot be null if iteration_time is not null. DCHECK(active_time); - time_to_next_iteration = IterationDuration() - iteration_time.value(); + time_to_next_iteration = duration - iteration_time.value(); if (active_duration - active_time.value() < time_to_next_iteration) time_to_next_iteration = AnimationTimeDelta::Max(); } diff --git a/chromium/third_party/blink/renderer/core/animation/timing.h b/chromium/third_party/blink/renderer/core/animation/timing.h index cb00ec731ed..4ef4abf7811 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing.h +++ b/chromium/third_party/blink/renderer/core/animation/timing.h @@ -34,6 +34,7 @@ #include "base/memory/scoped_refptr.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/animation_time_delta.h" +#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h" #include "third_party/blink/renderer/core/style/data_equivalency.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/animation/timing_function.h" @@ -101,13 +102,6 @@ struct CORE_EXPORT Timing { DCHECK(timing_function); } - // https://drafts.csswg.org/web-animations-1/#iteration-duration - AnimationTimeDelta IterationDuration() const; - - // https://drafts.csswg.org/web-animations-1/#active-duration - AnimationTimeDelta ActiveDuration() const; - AnimationTimeDelta EndTimeInternal() const; - Timing::FillMode ResolvedFillMode(bool is_animation) const; EffectTiming* ConvertToEffectTiming() const; @@ -133,6 +127,10 @@ struct CORE_EXPORT Timing { } bool HasTimingOverrides() { return timing_overrides != kOverrideNode; } + V8CSSNumberish* ToComputedValue(absl::optional<AnimationTimeDelta>, + absl::optional<AnimationTimeDelta>) const; + + // TODO(crbug.com/1216527): Support CSSNumberish delays AnimationTimeDelta start_delay; AnimationTimeDelta end_delay; FillMode fill_mode = FillMode::AUTO; @@ -165,13 +163,31 @@ struct CORE_EXPORT Timing { AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max(); }; + // Normalized values contain specified timing values after normalizing to + // timeline. + struct NormalizedTiming { + DISALLOW_NEW(); + // Value used in normalization math. Stored so that we can convert back if + // needed. + absl::optional<AnimationTimeDelta> timeline_duration; + AnimationTimeDelta start_delay; + AnimationTimeDelta end_delay; + AnimationTimeDelta iteration_duration; + // Calculated as (iteration_duration * iteration_count) + AnimationTimeDelta active_duration; + // Calculated as (start_delay + active_duration + end_delay) + AnimationTimeDelta end_time; + }; + CalculatedTiming CalculateTimings( absl::optional<AnimationTimeDelta> local_time, absl::optional<Phase> timeline_phase, + const NormalizedTiming& normalized_timing, AnimationDirection animation_direction, bool is_keyframe_effect, absl::optional<double> playback_rate) const; ComputedEffectTiming* getComputedTiming(const CalculatedTiming& calculated, + const NormalizedTiming& normalized, bool is_keyframe_effect) const; }; diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h index 56966564ed1..de1059ba672 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h +++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_CALCULATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_TIMING_CALCULATIONS_H_ +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/animation/timing.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -108,20 +109,18 @@ static inline AnimationTimeDelta MultiplyZeroAlwaysGivesZero( // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states static inline Timing::Phase CalculatePhase( - AnimationTimeDelta active_duration, + const Timing::NormalizedTiming& normalized, absl::optional<AnimationTimeDelta> local_time, absl::optional<Timing::Phase> timeline_phase, - Timing::AnimationDirection direction, - const Timing& specified) { - DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + Timing::AnimationDirection direction) { + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(normalized.active_duration, AnimationTimeDelta())); if (!local_time) return Timing::kPhaseNone; - AnimationTimeDelta end_time = - std::max(specified.start_delay + active_duration + specified.end_delay, - AnimationTimeDelta()); + AnimationTimeDelta before_active_boundary_time = - std::max(std::min(specified.start_delay, end_time), AnimationTimeDelta()); + std::max(std::min(normalized.start_delay, normalized.end_time), + AnimationTimeDelta()); if (local_time.value() < before_active_boundary_time || (local_time.value() == before_active_boundary_time && timeline_phase && timeline_phase.value() == Timing::kPhaseBefore) || @@ -130,7 +129,8 @@ static inline Timing::Phase CalculatePhase( return Timing::kPhaseBefore; } AnimationTimeDelta active_after_boundary_time = - std::max(std::min(specified.start_delay + active_duration, end_time), + std::max(std::min(normalized.start_delay + normalized.active_duration, + normalized.end_time), AnimationTimeDelta()); if (local_time > active_after_boundary_time || (local_time.value() == active_after_boundary_time && timeline_phase && @@ -144,33 +144,31 @@ static inline Timing::Phase CalculatePhase( // https://drafts.csswg.org/web-animations/#calculating-the-active-time static inline absl::optional<AnimationTimeDelta> CalculateActiveTime( - AnimationTimeDelta active_duration, + const Timing::NormalizedTiming& normalized, Timing::FillMode fill_mode, absl::optional<AnimationTimeDelta> local_time, - Timing::Phase phase, - const Timing& specified) { - DCHECK(GreaterThanOrEqualToWithinTimeTolerance(active_duration, + Timing::Phase phase) { + DCHECK(GreaterThanOrEqualToWithinTimeTolerance(normalized.active_duration, AnimationTimeDelta())); - switch (phase) { case Timing::kPhaseBefore: if (fill_mode == Timing::FillMode::BACKWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); - return std::max(local_time.value() - specified.start_delay, + return std::max(local_time.value() - normalized.start_delay, AnimationTimeDelta()); } return absl::nullopt; case Timing::kPhaseActive: DCHECK(local_time.has_value()); - return local_time.value() - specified.start_delay; + return local_time.value() - normalized.start_delay; case Timing::kPhaseAfter: if (fill_mode == Timing::FillMode::FORWARDS || fill_mode == Timing::FillMode::BOTH) { DCHECK(local_time.has_value()); return std::max(AnimationTimeDelta(), - std::min(active_duration, - local_time.value() - specified.start_delay)); + std::min(normalized.active_duration, + local_time.value() - normalized.start_delay)); } return absl::nullopt; case Timing::kPhaseNone: diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc index f07595c0f1f..4888dabd89f 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc @@ -36,66 +36,60 @@ namespace blink { TEST(AnimationTimingCalculationsTest, ActiveTime) { - Timing timing; + Timing::NormalizedTiming normalized_timing; // calculateActiveTime( // activeDuration, fillMode, localTime, parentPhase, phase, timing) // Before Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); - EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(20), Timing::FillMode::FORWARDS, - AnimationTimeDelta(), Timing::kPhaseBefore, timing)); - EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::NONE, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); - EXPECT_EQ( - AnimationTimeDelta(), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BACKWARDS, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(20); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, + Timing::FillMode::FORWARDS, + AnimationTimeDelta(), Timing::kPhaseBefore)); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + AnimationTimeDelta(), Timing::kPhaseBefore)); EXPECT_EQ(AnimationTimeDelta(), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BOTH, AnimationTimeDelta(), - Timing::kPhaseBefore, timing)); - timing.start_delay = AnimationTimeDelta::FromSecondsD(-10); + CalculateActiveTime(normalized_timing, Timing::FillMode::BACKWARDS, + AnimationTimeDelta(), Timing::kPhaseBefore)); + EXPECT_EQ(AnimationTimeDelta(), + CalculateActiveTime(normalized_timing, Timing::FillMode::BOTH, + AnimationTimeDelta(), Timing::kPhaseBefore)); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(-10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::BACKWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::BACKWARDS, AnimationTimeDelta::FromSecondsD(-5), - Timing::kPhaseBefore, timing)); + Timing::kPhaseBefore)); // Active Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(20), - Timing::FillMode::FORWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::FORWARDS, AnimationTimeDelta::FromSecondsD(15), - Timing::kPhaseActive, timing)); + Timing::kPhaseActive)); // After Phase - timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.start_delay = AnimationTimeDelta::FromSecondsD(10); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(21); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), - Timing::FillMode::FORWARDS, + CalculateActiveTime(normalized_timing, Timing::FillMode::FORWARDS, AnimationTimeDelta::FromSecondsD(45), - Timing::kPhaseAfter, timing)); + Timing::kPhaseAfter)); EXPECT_EQ(AnimationTimeDelta::FromSecondsD(21), - CalculateActiveTime(AnimationTimeDelta::FromSecondsD(21), - Timing::FillMode::BOTH, + CalculateActiveTime(normalized_timing, Timing::FillMode::BOTH, AnimationTimeDelta::FromSecondsD(45), - Timing::kPhaseAfter, timing)); - EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::BACKWARDS, - AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); + Timing::kPhaseAfter)); EXPECT_FALSE(CalculateActiveTime( - AnimationTimeDelta::FromSecondsD(21), Timing::FillMode::NONE, - AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter, timing)); + normalized_timing, Timing::FillMode::BACKWARDS, + AnimationTimeDelta::FromSecondsD(45), Timing::kPhaseAfter)); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + AnimationTimeDelta::FromSecondsD(45), + Timing::kPhaseAfter)); // None - EXPECT_FALSE(CalculateActiveTime(AnimationTimeDelta::FromSecondsD(32), - Timing::FillMode::NONE, absl::nullopt, - Timing::kPhaseNone, timing)); + normalized_timing.active_duration = AnimationTimeDelta::FromSecondsD(32); + EXPECT_FALSE(CalculateActiveTime(normalized_timing, Timing::FillMode::NONE, + absl::nullopt, Timing::kPhaseNone)); } TEST(AnimationTimingCalculationsTest, OffsetActiveTime) { diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input.cc b/chromium/third_party/blink/renderer/core/animation/timing_input.cc index 90ed70bd569..03009262e42 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_input.cc @@ -4,19 +4,20 @@ #include "third_party/blink/renderer/core/animation/timing_input.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddouble.h" #include "third_party/blink/renderer/core/animation/animation_effect.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" namespace blink { namespace { + Timing::PlaybackDirection ConvertPlaybackDirection(const String& direction) { if (direction == "reverse") return Timing::PlaybackDirection::REVERSE; @@ -29,10 +30,10 @@ Timing::PlaybackDirection ConvertPlaybackDirection(const String& direction) { } absl::optional<AnimationTimeDelta> ConvertIterationDuration( - const UnrestrictedDoubleOrString& duration) { - if (duration.IsUnrestrictedDouble()) { + const V8UnionStringOrUnrestrictedDouble* duration) { + if (duration->IsUnrestrictedDouble()) { return AnimationTimeDelta::FromMillisecondsD( - duration.GetAsUnrestrictedDouble()); + duration->GetAsUnrestrictedDouble()); } return absl::nullopt; } @@ -59,7 +60,6 @@ bool UpdateValueIfChanged(V& lhs, const V& rhs) { } // namespace -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing TimingInput::Convert( const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, Document* document, @@ -81,7 +81,7 @@ Timing TimingInput::Convert( // their default values and duration set to options. EffectTiming* timing_input = EffectTiming::Create(); timing_input->setDuration( - UnrestrictedDoubleOrString::FromUnrestrictedDouble( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( options->GetAsUnrestrictedDouble())); return ConvertEffectTiming(timing_input, document, exception_state); } @@ -89,34 +89,7 @@ Timing TimingInput::Convert( NOTREACHED(); return Timing(); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -Timing TimingInput::Convert( - const UnrestrictedDoubleOrKeyframeEffectOptions& options, - Document* document, - ExceptionState& exception_state) { - if (options.IsNull()) { - return Timing(); - } - - if (options.IsKeyframeEffectOptions()) { - return ConvertEffectTiming(options.GetAsKeyframeEffectOptions(), document, - exception_state); - } - - DCHECK(options.IsUnrestrictedDouble()); - - // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect - // If options is a double, - // Let timing input be a new EffectTiming object with all members set to - // their default values and duration set to options. - EffectTiming* timing_input = EffectTiming::Create(); - timing_input->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble( - options.GetAsUnrestrictedDouble())); - return ConvertEffectTiming(timing_input, document, exception_state); -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing TimingInput::Convert( const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, Document* document, @@ -138,7 +111,7 @@ Timing TimingInput::Convert( // their default values and duration set to options. EffectTiming* timing_input = EffectTiming::Create(); timing_input->setDuration( - UnrestrictedDoubleOrString::FromUnrestrictedDouble( + MakeGarbageCollected<V8UnionStringOrUnrestrictedDouble>( options->GetAsUnrestrictedDouble())); return ConvertEffectTiming(timing_input, document, exception_state); } @@ -146,31 +119,6 @@ Timing TimingInput::Convert( NOTREACHED(); return Timing(); } -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) -Timing TimingInput::Convert( - const UnrestrictedDoubleOrKeyframeAnimationOptions& options, - Document* document, - ExceptionState& exception_state) { - if (options.IsNull()) - return Timing(); - - if (options.IsKeyframeAnimationOptions()) { - return ConvertEffectTiming(options.GetAsKeyframeAnimationOptions(), - document, exception_state); - } - - DCHECK(options.IsUnrestrictedDouble()); - - // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect - // If options is a double, - // Let timing input be a new EffectTiming object with all members set to - // their default values and duration set to options. - EffectTiming* timing_input = EffectTiming::Create(); - timing_input->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble( - options.GetAsUnrestrictedDouble())); - return ConvertEffectTiming(timing_input, document, exception_state); -} -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) template <class InputTiming> bool TimingInput::Update(Timing& timing, @@ -199,15 +147,22 @@ bool TimingInput::Update(Timing& timing, // https://github.com/w3c/csswg-drafts/issues/247 . if (input->hasDuration()) { const char* error_message = "duration must be non-negative or auto"; - if (input->duration().IsUnrestrictedDouble()) { - double duration = input->duration().GetAsUnrestrictedDouble(); - if (std::isnan(duration) || duration < 0) { - exception_state.ThrowTypeError(error_message); - return false; + switch (input->duration()->GetContentType()) { + case V8UnionStringOrUnrestrictedDouble::ContentType::kString: + if (input->duration()->GetAsString() != "auto") { + exception_state.ThrowTypeError(error_message); + return false; + } + break; + case V8UnionStringOrUnrestrictedDouble::ContentType:: + kUnrestrictedDouble: { + double duration = input->duration()->GetAsUnrestrictedDouble(); + if (std::isnan(duration) || duration < 0) { + exception_state.ThrowTypeError(error_message); + return false; + } + break; } - } else if (input->duration().GetAsString() != "auto") { - exception_state.ThrowTypeError(error_message); - return false; } } diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input.h b/chromium/third_party/blink/renderer/core/animation/timing_input.h index 6a30531d57f..7ab8be1dd66 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input.h +++ b/chromium/third_party/blink/renderer/core/animation/timing_input.h @@ -13,8 +13,6 @@ namespace blink { class Document; class ExceptionState; -class UnrestrictedDoubleOrKeyframeAnimationOptions; -class UnrestrictedDoubleOrKeyframeEffectOptions; class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble; class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble; @@ -26,31 +24,19 @@ class CORE_EXPORT TimingInput { // the 'options' parameter into timing information. // // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static Timing Convert( const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options, Document* document, ExceptionState& exception_state); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - static Timing Convert(const UnrestrictedDoubleOrKeyframeEffectOptions&, - Document*, - ExceptionState&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Implements step 2 of the Animatable::animate() method, converting the // 'options' parameter into timing information. // // https://drafts.csswg.org/web-animations-1/#dom-animatable-animate -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) static Timing Convert( const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options, Document* document, ExceptionState& exception_state); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - static Timing Convert(const UnrestrictedDoubleOrKeyframeAnimationOptions&, - Document*, - ExceptionState&); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) // Implements the procedure to 'update the timing properties of an animation // effect'. diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc index 4a7b2bbacc1..267e9c26ce5 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc @@ -6,8 +6,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h" -#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_animation_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h" @@ -64,15 +62,9 @@ Timing AnimationTimingInputTest::ApplyTimingInputNumber( return Timing(); } -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* timing_input = MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( timing_input_dictionary); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeEffectOptions timing_input = - UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( - timing_input_dictionary); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -83,15 +75,9 @@ Timing AnimationTimingInputTest::ApplyTimingInputNumber( if (exception_state.HadException()) return Timing(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* timing_input = MakeGarbageCollected< V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( timing_input_dictionary); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeAnimationOptions timing_input = - UnrestrictedDoubleOrKeyframeAnimationOptions:: - FromKeyframeAnimationOptions(timing_input_dictionary); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -120,15 +106,9 @@ Timing AnimationTimingInputTest::ApplyTimingInputString( if (exception_state.HadException()) return Timing(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* timing_input = MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( timing_input_dictionary); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeEffectOptions timing_input = - UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( - timing_input_dictionary); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -139,15 +119,9 @@ Timing AnimationTimingInputTest::ApplyTimingInputString( if (exception_state.HadException()) return Timing(); -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* timing_input = MakeGarbageCollected< V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( timing_input_dictionary); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeAnimationOptions timing_input = - UnrestrictedDoubleOrKeyframeAnimationOptions:: - FromKeyframeAnimationOptions(timing_input_dictionary); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) result = TimingInput::Convert(timing_input, GetDocument(), exception_state); if (exception_state.HadException()) return Timing(); @@ -479,15 +453,9 @@ TEST_F(AnimationTimingInputTest, TimingInputTimingFunction) { TEST_F(AnimationTimingInputTest, TimingInputEmpty) { DummyExceptionStateForTesting exception_state; Timing control_timing; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* timing_input = MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>( KeyframeEffectOptions::Create()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeEffectOptions timing_input = - UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions( - KeyframeEffectOptions::Create()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing updated_timing = TimingInput::Convert(timing_input, nullptr, exception_state); EXPECT_FALSE(exception_state.HadException()); @@ -504,15 +472,9 @@ TEST_F(AnimationTimingInputTest, TimingInputEmpty) { TEST_F(AnimationTimingInputTest, TimingInputEmptyKeyframeAnimationOptions) { DummyExceptionStateForTesting exception_state; Timing control_timing; -#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) auto* input_timing = MakeGarbageCollected<V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>( KeyframeAnimationOptions::Create()); -#else // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) - UnrestrictedDoubleOrKeyframeAnimationOptions input_timing = - UnrestrictedDoubleOrKeyframeAnimationOptions:: - FromKeyframeAnimationOptions(KeyframeAnimationOptions::Create()); -#endif // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION) Timing updated_timing = TimingInput::Convert(input_timing, nullptr, exception_state); EXPECT_FALSE(exception_state.HadException()); diff --git a/chromium/third_party/blink/renderer/core/animation/timing_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_test.cc index 9ce6f35240d..fed9dfee939 100644 --- a/chromium/third_party/blink/renderer/core/animation/timing_test.cc +++ b/chromium/third_party/blink/renderer/core/animation/timing_test.cc @@ -18,8 +18,8 @@ class AnimationTimingTest : public testing::Test { playback_rate < 0 ? Timing::AnimationDirection::kBackwards : Timing::AnimationDirection::kForwards; return timing_.CalculateTimings( - local_time, /*timeline_phase*/ absl::nullopt, animation_direction, - is_keyframe_effect, playback_rate); + local_time, /*timeline_phase*/ absl::nullopt, normalized_timing_, + animation_direction, is_keyframe_effect, playback_rate); } bool IsCurrent(absl::optional<double> local_time, double playback_rate) { absl::optional<AnimationTimeDelta> local_time_delta; @@ -32,9 +32,14 @@ class AnimationTimingTest : public testing::Test { private: void SetUp() override { - timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.start_delay = AnimationTimeDelta(); + normalized_timing_.end_delay = AnimationTimeDelta(); + normalized_timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.active_duration = AnimationTimeDelta::FromSecondsD(1); + normalized_timing_.end_time = AnimationTimeDelta::FromSecondsD(1); } Timing timing_; + Timing::NormalizedTiming normalized_timing_; }; TEST_F(AnimationTimingTest, IsCurrent) { diff --git a/chromium/third_party/blink/renderer/core/animation/underlying_value_owner.h b/chromium/third_party/blink/renderer/core/animation/underlying_value_owner.h index 95efc5d1992..1f6d277e017 100644 --- a/chromium/third_party/blink/renderer/core/animation/underlying_value_owner.h +++ b/chromium/third_party/blink/renderer/core/animation/underlying_value_owner.h @@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "third_party/blink/renderer/core/animation/typed_interpolation_value.h" #include "third_party/blink/renderer/core/animation/underlying_value.h" #include "third_party/blink/renderer/core/core_export.h" @@ -25,6 +24,8 @@ class CORE_EXPORT UnderlyingValueOwner : public UnderlyingValue { public: UnderlyingValueOwner() : type_(nullptr), value_owner_(nullptr), value_(nullptr) {} + UnderlyingValueOwner(const UnderlyingValueOwner&) = delete; + UnderlyingValueOwner& operator=(const UnderlyingValueOwner&) = delete; operator bool() const { DCHECK_EQ(static_cast<bool>(type_), static_cast<bool>(value_)); @@ -56,7 +57,6 @@ class CORE_EXPORT UnderlyingValueOwner : public UnderlyingValue { const InterpolationType* type_; InterpolationValue value_owner_; const InterpolationValue* value_; - DISALLOW_COPY_AND_ASSIGN(UnderlyingValueOwner); }; } // namespace blink |