Fix latest_frame_target_time race (#18279)
There are some cases where onAnimatorDraw gets called before
onAnimatorBeginFrame, in these cases we need to update the
latest_frame_target_time to be the target time for the current frame.
This manifested as an issue in release mode Android builds:
https://firebase.corp.google.com/project/flutter-infra/testlab/histories/bh.27c33c672e9b01f2/matrices/4903344583855476919/executions/bs.ee4f6f7ad8671a34
diff --git a/shell/common/animator.cc b/shell/common/animator.cc
index 004069b..7e581c0 100644
--- a/shell/common/animator.cc
+++ b/shell/common/animator.cc
@@ -190,7 +190,7 @@
FML_DLOG(INFO) << "No pending continuation to commit";
}
- delegate_.OnAnimatorDraw(layer_tree_pipeline_);
+ delegate_.OnAnimatorDraw(layer_tree_pipeline_, last_frame_target_time_);
}
bool Animator::CanReuseLastLayerTree() {
diff --git a/shell/common/animator.h b/shell/common/animator.h
index f96acb7..0bab577 100644
--- a/shell/common/animator.h
+++ b/shell/common/animator.h
@@ -35,7 +35,8 @@
virtual void OnAnimatorNotifyIdle(int64_t deadline) = 0;
virtual void OnAnimatorDraw(
- fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) = 0;
+ fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
+ fml::TimePoint frame_target_time) = 0;
virtual void OnAnimatorDrawLastLayerTree() = 0;
};
diff --git a/shell/common/shell.cc b/shell/common/shell.cc
index 8d27853..d83fadb 100644
--- a/shell/common/shell.cc
+++ b/shell/common/shell.cc
@@ -952,9 +952,20 @@
}
// |Animator::Delegate|
-void Shell::OnAnimatorDraw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
+void Shell::OnAnimatorDraw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
+ 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_);
+ 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;
+ }
+ }
+
task_runners_.GetRasterTaskRunner()->PostTask(
[&waiting_for_first_frame = waiting_for_first_frame_,
&waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
diff --git a/shell/common/shell.h b/shell/common/shell.h
index 3c904d8..a39884a 100644
--- a/shell/common/shell.h
+++ b/shell/common/shell.h
@@ -489,8 +489,8 @@
void OnAnimatorNotifyIdle(int64_t deadline) override;
// |Animator::Delegate|
- void OnAnimatorDraw(
- fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) override;
+ void OnAnimatorDraw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
+ fml::TimePoint frame_target_time) override;
// |Animator::Delegate|
void OnAnimatorDrawLastLayerTree() override;