diff --git a/src/backend/kms/surface/mod.rs b/src/backend/kms/surface/mod.rs index 56b154dc..100af290 100644 --- a/src/backend/kms/surface/mod.rs +++ b/src/backend/kms/surface/mod.rs @@ -1008,14 +1008,12 @@ impl SurfaceThreadState { .map_err(|err| { anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err) })?; - let additional_frame_flags = if vrr - && has_active_fullscreen - && !self.timings.past_min_presentation_time(&self.clock) - { - FrameFlags::SKIP_CURSOR_ONLY_UPDATES - } else { - FrameFlags::empty() - }; + let additional_frame_flags = + if vrr && has_active_fullscreen && !self.timings.past_min_render_time(&self.clock) { + FrameFlags::SKIP_CURSOR_ONLY_UPDATES + } else { + FrameFlags::empty() + }; self.timings.set_vrr(vrr); self.timings.elements_done(&self.clock); diff --git a/src/backend/kms/surface/timings.rs b/src/backend/kms/surface/timings.rs index eff7efa4..583dce2e 100644 --- a/src/backend/kms/surface/timings.rs +++ b/src/backend/kms/surface/timings.rs @@ -320,9 +320,9 @@ impl Timings { } } - pub fn past_min_presentation_time(&self, clock: &Clock) -> bool { + pub fn past_min_render_time(&self, clock: &Clock) -> bool { let now: Duration = clock.now().into(); - let Some(refresh_interval_ns) = self.min_refresh_interval_ns else { + let Some(min_refresh_interval_ns) = self.min_refresh_interval_ns else { return true; }; let Some(last_presentation_time): Option = self @@ -333,13 +333,29 @@ impl Timings { return true; }; - let refresh_interval_ns = refresh_interval_ns.get(); + let min_refresh_interval_ns = min_refresh_interval_ns.get(); if now <= last_presentation_time { return false; } - let next = last_presentation_time + Duration::from_nanos(refresh_interval_ns); - now >= next + const MIN_MARGIN: Duration = Duration::from_millis(3); + let baseline = if let Some(refresh_interval_ns) = self.refresh_interval_ns { + MIN_MARGIN.max(Duration::from_nanos(refresh_interval_ns.get() / 2)) + } else { + MIN_MARGIN + }; + + let next_presentation_time = + last_presentation_time + Duration::from_nanos(min_refresh_interval_ns); + let deadline = next_presentation_time.saturating_sub( + if let Some(avg_submittime) = self.avg_submittime(SAMPLE_TIME_WINDOW) { + avg_submittime + } else { + baseline + } + BASE_SAFETY_MARGIN, + ); + + now >= deadline } pub fn next_render_time(&self, clock: &Clock) -> Duration {