@@ -57,12 +57,6 @@ void Animator::EnqueueTraceFlowId(uint64_t trace_flow_id) {
5757 });
5858}
5959
60- static fml::TimePoint FxlToDartOrEarlier (fml::TimePoint time) {
61- auto dart_now = fml::TimeDelta::FromMicroseconds (Dart_TimelineGetMicros ());
62- fml::TimePoint fxl_now = fml::TimePoint::Now ();
63- return fml::TimePoint::FromEpochDelta (time - fxl_now + dart_now);
64- }
65-
6660void Animator::BeginFrame (
6761 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
6862 TRACE_EVENT_ASYNC_END0 (" flutter" , " Frame Request Pending" ,
@@ -81,7 +75,6 @@ void Animator::BeginFrame(
8175 }
8276
8377 frame_scheduled_ = false ;
84- notify_idle_task_id_++;
8578 regenerate_layer_tree_ = false ;
8679 pending_frame_semaphore_.Signal ();
8780
@@ -106,34 +99,29 @@ void Animator::BeginFrame(
10699 FML_DCHECK (producer_continuation_);
107100 const fml::TimePoint frame_target_time =
108101 frame_timings_recorder_->GetVsyncTargetTime ();
109- dart_frame_deadline_ = FxlToDartOrEarlier ( frame_target_time);
102+ dart_frame_deadline_ = frame_target_time. ToEpochDelta ( );
110103 uint64_t frame_number = frame_timings_recorder_->GetFrameNumber ();
111104 delegate_.OnAnimatorBeginFrame (frame_target_time, frame_number);
112105
113106 if (!frame_scheduled_ && has_rendered_) {
114- // Under certain workloads (such as our parent view resizing us, which is
115- // communicated to us by repeat viewport metrics events), we won't
116- // actually have a frame scheduled yet, despite the fact that we *will* be
117- // producing a frame next vsync (it will be scheduled once we receive the
118- // viewport event). Because of this, we hold off on calling
119- // |OnAnimatorNotifyIdle| for a little bit, as that could cause garbage
120- // collection to trigger at a highly undesirable time.
107+ // Wait a tad more than 3 60hz frames before reporting a big idle period.
108+ // This is a heuristic that is meant to avoid giving false positives to the
109+ // VM when we are about to schedule a frame in the next vsync, the idea
110+ // being that if there have been three vsyncs with no frames it's a good
111+ // time to start doing GC work.
121112 task_runners_.GetUITaskRunner ()->PostDelayedTask (
122- [self = weak_factory_.GetWeakPtr (),
123- notify_idle_task_id = notify_idle_task_id_]() {
113+ [self = weak_factory_.GetWeakPtr ()]() {
124114 if (!self) {
125115 return ;
126116 }
127- // If our (this task's) task id is the same as the current one
128- // (meaning there were no follow up frames to the |BeginFrame| call
129- // that posted this task) and no frame is currently scheduled, then
130- // assume that we are idle, and notify the engine of this.
131- if (notify_idle_task_id == self->notify_idle_task_id_ &&
132- !self->frame_scheduled_ ) {
117+ auto now = fml::TimeDelta::FromMicroseconds (Dart_TimelineGetMicros ());
118+ // If there's a frame scheduled, bail.
119+ // If there's no frame scheduled, but we're not yet past the last
120+ // vsync deadline, bail.
121+ if (!self->frame_scheduled_ && now > self->dart_frame_deadline_ ) {
133122 TRACE_EVENT0 (" flutter" , " BeginFrame idle callback" );
134123 self->delegate_ .OnAnimatorNotifyIdle (
135- FxlToDartOrEarlier (fml::TimePoint::Now () +
136- fml::TimeDelta::FromMicroseconds (100000 )));
124+ now + fml::TimeDelta::FromMilliseconds (100 ));
137125 }
138126 },
139127 kNotifyIdleTaskWaitTime );
0 commit comments