[frame_stats] Add a VSync toggle key; show the current VSync state in stats UI

This commit is contained in:
Arman Uguray 2023-03-16 01:02:49 -07:00
parent 306aeab6df
commit 1250cdcf86
4 changed files with 50 additions and 38 deletions

View file

@ -20,4 +20,5 @@ $ cargo run -p with_winit --release -- [SVG FILES]
- Space resets the position and zoom of the image.
- S toggles the frame statistics layer
- C resets the min/max frame time tracked by statistics
- V toggles VSync on/off (default: on)
- Escape exits the program.

View file

@ -100,6 +100,7 @@ fn run(
let mut images = ImageCache::new();
let mut stats = stats::Stats::new();
let mut stats_shown = true;
let mut vsync_on = true;
let start = Instant::now();
let mut touch_state = multi_touch::TouchState::new();
@ -151,6 +152,17 @@ fn run(
Some(VirtualKeyCode::C) => {
stats.clear_min_and_max();
}
Some(VirtualKeyCode::V) => {
vsync_on = !vsync_on;
render_cx.set_present_mode(
&mut render_state.surface,
if vsync_on {
wgpu::PresentMode::Fifo
} else {
wgpu::PresentMode::Immediate
},
);
}
Some(VirtualKeyCode::Escape) => {
*control_flow = ControlFlow::Exit;
}
@ -314,6 +326,7 @@ fn run(
width as f64,
height as f64,
stats.samples(),
vsync_on,
);
}
let surface_texture = render_state

View file

@ -40,17 +40,17 @@ impl Snapshot {
viewport_width: f64,
viewport_height: f64,
samples: T,
vsync: bool,
) where
T: Iterator<Item = &'a u64>,
{
let width = (viewport_width * 0.4).max(200.).min(600.);
let height = width * 0.6;
let height = width * 0.7;
let x_offset = viewport_width - width;
let y_offset = viewport_height - height;
let offset = Affine::translate((x_offset, y_offset));
let text_height = height * 0.1;
let left_margin = width * 0.01;
let text_size = (text_height * 0.9) as f32;
// Draw the background
sb.fill(
Fill::NonZero,
offset,
@ -58,38 +58,29 @@ impl Snapshot {
None,
&Rect::new(0., 0., width, height),
);
text.add(
sb,
None,
text_size,
Some(&Brush::Solid(Color::WHITE)),
offset * Affine::translate((left_margin, text_height)),
&format!("Frame Time: {:.2} ms", self.frame_time_ms),
);
text.add(
sb,
None,
text_size,
Some(&Brush::Solid(Color::WHITE)),
offset * Affine::translate((left_margin, 2. * text_height)),
&format!("Frame Time (min): {:.2} ms", self.frame_time_min_ms),
);
text.add(
sb,
None,
text_size,
Some(&Brush::Solid(Color::WHITE)),
offset * Affine::translate((left_margin, 3. * text_height)),
&format!("Frame Time (max): {:.2} ms", self.frame_time_max_ms),
);
text.add(
sb,
None,
text_size,
Some(&Brush::Solid(Color::WHITE)),
offset * Affine::translate((left_margin, 4. * text_height)),
&format!("Resolution: {viewport_width}x{viewport_height}"),
);
let labels = [
format!("Frame Time: {:.2} ms", self.frame_time_ms),
format!("Frame Time (min): {:.2} ms", self.frame_time_min_ms),
format!("Frame Time (max): {:.2} ms", self.frame_time_max_ms),
format!("VSync: {}", if vsync { "on" } else { "off" }),
format!("Resolution: {viewport_width}x{viewport_height}"),
];
// height / 2 is dedicated to the text labels and the rest is filled by the bar graph.
let text_height = height * 0.5 / (1 + labels.len()) as f64;
let left_margin = width * 0.01;
let text_size = (text_height * 0.9) as f32;
for (i, label) in labels.iter().enumerate() {
text.add(
sb,
None,
text_size,
Some(&Brush::Solid(Color::WHITE)),
offset * Affine::translate((left_margin, (i + 1) as f64 * text_height)),
&label,
);
}
text.add(
sb,
None,
@ -112,7 +103,7 @@ impl Snapshot {
LineTo((bar_width, graph_max_height).into()),
];
for (i, sample) in samples.enumerate() {
let t = offset * Affine::translate(((i as f64) * bar_extent, graph_max_height));
let t = offset * Affine::translate((i as f64 * bar_extent, graph_max_height));
// The height of each sample is based on its ratio to the maximum observed frame time.
// Currently this maximum scale is sticky and a high temporary spike will permanently
// shrink the draw size of the overall average sample, so scale the size non-linearly to
@ -121,7 +112,7 @@ impl Snapshot {
let s = Affine::scale_non_uniform(1., -h.sqrt());
sb.fill(
Fill::NonZero,
t * Affine::translate((left_margin, 5. * text_height)) * s,
t * Affine::translate((left_margin, (1 + labels.len()) as f64 * text_height)) * s,
Color::rgb8(0, 240, 0),
None,
&bar,

View file

@ -92,6 +92,13 @@ impl RenderContext {
.configure(&self.devices[surface.dev_id].device, &surface.config);
}
pub fn set_present_mode(&self, surface: &mut RenderSurface, present_mode: wgpu::PresentMode) {
surface.config.present_mode = present_mode;
surface
.surface
.configure(&self.devices[surface.dev_id].device, &surface.config);
}
/// Finds or creates a compatible device handle id.
pub async fn device(&mut self, compatible_surface: Option<&Surface>) -> Option<usize> {
let compatible = match compatible_surface {