Skip to content

Commit

Permalink
Always update the latest frame target time when the 'Animator::Render…
Browse files Browse the repository at this point in the history
…' method is called (flutter#31973)
  • Loading branch information
ColdPaleLight authored Mar 21, 2022
1 parent 0b48495 commit 4000df1
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 9 deletions.
3 changes: 3 additions & 0 deletions shell/common/animator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ void Animator::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
"Animator::Render");
frame_timings_recorder_->RecordBuildEnd(fml::TimePoint::Now());

delegate_.OnAnimatorUpdateLatestFrameTargetTime(
frame_timings_recorder_->GetVsyncTargetTime());

// Commit the pending continuation.
PipelineProduceResult result =
producer_continuation_.Complete(std::move(layer_tree));
Expand Down
3 changes: 3 additions & 0 deletions shell/common/animator.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class Animator final {

virtual void OnAnimatorNotifyIdle(fml::TimePoint deadline) = 0;

virtual void OnAnimatorUpdateLatestFrameTargetTime(
fml::TimePoint frame_target_time) = 0;

virtual void OnAnimatorDraw(
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) = 0;
Expand Down
12 changes: 9 additions & 3 deletions shell/common/animator_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class FakeAnimatorDelegate : public Animator::Delegate {
notify_idle_called_ = true;
}

MOCK_METHOD1(OnAnimatorUpdateLatestFrameTargetTime,
void(fml::TimePoint frame_target_time));

MOCK_METHOD2(
OnAnimatorDraw,
void(std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
Expand Down Expand Up @@ -222,9 +225,12 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) {
[&](fml::TimePoint frame_target_time, uint64_t frame_number) {
begin_frame_latch.Signal();
});

// It will only be called once even though we call the method Animator::Render
// twice. because it will only be called when the pipeline is empty.
// It must always be called when the method 'Animator::Render' is called,
// regardless of whether the pipeline is empty or not.
EXPECT_CALL(delegate, OnAnimatorUpdateLatestFrameTargetTime).Times(2);
// It will only be called once even though we call the method
// 'Animator::Render' twice. because it will only be called when the pipeline
// is empty.
EXPECT_CALL(delegate, OnAnimatorDraw).Times(1);

for (int i = 0; i < 2; i++) {
Expand Down
15 changes: 9 additions & 6 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1111,23 +1111,26 @@ void Shell::OnAnimatorNotifyIdle(fml::TimePoint deadline) {
}
}

// |Animator::Delegate|
void Shell::OnAnimatorDraw(
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
void Shell::OnAnimatorUpdateLatestFrameTargetTime(
fml::TimePoint frame_target_time) {
FML_DCHECK(is_setup_);

// record the target time for use by rasterizer.
{
std::scoped_lock time_recorder_lock(time_recorder_mutex_);
const fml::TimePoint frame_target_time =
frame_timings_recorder->GetVsyncTargetTime();
if (!latest_frame_target_time_) {
latest_frame_target_time_ = frame_target_time;
} else if (latest_frame_target_time_ < frame_target_time) {
latest_frame_target_time_ = frame_target_time;
}
}
}

// |Animator::Delegate|
void Shell::OnAnimatorDraw(
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
FML_DCHECK(is_setup_);

auto discard_callback = [this](flutter::LayerTree& tree) {
std::scoped_lock<std::mutex> lock(resize_mutex_);
Expand Down
4 changes: 4 additions & 0 deletions shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ class Shell final : public PlatformView::Delegate,
// |Animator::Delegate|
void OnAnimatorNotifyIdle(fml::TimePoint deadline) override;

// |Animator::Delegate|
void OnAnimatorUpdateLatestFrameTargetTime(
fml::TimePoint frame_target_time) override;

// |Animator::Delegate|
void OnAnimatorDraw(
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
Expand Down

0 comments on commit 4000df1

Please sign in to comment.