blob: 0ef1c3bc035a0d92e8f27c35910687ab4ddd895a [file] [log] [blame]
/*
* Copyright (C) 2008 Apple 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:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_
#include "base/time/time.h"
#include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/svg/animation/priority_queue.h"
#include "third_party/blink/renderer/core/svg/animation/smil_time.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
class Document;
class SVGElement;
class SVGSMILElement;
class SVGSVGElement;
class CORE_EXPORT SMILTimeContainer final
: public GarbageCollected<SMILTimeContainer> {
public:
explicit SMILTimeContainer(SVGSVGElement& owner);
~SMILTimeContainer();
void Schedule(SVGSMILElement*);
void Reschedule(SVGSMILElement*, SMILTime interval_time);
void Unschedule(SVGSMILElement*);
// Returns the current animation time.
SMILTime Elapsed() const;
// Returns the time that we last updated timed elements to. This differs from
// the above in that it only moves during animation update steps.
SMILTime LatestUpdatePresentationTime() const;
bool IsPaused() const;
bool IsStarted() const;
void Start();
void Pause();
void Unpause();
void SetElapsed(SMILTime);
void ServiceAnimations();
bool HasAnimations() const;
void ResetDocumentTime();
void SetDocumentOrderIndexesDirty() { document_order_indexes_dirty_ = true; }
// Advance the animation timeline a single frame.
void AdvanceFrameForTesting();
bool EventsDisabled() const { return !should_dispatch_events_; }
void Trace(Visitor*) const;
private:
enum FrameSchedulingState {
// No frame scheduled.
kIdle,
// Scheduled a wakeup to update the animation values.
kSynchronizeAnimations,
// Scheduled a wakeup to trigger an animation frame.
kFutureAnimationFrame,
// Scheduled a animation frame for continuous update.
kAnimationFrame
};
bool IsTimelineRunning() const;
void SynchronizeToDocumentTimeline();
void ScheduleAnimationFrame(base::TimeDelta delay_time);
void CancelAnimationFrame();
void WakeupTimerFired(TimerBase*);
mojom::blink::ImageAnimationPolicy AnimationPolicy() const;
bool AnimationsDisabled() const;
class TimingUpdate;
void UpdateAnimationsAndScheduleFrameIfNeeded(TimingUpdate&);
void PrepareSeek(TimingUpdate&);
void ResetIntervals();
void UpdateIntervals(TimingUpdate&);
void UpdateTimedElements(TimingUpdate&);
void ApplyTimedEffects(SMILTime elapsed);
SMILTime NextProgressTime(SMILTime presentation_time) const;
void ServiceOnNextFrame();
void ScheduleWakeUp(base::TimeDelta delay_time, FrameSchedulingState);
bool HasPendingSynchronization() const;
void SetPresentationTime(SMILTime new_presentation_time);
SMILTime ClampPresentationTime(SMILTime presentation_time) const;
void UpdateDocumentOrderIndexes();
SVGSVGElement& OwnerSVGElement() const;
Document& GetDocument() const;
// The latest "restart" time for the time container's timeline. If the
// timeline has not been manipulated (seeked, paused) this will be zero.
SMILTime presentation_time_;
// The maximum possible presentation time. When this time is reached
// animations will stop.
SMILTime max_presentation_time_;
// The state all SVGSMILElements should be at.
SMILTime latest_update_time_;
// The time on the document timeline corresponding to |presentation_time_|.
base::TimeDelta reference_time_;
FrameSchedulingState frame_scheduling_state_;
bool started_ : 1; // The timeline has been started.
bool paused_ : 1; // The timeline is paused.
const bool should_dispatch_events_ : 1;
bool document_order_indexes_dirty_ : 1;
bool is_updating_intervals_;
HeapTaskRunnerTimer<SMILTimeContainer> wakeup_timer_;
using AnimatedTargets = HeapHashCountedSet<WeakMember<SVGElement>>;
AnimatedTargets animated_targets_;
PriorityQueue<SMILTime, SVGSMILElement> priority_queue_;
Member<SVGSVGElement> owner_svg_element_;
#if DCHECK_IS_ON()
friend class AnimationTargetsMutationsForbidden;
// This boolean will catch any attempts to mutate (schedule/unschedule)
// |scheduled_animations_| when it is set to true.
bool prevent_animation_targets_changes_ = false;
#endif
bool AnimationTargetsMutationsAllowed() const {
#if DCHECK_IS_ON()
return !prevent_animation_targets_changes_;
#else
return true;
#endif
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_