Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller Scene] Use std::chrono for animation durations #38606

Merged
merged 2 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,7 @@ ORIGIN: ../../../flutter/impeller/base/thread.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/thread.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/thread_safety.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/thread_safety.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/timing.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/validation.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/validation.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/base/version.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3614,6 +3615,7 @@ FILE: ../../../flutter/impeller/base/thread.cc
FILE: ../../../flutter/impeller/base/thread.h
FILE: ../../../flutter/impeller/base/thread_safety.cc
FILE: ../../../flutter/impeller/base/thread_safety.h
FILE: ../../../flutter/impeller/base/timing.h
FILE: ../../../flutter/impeller/base/validation.cc
FILE: ../../../flutter/impeller/base/validation.h
FILE: ../../../flutter/impeller/base/version.cc
Expand Down
1 change: 1 addition & 0 deletions impeller/base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ impeller_component("base") {
"thread.h",
"thread_safety.cc",
"thread_safety.h",
"timing.h",
"validation.cc",
"validation.h",
"version.cc",
Expand Down
15 changes: 15 additions & 0 deletions impeller/base/timing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <chrono>

namespace impeller {

using SecondsF = std::chrono::duration<float>;
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;

} // namespace impeller
2 changes: 1 addition & 1 deletion impeller/scene/animation/animation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const std::vector<Animation::Channel>& Animation::GetChannels() const {
return channels_;
}

Scalar Animation::GetEndTime() const {
SecondsF Animation::GetEndTime() const {
return end_time_;
}

Expand Down
5 changes: 3 additions & 2 deletions impeller/scene/animation/animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "flutter/fml/hash_combine.h"
#include "flutter/fml/macros.h"
#include "impeller/base/timing.h"
#include "impeller/geometry/quaternion.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vector.h"
Expand Down Expand Up @@ -60,14 +61,14 @@ class Animation final {

const std::vector<Channel>& GetChannels() const;

Scalar GetEndTime() const;
SecondsF GetEndTime() const;

private:
Animation();

std::string name_;
std::vector<Channel> channels_;
Scalar end_time_ = 0;
SecondsF end_time_;

FML_DISALLOW_COPY_AND_ASSIGN(Animation);
};
Expand Down
32 changes: 18 additions & 14 deletions impeller/scene/animation/animation_clip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void AnimationClip::Pause() {

void AnimationClip::Stop() {
SetPlaying(false);
Seek(0);
Seek(SecondsF::zero());
}

bool AnimationClip::GetLoop() const {
Expand All @@ -70,39 +70,43 @@ void AnimationClip::SetWeight(Scalar weight) {
weight_ = weight;
}

Scalar AnimationClip::GetPlaybackTime() const {
SecondsF AnimationClip::GetPlaybackTime() const {
return playback_time_;
}

void AnimationClip::Seek(Scalar time) {
playback_time_ = std::clamp(time, 0.0f, animation_->GetEndTime());
void AnimationClip::Seek(SecondsF time) {
playback_time_ = std::clamp(time, SecondsF::zero(), animation_->GetEndTime());
}

void AnimationClip::Advance(Scalar delta_time) {
if (!playing_ || delta_time <= 0) {
void AnimationClip::Advance(SecondsF delta_time) {
if (!playing_ || delta_time <= SecondsF::zero()) {
return;
}
delta_time *= playback_time_scale_;
playback_time_ += delta_time;

/// Handle looping behavior.

Scalar end_time = animation_->GetEndTime();
if (end_time == 0) {
playback_time_ = 0;
auto end_time = animation_->GetEndTime();
if (end_time == SecondsF::zero()) {
playback_time_ = SecondsF::zero();
return;
}
if (!loop_ && (playback_time_ < 0 || playback_time_ > end_time)) {
if (!loop_ &&
(playback_time_ < SecondsF::zero() || playback_time_ > end_time)) {
// If looping is disabled, clamp to the end (or beginning, if playing in
// reverse) and pause.
Pause();
playback_time_ = std::clamp(playback_time_, 0.0f, end_time);
playback_time_ = std::clamp(playback_time_, SecondsF::zero(), end_time);
} else if (/* loop && */ playback_time_ > end_time) {
// If looping is enabled and we ran off the end, loop to the beginning.
playback_time_ = std::fmod(std::abs(playback_time_), end_time);
} else if (/* loop && */ playback_time_ < 0) {
playback_time_ =
SecondsF(std::fmod(std::abs(playback_time_.count()), end_time.count()));
} else if (/* loop && */ playback_time_ < SecondsF::zero()) {
// If looping is enabled and we ran off the beginning, loop to the end.
playback_time_ = end_time - std::fmod(std::abs(playback_time_), end_time);
playback_time_ =
end_time -
SecondsF(std::fmod(std::abs(playback_time_.count()), end_time.count()));
}
}

Expand Down
8 changes: 4 additions & 4 deletions impeller/scene/animation/animation_clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ class AnimationClip final {
void SetWeight(Scalar weight);

/// @brief Get the current playback time of the animation.
Scalar GetPlaybackTime() const;
SecondsF GetPlaybackTime() const;

/// @brief Move the animation to the specified time. The given `time` is
/// clamped to the animation's playback range.
void Seek(Scalar time);
void Seek(SecondsF time);

/// @brief Advance the animation by `delta_time` seconds. Negative
/// `delta_time` values do nothing.
void Advance(Scalar delta_time);
void Advance(SecondsF delta_time);

/// @brief Applies the animation to all binded properties in the scene.
void ApplyToBindings() const;
Expand All @@ -73,7 +73,7 @@ class AnimationClip final {
std::shared_ptr<Animation> animation_;
std::vector<ChannelBinding> bindings_;

Scalar playback_time_ = 0;
SecondsF playback_time_;
Scalar playback_time_scale_ = 1; // Seconds multiplier, can be negative.
Scalar weight_ = 1;
bool playing_ = false;
Expand Down
7 changes: 4 additions & 3 deletions impeller/scene/animation/animation_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <memory>

#include "flutter/fml/time/time_point.h"
#include "impeller/base/timing.h"
#include "impeller/scene/node.h"

namespace impeller {
Expand Down Expand Up @@ -36,10 +37,10 @@ AnimationClip& AnimationPlayer::AddAnimation(

void AnimationPlayer::Update() {
if (!previous_time_.has_value()) {
previous_time_ = fml::TimePoint::Now().ToEpochDelta();
previous_time_ = Clock::now();
}
auto new_time = fml::TimePoint::Now().ToEpochDelta();
Scalar delta_time = (new_time - previous_time_.value()).ToSecondsF();
auto new_time = Clock::now();
auto delta_time = new_time - previous_time_.value();
previous_time_ = new_time;

Reset();
Expand Down
3 changes: 2 additions & 1 deletion impeller/scene/animation/animation_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "flutter/fml/hash_combine.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/time/time_delta.h"
#include "impeller/base/timing.h"
#include "impeller/geometry/matrix.h"
#include "impeller/scene/animation/animation_clip.h"

Expand Down Expand Up @@ -42,7 +43,7 @@ class AnimationPlayer final {

std::vector<AnimationClip> clips_;

std::optional<fml::TimeDelta> previous_time_;
std::optional<TimePoint> previous_time_;

FML_DISALLOW_COPY_AND_ASSIGN(AnimationPlayer);
};
Expand Down
24 changes: 13 additions & 11 deletions impeller/scene/animation/property_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,35 @@ PropertyResolver::~PropertyResolver() = default;

TimelineResolver::~TimelineResolver() = default;

Scalar TimelineResolver::GetEndTime() {
SecondsF TimelineResolver::GetEndTime() {
if (times_.empty()) {
return 0;
return SecondsF::zero();
}
return times_.back();
return SecondsF(times_.back());
}

TimelineResolver::TimelineKey TimelineResolver::GetTimelineKey(Scalar time) {
if (times_.size() <= 1 || time <= times_.front()) {
TimelineResolver::TimelineKey TimelineResolver::GetTimelineKey(SecondsF time) {
if (times_.size() <= 1 || time.count() <= times_.front()) {
return {.index = 0, .lerp = 1};
}
if (time >= times_.back()) {
if (time.count() >= times_.back()) {
return {.index = times_.size() - 1, .lerp = 1};
}
auto it = std::lower_bound(times_.begin(), times_.end(), time);
auto it = std::lower_bound(times_.begin(), times_.end(), time.count());
size_t index = std::distance(times_.begin(), it);

Scalar previous_time = *(it - 1);
Scalar next_time = *it;
return {.index = index,
.lerp = (time - previous_time) / (next_time - previous_time)};
.lerp = (time.count() - previous_time) / (next_time - previous_time)};
}

TranslationTimelineResolver::TranslationTimelineResolver() = default;

TranslationTimelineResolver::~TranslationTimelineResolver() = default;

void TranslationTimelineResolver::Apply(Node& target,
Scalar time,
SecondsF time,
Scalar weight) {
if (values_.empty()) {
return;
Expand All @@ -97,7 +97,9 @@ RotationTimelineResolver::RotationTimelineResolver() = default;

RotationTimelineResolver::~RotationTimelineResolver() = default;

void RotationTimelineResolver::Apply(Node& target, Scalar time, Scalar weight) {
void RotationTimelineResolver::Apply(Node& target,
SecondsF time,
Scalar weight) {
if (values_.empty()) {
return;
}
Expand All @@ -114,7 +116,7 @@ ScaleTimelineResolver::ScaleTimelineResolver() = default;

ScaleTimelineResolver::~ScaleTimelineResolver() = default;

void ScaleTimelineResolver::Apply(Node& target, Scalar time, Scalar weight) {
void ScaleTimelineResolver::Apply(Node& target, SecondsF time, Scalar weight) {
if (values_.empty()) {
return;
}
Expand Down
15 changes: 8 additions & 7 deletions impeller/scene/animation/property_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "flutter/fml/hash_combine.h"
#include "flutter/fml/macros.h"
#include "impeller/base/timing.h"
#include "impeller/geometry/quaternion.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vector.h"
Expand Down Expand Up @@ -38,22 +39,22 @@ class PropertyResolver {

virtual ~PropertyResolver();

virtual Scalar GetEndTime() = 0;
virtual SecondsF GetEndTime() = 0;

/// @brief Resolve and apply the property value to a target node. This
/// operation is additive; a given node property may be amended by
/// many different PropertyResolvers prior to rendering. For example,
/// an AnimationPlayer may blend multiple Animations together by
/// applying several AnimationClips.
virtual void Apply(Node& target, Scalar time, Scalar weight) = 0;
virtual void Apply(Node& target, SecondsF time, Scalar weight) = 0;
};

class TimelineResolver : public PropertyResolver {
public:
virtual ~TimelineResolver();

// |Resolver|
Scalar GetEndTime();
SecondsF GetEndTime();

protected:
struct TimelineKey {
Expand All @@ -63,7 +64,7 @@ class TimelineResolver : public PropertyResolver {
/// and `timeline_index`. The range of this value should always be `0>N>=1`.
Scalar lerp = 1;
};
TimelineKey GetTimelineKey(Scalar time);
TimelineKey GetTimelineKey(SecondsF time);

std::vector<Scalar> times_;
};
Expand All @@ -73,7 +74,7 @@ class TranslationTimelineResolver final : public TimelineResolver {
~TranslationTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target, SecondsF time, Scalar weight) override;

private:
TranslationTimelineResolver();
Expand All @@ -90,7 +91,7 @@ class RotationTimelineResolver final : public TimelineResolver {
~RotationTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target, SecondsF time, Scalar weight) override;

private:
RotationTimelineResolver();
Expand All @@ -107,7 +108,7 @@ class ScaleTimelineResolver final : public TimelineResolver {
~ScaleTimelineResolver();

// |Resolver|
void Apply(Node& target, Scalar time, Scalar weight) override;
void Apply(Node& target, SecondsF time, Scalar weight) override;

private:
ScaleTimelineResolver();
Expand Down