Commit 1136328fbe69
tarball1 file changed+55-34
@@ -1,5 +1,6 @@
11
//! Drawing one output and queueing the frame.22
3
+use super::Surface;34
use super::pacing::{schedule, watch};45
use crate::backend::Backend;56
use crate::frame::{CLEAR, FrameCtx};@@ -42,6 +43,51 @@ pub fn render(state: &mut State) {
4243
}4344
}4445
46
+struct FrameTimes {47
+ took_ns: u64,48
+ scene_ns: u64,49
+ render_ns: u64,50
+ render_cpu_ns: u64,51
+ queue_ns: u64,52
+ frame_cpu_ns: u64,53
+}54
+55
+impl Surface {56
+ fn set_vrr(&mut self, want: bool) {57
+ if want == self.vrr_on {58
+ return;59
+ }60
+ match self.drm.with_compositor(|c| c.use_vrr(want)) {61
+ Ok(()) => {62
+ self.vrr_on = want;63
+ tracing::info!(output = self.output.name(), vrr = want, "adaptive sync");64
+ }65
+ Err(e) => {66
+ tracing::warn!("could not switch adaptive sync: {e}");67
+ self.vrr_capable = false;68
+ }69
+ }70
+ }71
+72
+ fn record_frame(&mut self, t: FrameTimes) {73
+ self.budget.record(t.took_ns);74
+ if self.frame_cpu_ns.len() < MAX_CPU_SAMPLES {75
+ self.frame_cpu_ns.push(t.frame_cpu_ns);76
+ }77
+ if t.took_ns > self.refresh_ns / 2 {78
+ tracing::debug!(79
+ output = self.output.name(),80
+ took_ns = t.took_ns,81
+ scene_ns = t.scene_ns,82
+ render_ns = t.render_ns,83
+ render_cpu_ns = t.render_cpu_ns,84
+ queue_ns = t.queue_ns,85
+ "slow frame"86
+ );87
+ }88
+ }89
+}90
+4591
/// Draws one output for the vblank at `target`. Returns whether it still4692
/// animates without a frame in flight, and so needs another render.4793
#[profiling::function]@@ -84,22 +130,7 @@ pub(super) fn render_surface(state: &mut State, crtc: crtc::Handle, target: u64)
84130
Vrr::On => true,85131
Vrr::Fullscreen => fullscreen.is_some(),86132
});87
- if want_vrr != surface.vrr_on {88
- match surface.drm.with_compositor(|c| c.use_vrr(want_vrr)) {89
- Ok(()) => {90
- surface.vrr_on = want_vrr;91
- tracing::info!(92
- output = surface.output.name(),93
- vrr = want_vrr,94
- "adaptive sync"95
- );96
- }97
- Err(e) => {98
- tracing::warn!("could not switch adaptive sync: {e}");99
- surface.vrr_capable = false;100
- }101
- }102
- }133
+ surface.set_vrr(want_vrr);103134
let began = std::time::Instant::now();104135
let frame_cpu_began = thread_cpu_ns();105136
let now = target;@@ -182,24 +213,14 @@ pub(super) fn render_surface(state: &mut State, crtc: crtc::Handle, target: u64)
182213
tracing::warn!("rendering failed: {e}");183214
}184215
}185
- let render_cpu_ns = thread_cpu_ns() - cpu_began;186
- let render_ns = render_began.elapsed().as_nanos() as u64 - queue_ns;187
- let took = began.elapsed().as_nanos() as u64;188
- surface.budget.record(took);189
- if surface.frame_cpu_ns.len() < MAX_CPU_SAMPLES {190
- surface.frame_cpu_ns.push(thread_cpu_ns() - frame_cpu_began);191
- }192
- if took > surface.refresh_ns / 2 {193
- tracing::debug!(194
- output = surface.output.name(),195
- took_ns = took,196
- scene_ns,197
- render_ns,198
- render_cpu_ns,199
- queue_ns,200
- "slow frame"201
- );202
- }216
+ surface.record_frame(FrameTimes {217
+ took_ns: began.elapsed().as_nanos() as u64,218
+ scene_ns,219
+ render_ns: render_began.elapsed().as_nanos() as u64 - queue_ns,220
+ render_cpu_ns: thread_cpu_ns() - cpu_began,221
+ queue_ns,222
+ frame_cpu_ns: thread_cpu_ns() - frame_cpu_began,223
+ });203224
if !surface.queued {204225
surface.target_ns = None;205226
}