@@ -178,6 +178,8 @@ DefaultSessionConnection::DefaultSessionConnection(
178178 on_frame_presented_callback_ (std::move(on_frame_presented_callback)),
179179 kMaxFramesInFlight(max_frames_in_flight),
180180 vsync_offset_(vsync_offset) {
181+ FML_CHECK (kMaxFramesInFlight > 0 );
182+
181183 next_presentation_info_.set_presentation_time (0 );
182184
183185 session_wrapper_.set_error_handler (
@@ -187,14 +189,16 @@ DefaultSessionConnection::DefaultSessionConnection(
187189 // fire every time a set of one or more frames is presented.
188190 session_wrapper_.set_on_frame_presented_handler (
189191 [this ](fuchsia::scenic::scheduling::FramePresentedInfo info) {
192+ std::lock_guard<std::mutex> lock (mutex_);
193+
190194 // Update Scenic's limit for our remaining frames in flight allowed.
191195 size_t num_presents_handled = info.presentation_infos .size ();
192- frames_in_flight_allowed_ = info.num_presents_allowed ;
193196
194197 // A frame was presented: Update our |frames_in_flight| to match the
195198 // updated unfinalized present requests.
196199 frames_in_flight_ -= num_presents_handled;
197- TRACE_DURATION (" gfx" , " OnFramePresented" , " frames_in_flight" ,
200+
201+ TRACE_DURATION (" gfx" , " OnFramePresented5" , " frames_in_flight" ,
198202 frames_in_flight_, " max_frames_in_flight" ,
199203 kMaxFramesInFlight , " num_presents_handled" ,
200204 num_presents_handled);
@@ -203,19 +207,16 @@ DefaultSessionConnection::DefaultSessionConnection(
203207 last_presentation_time_ = fml::TimePoint::FromEpochDelta (
204208 fml::TimeDelta::FromNanoseconds (info.actual_presentation_time ));
205209
206- // Call the client-provided callback once we are done using |info|.
207- on_frame_presented_callback_ (std::move (info));
210+ if (fire_callback_request_pending_) {
211+ FireCallbackMaybe ();
212+ }
208213
209214 if (present_session_pending_) {
210215 PresentSession ();
211216 }
212217
213- {
214- std::lock_guard<std::mutex> lock (mutex_);
215- if (fire_callback_request_pending_) {
216- FireCallbackMaybe ();
217- }
218- }
218+ // Call the client-provided callback once we are done using |info|.
219+ on_frame_presented_callback_ (std::move (info));
219220 } // callback
220221 );
221222
@@ -225,10 +226,7 @@ DefaultSessionConnection::DefaultSessionConnection(
225226 session_wrapper_.RequestPresentationTimes (
226227 /* requested_prediction_span=*/ 0 ,
227228 [this ](fuchsia::scenic::scheduling::FuturePresentationTimes info) {
228- frames_in_flight_allowed_ = info.remaining_presents_in_flight_allowed ;
229-
230- // If Scenic alloted us 0 frames to begin with, we should fail here.
231- FML_CHECK (frames_in_flight_allowed_ > 0 );
229+ std::lock_guard<std::mutex> lock (mutex_);
232230
233231 next_presentation_info_ =
234232 UpdatePresentationInfo (std::move (info), next_presentation_info_);
@@ -244,12 +242,14 @@ DefaultSessionConnection::DefaultSessionConnection(
244242DefaultSessionConnection::~DefaultSessionConnection () = default ;
245243
246244void DefaultSessionConnection::Present () {
245+ std::lock_guard<std::mutex> lock (mutex_);
246+
247247 TRACE_DURATION (" gfx" , " DefaultSessionConnection::Present" , " frames_in_flight" ,
248248 frames_in_flight_, " max_frames_in_flight" , kMaxFramesInFlight );
249249
250250 TRACE_FLOW_BEGIN (" gfx" , " DefaultSessionConnection::PresentSession" ,
251251 next_present_session_trace_id_);
252- next_present_session_trace_id_++ ;
252+ ++next_present_session_trace_id_ ;
253253
254254 present_requested_time_ = fml::TimePoint::Now ();
255255
@@ -286,29 +286,21 @@ void DefaultSessionConnection::AwaitVsyncForSecondaryCallback(
286286 fire_callback_ (times.frame_start , times.frame_target );
287287}
288288
289+ // Precondition: |mutex_| is held
289290void DefaultSessionConnection::PresentSession () {
290291 TRACE_DURATION (" gfx" , " DefaultSessionConnection::PresentSession" );
291292
292- // If we cannot call Present2() because we have no more Scenic frame budget,
293- // then we must wait until the OnFramePresented() event fires so we can
294- // continue our work.
295- if (frames_in_flight_allowed_ == 0 ) {
296- FML_CHECK (!initialized_ || present_session_pending_);
297- return ;
298- }
299-
300293 present_session_pending_ = false ;
301294
302295 while (processed_present_session_trace_id_ < next_present_session_trace_id_) {
303296 TRACE_FLOW_END (" gfx" , " DefaultSessionConnection::PresentSession" ,
304297 processed_present_session_trace_id_);
305- processed_present_session_trace_id_++ ;
298+ ++processed_present_session_trace_id_ ;
306299 }
307300 TRACE_FLOW_BEGIN (" gfx" , " Session::Present" , next_present_trace_id_);
308- next_present_trace_id_++ ;
301+ ++next_present_trace_id_ ;
309302
310303 ++frames_in_flight_;
311-
312304 // Flush all session ops. Paint tasks may not yet have executed but those are
313305 // fenced. The compositor can start processing ops while we finalize paint
314306 // tasks.
@@ -329,6 +321,8 @@ void DefaultSessionConnection::PresentSession() {
329321 .ToNanoseconds (),
330322 /* requested_prediction_span=*/ presentation_interval.ToNanoseconds () * 10 ,
331323 [this ](fuchsia::scenic::scheduling::FuturePresentationTimes info) {
324+ std::lock_guard<std::mutex> lock (mutex_);
325+
332326 // Clear |future_presentation_infos_| and replace it with the updated
333327 // information.
334328 std::deque<std::pair<fml::TimePoint, fml::TimePoint>>().swap (
@@ -343,15 +337,16 @@ void DefaultSessionConnection::PresentSession() {
343337 presentation_info.presentation_time ()))});
344338 }
345339
346- frames_in_flight_allowed_ = info.remaining_presents_in_flight_allowed ;
347340 next_presentation_info_ =
348341 UpdatePresentationInfo (std::move (info), next_presentation_info_);
349342 });
350343}
351344
345+ // Precondition: |mutex_| is held.
346+ //
352347// Postcondition: Either a frame is scheduled or fire_callback_request_pending_
353348// is set to true, meaning we will attempt to schedule a frame on the next
354- // |OnVsync |.
349+ // |OnFramePresented |.
355350void DefaultSessionConnection::FireCallbackMaybe () {
356351 TRACE_DURATION (" flutter" , " FireCallbackMaybe" );
357352
@@ -368,6 +363,8 @@ void DefaultSessionConnection::FireCallbackMaybe() {
368363 }
369364}
370365
366+ // Precondition: |mutex_| is held
367+ //
371368// A helper function for GetTargetTimes(), since many of the fields it takes
372369// have to be derived from other state.
373370FlutterFrameTimes DefaultSessionConnection::GetTargetTimesHelper (
@@ -412,6 +409,7 @@ DefaultSessionConnection::UpdatePresentationInfo(
412409 return new_presentation_info;
413410}
414411
412+ // Precondition: |mutex_| is held
415413VsyncInfo DefaultSessionConnection::GetCurrentVsyncInfo () const {
416414 return {fml::TimePoint::FromEpochDelta (fml::TimeDelta::FromNanoseconds (
417415 next_presentation_info_.presentation_time ())),
0 commit comments