chromium/third_party/blink/renderer/core/animation/animation.cc

/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/animation/animation.h"

#include <limits>
#include <memory>

#include "base/debug/stack_trace.h"
#include "base/metrics/histogram_macros.h"
#include "cc/animation/animation_timeline.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/v8_timeline_range_offset.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/animation/animation_utils.h"
#include "third_party/blink/renderer/core/animation/compositor_animations.h"
#include "third_party/blink/renderer/core/animation/css/css_animation.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/animation/css/css_transition.h"
#include "third_party/blink/renderer/core/animation/document_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/scroll_timeline.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#include "third_party/blink/renderer/core/animation/timeline_range.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/native_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/properties/longhands.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_attribute_mutation_scope.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_document_state.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.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/event_target_names.h"
#include "third_party/blink/renderer/core/events/animation_playback_event.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"

namespace blink {

namespace {

// Accessing the compositor animation state should not be done during style,
// layout or paint to avoid blocking on a previous pending commit.
#if DCHECK_IS_ON()
#define VERIFY_PAINT_CLEAN_LOG_ONCE()
#else
#define VERIFY_PAINT_CLEAN_LOG_ONCE
#endif

// Ensure the time is bounded such that it can be resolved to microsecond
// accuracy. Beyond this limit, we can effectively stall an animation when
// ticking (i.e. b + delta == b for high enough floating point value of b).
// Furthermore, we can encounter numeric overflows when converting to a
// time format that is backed by a 64-bit integer.
bool SupportedTimeValue(double time_in_ms) {}

enum class PseudoPriority {};

unsigned NextSequenceNumber() {}

PseudoPriority ConvertPseudoIdtoPriority(const PseudoId& pseudo) {}

Animation::AnimationClassPriority AnimationPriority(
    const Animation& animation) {}

void RecordCompositorAnimationFailureReasons(
    CompositorAnimations::FailureReasons failure_reasons) {}

Element* OriginatingElement(Element* owning_element) {}

AtomicString GetCSSTransitionCSSPropertyName(const Animation* animation) {}

bool GreaterThanOrEqualWithinTimeTolerance(const AnimationTimeDelta& a,
                                           const AnimationTimeDelta& b) {}

// Consider boundaries aligned if they round to the same integer pixel value.
const double kScrollBoundaryTolerance =;

}  // namespace

Animation* Animation::Create(AnimationEffect* effect,
                             AnimationTimeline* timeline,
                             ExceptionState& exception_state) {}

Animation* Animation::Create(ExecutionContext* execution_context,
                             AnimationEffect* effect,
                             ExceptionState& exception_state) {}

Animation* Animation::Create(ExecutionContext* execution_context,
                             AnimationEffect* effect,
                             AnimationTimeline* timeline,
                             ExceptionState& exception_state) {}

Animation::Animation(ExecutionContext* execution_context,
                     AnimationTimeline* timeline,
                     AnimationEffect* content)
    :{}

Animation::~Animation() {}

void Animation::Dispose() {}

AnimationTimeDelta Animation::EffectEnd() const {}

bool Animation::Limited(std::optional<AnimationTimeDelta> current_time) const {}

Document* Animation::GetDocument() const {}

std::optional<AnimationTimeDelta> Animation::TimelineTime() const {}

bool Animation::ConvertCSSNumberishToTime(
    const V8CSSNumberish* numberish,
    std::optional<AnimationTimeDelta>& time,
    String variable_name,
    ExceptionState& exception_state) {}

// https://www.w3.org/TR/web-animations-1/#setting-the-current-time-of-an-animation
void Animation::setCurrentTime(const V8CSSNumberish* current_time,
                               ExceptionState& exception_state) {}

// https://www.w3.org/TR/web-animations-1/#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.
void Animation::SetCurrentTimeInternal(AnimationTimeDelta new_current_time) {}

V8CSSNumberish* Animation::startTime() const {}

V8CSSNumberish* Animation::ConvertTimeToCSSNumberish(
    std::optional<AnimationTimeDelta> time) const {}

std::optional<double> Animation::TimeAsAnimationProgress(
    AnimationTimeDelta time) const {}

// https://www.w3.org/TR/web-animations-1/#the-current-time-of-an-animation
V8CSSNumberish* Animation::currentTime() const {}

std::optional<AnimationTimeDelta> Animation::CurrentTimeInternal() const {}

std::optional<AnimationTimeDelta> Animation::UnlimitedCurrentTime() const {}

std::optional<double> Animation::progress() const {}

String Animation::playState() const {}

bool Animation::PreCommit(
    int compositor_group,
    const PaintArtifactCompositor* paint_artifact_compositor,
    bool start_on_compositor) {}

void Animation::PostCommit() {}

bool Animation::HasLowerCompositeOrdering(
    const Animation* animation1,
    const Animation* animation2,
    CompareAnimationsOrdering compare_animation_type) {}

void Animation::NotifyReady(AnimationTimeDelta ready_time) {}

// Microtask for playing an animation.
// Refer to Step 8.3 'pending play task' in the following spec:
// https://www.w3.org/TR/web-animations-1/#playing-an-animation-section
void Animation::CommitPendingPlay(AnimationTimeDelta ready_time) {}

// Microtask for pausing an animation.
// Refer to step 7 'pending pause task' in the following spec:
// https://www.w3.org/TR/web-animations-1/#pausing-an-animation-section
void Animation::CommitPendingPause(AnimationTimeDelta ready_time) {}

bool Animation::Affects(const Element& element,
                        const CSSProperty& property) const {}

AnimationTimeline* Animation::timeline() {}

void Animation::setTimeline(AnimationTimeline* timeline) {}

std::optional<AnimationTimeDelta> Animation::CalculateStartTime(
    AnimationTimeDelta current_time) const {}

std::optional<AnimationTimeDelta> Animation::CalculateCurrentTime() const {}

// https://www.w3.org/TR/web-animations-1/#setting-the-start-time-of-an-animation
void Animation::setStartTime(const V8CSSNumberish* start_time,
                             ExceptionState& exception_state) {}

// https://www.w3.org/TR/web-animations-1/#setting-the-associated-effect
void Animation::setEffect(AnimationEffect* new_effect) {}

String Animation::PlayStateString() const {}

const char* Animation::PlayStateString(AnimationPlayState play_state) {}

// https://www.w3.org/TR/web-animations-1/#play-states
Animation::AnimationPlayState Animation::CalculateAnimationPlayState() const {}

bool Animation::PendingInternal() const {}

bool Animation::pending() const {}

// https://www.w3.org/TR/web-animations-1/#reset-an-animations-pending-tasks.
void Animation::ResetPendingTasks() {}

// ----------------------------------------------
// Pause methods.
// ----------------------------------------------

// https://www.w3.org/TR/web-animations-1/#pausing-an-animation-section
void Animation::pause(ExceptionState& exception_state) {}

// ----------------------------------------------
// Play methods.
// ----------------------------------------------

// Refer to the unpause operation in the following spec:
// https://www.w3.org/TR/css-animations-1/#animation-play-state
void Animation::Unpause() {}

// https://www.w3.org/TR/web-animations-1/#playing-an-animation-section
void Animation::play(ExceptionState& exception_state) {}

// https://www.w3.org/TR/web-animations-2/#playing-an-animation-section
void Animation::PlayInternal(AutoRewind auto_rewind,
                             ExceptionState& exception_state) {}

// https://www.w3.org/TR/web-animations-1/#reversing-an-animation-section
void Animation::reverse(ExceptionState& exception_state) {}

// ----------------------------------------------
// Finish methods.
// ----------------------------------------------

// https://www.w3.org/TR/web-animations-1/#finishing-an-animation-section
void Animation::finish(ExceptionState& exception_state) {}

void Animation::UpdateFinishedState(UpdateType update_type,
                                    NotificationType notification_type) {}

void Animation::ScheduleAsyncFinish() {}

void Animation::AsyncFinishMicrotask() {}

// Refer to 'finished notification steps' in
// https://www.w3.org/TR/web-animations-1/#updating-the-finished-state
void Animation::CommitFinishNotification() {}

// https://www.w3.org/TR/web-animations-1/#setting-the-playback-rate-of-an-animation
void Animation::updatePlaybackRate(double playback_rate,
                                   ExceptionState& exception_state) {}

ScriptPromise<Animation> Animation::finished(ScriptState* script_state) {}

ScriptPromise<Animation> Animation::ready(ScriptState* script_state) {}

const AtomicString& Animation::InterfaceName() const {}

ExecutionContext* Animation::GetExecutionContext() const {}

bool Animation::HasPendingActivity() const {}

void Animation::ContextDestroyed() {}

DispatchEventResult Animation::DispatchEventInternal(Event& event) {}

double Animation::playbackRate() const {}

double Animation::EffectivePlaybackRate() const {}

void Animation::ApplyPendingPlaybackRate() {}

void Animation::setPlaybackRate(double playback_rate,
                                ExceptionState& exception_state) {}

void Animation::ClearOutdated() {}

void Animation::SetOutdated() {}

void Animation::ForceServiceOnNextFrame() {}

CompositorAnimations::FailureReasons
Animation::CheckCanStartAnimationOnCompositor(
    const PaintArtifactCompositor* paint_artifact_compositor,
    PropertyHandleSet* unsupported_properties) const {}

CompositorAnimations::FailureReasons
Animation::CheckCanStartAnimationOnCompositorInternal() const {}

base::TimeDelta Animation::ComputeCompositorTimeOffset() const {}

void Animation::MarkPendingIfCompositorPropertyAnimationChanges(
    const PaintArtifactCompositor* paint_artifact_compositor) {}

void Animation::StartAnimationOnCompositor(
    const PaintArtifactCompositor* paint_artifact_compositor) {}

// TODO(crbug.com/960944): Rename to SetPendingCommit. This method handles both
// composited and non-composited animations. The use of 'compositor' in the name
// is confusing.
void Animation::SetCompositorPending(CompositorPendingReason reason) {}

const Animation::RangeBoundary* Animation::rangeStart() {}

const Animation::RangeBoundary* Animation::rangeEnd() {}

void Animation::setRangeStart(const Animation::RangeBoundary* range_start,
                              ExceptionState& exception_state) {}

void Animation::setRangeEnd(const Animation::RangeBoundary* range_end,
                            ExceptionState& exception_state) {}

std::optional<TimelineOffset> Animation::GetEffectiveTimelineOffset(
    const Animation::RangeBoundary* boundary,
    double default_percent,
    ExceptionState& exception_state) {}

/* static */
Animation::RangeBoundary* Animation::ToRangeBoundary(
    std::optional<TimelineOffset> timeline_offset) {}

void Animation::UpdateAutoAlignedStartTime() {}

bool Animation::OnValidateSnapshot(bool snapshot_changed) {}

void Animation::SetRangeStartInternal(
    const std::optional<TimelineOffset>& range_start) {}

void Animation::SetRangeEndInternal(
    const std::optional<TimelineOffset>& range_end) {}

void Animation::SetRange(const std::optional<TimelineOffset>& range_start,
                         const std::optional<TimelineOffset>& range_end) {}

void Animation::OnRangeUpdate() {}

void Animation::UpdateBoundaryAlignment(
    Timing::NormalizedTiming& timing) const {}

namespace {

double ResolveAnimationRange(const std::optional<TimelineOffset>& offset,
                             const TimelineRange& timeline_range,
                             double default_value) {}

}  // namespace

bool Animation::ResolveTimelineOffsets(const TimelineRange& timeline_range) {}

void Animation::CancelAnimationOnCompositor() {}

void Animation::RestartAnimationOnCompositor() {}

void Animation::CancelIncompatibleAnimationsOnCompositor() {}

bool Animation::HasActiveAnimationsOnCompositor() {}

// Update current time of the animation. Refer to step 1 in:
// https://www.w3.org/TR/web-animations-1/#update-animations-and-send-events
bool Animation::Update(TimingUpdateReason reason) {}

void Animation::QueueFinishedEvent() {}

void Animation::UpdateIfNecessary() {}

void Animation::EffectInvalidated() {}

bool Animation::IsEventDispatchAllowed() const {}

std::optional<AnimationTimeDelta> Animation::TimeToEffectChange() {}

// https://www.w3.org/TR/web-animations-1/#canceling-an-animation-section
void Animation::cancel() {}

void Animation::CreateCompositorAnimation(
    std::optional<int> replaced_cc_animation_id) {}

void Animation::DestroyCompositorAnimation() {}

void Animation::AttachCompositorTimeline() {}

void Animation::DetachCompositorTimeline() {}

void Animation::AttachCompositedLayers() {}

void Animation::DetachCompositedLayers() {}

void Animation::NotifyAnimationStarted(base::TimeDelta monotonic_time,
                                       int group) {}

void Animation::AddedEventListener(
    const AtomicString& event_type,
    RegisteredEventListener& registered_listener) {}

void Animation::PauseForTesting(AnimationTimeDelta pause_time) {}

void Animation::SetEffectSuppressed(bool suppressed) {}

void Animation::DisableCompositedAnimationForTesting() {}

void Animation::InvalidateKeyframeEffect(
    const TreeScope& tree_scope,
    const StyleChangeReasonForTracing& reason) {}

void Animation::InvalidateEffectTargetStyle() {}

void Animation::InvalidateNormalizedTiming() {}

void Animation::ResolvePromiseMaybeAsync(AnimationPromise* promise) {}

void Animation::RejectAndResetPromise(AnimationPromise* promise) {}

void Animation::RejectAndResetPromiseMaybeAsync(AnimationPromise* promise) {}

void Animation::NotifyProbe() {}

// -------------------------------------
// Replacement of animations
// -------------------------------------

// https://www.w3.org/TR/web-animations-1/#removing-replaced-animations
bool Animation::IsReplaceable() {}

// https://www.w3.org/TR/web-animations-1/#removing-replaced-animations
void Animation::RemoveReplacedAnimation() {}

void Animation::persist() {}

String Animation::replaceState() {}

// https://www.w3.org/TR/web-animations-1/#dom-animation-commitstyles
void Animation::commitStyles(ExceptionState& exception_state) {}

bool Animation::IsInDisplayLockedSubtree() {}

void Animation::UpdateCompositedPaintStatus() {}

void Animation::Trace(Visitor* visitor) const {}

Animation::CompositorAnimationHolder*
Animation::CompositorAnimationHolder::Create(
    Animation* animation,
    std::optional<int> replaced_cc_animation_id) {}

Animation::CompositorAnimationHolder::CompositorAnimationHolder(
    Animation* animation,
    std::optional<int> replaced_cc_animation_id)
    :{}

void Animation::CompositorAnimationHolder::Dispose() {}

void Animation::CompositorAnimationHolder::Detach() {}
}  // namespace blink