mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-09 12:21:31 +11:00
[frame_stats] Add a VSync toggle key; show the current VSync state in stats UI
This commit is contained in:
parent
306aeab6df
commit
1250cdcf86
|
@ -20,4 +20,5 @@ $ cargo run -p with_winit --release -- [SVG FILES]
|
||||||
- Space resets the position and zoom of the image.
|
- Space resets the position and zoom of the image.
|
||||||
- S toggles the frame statistics layer
|
- S toggles the frame statistics layer
|
||||||
- C resets the min/max frame time tracked by statistics
|
- C resets the min/max frame time tracked by statistics
|
||||||
|
- V toggles VSync on/off (default: on)
|
||||||
- Escape exits the program.
|
- Escape exits the program.
|
||||||
|
|
|
@ -100,6 +100,7 @@ fn run(
|
||||||
let mut images = ImageCache::new();
|
let mut images = ImageCache::new();
|
||||||
let mut stats = stats::Stats::new();
|
let mut stats = stats::Stats::new();
|
||||||
let mut stats_shown = true;
|
let mut stats_shown = true;
|
||||||
|
let mut vsync_on = true;
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let mut touch_state = multi_touch::TouchState::new();
|
let mut touch_state = multi_touch::TouchState::new();
|
||||||
|
@ -151,6 +152,17 @@ fn run(
|
||||||
Some(VirtualKeyCode::C) => {
|
Some(VirtualKeyCode::C) => {
|
||||||
stats.clear_min_and_max();
|
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) => {
|
Some(VirtualKeyCode::Escape) => {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
|
@ -314,6 +326,7 @@ fn run(
|
||||||
width as f64,
|
width as f64,
|
||||||
height as f64,
|
height as f64,
|
||||||
stats.samples(),
|
stats.samples(),
|
||||||
|
vsync_on,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let surface_texture = render_state
|
let surface_texture = render_state
|
||||||
|
|
|
@ -40,17 +40,17 @@ impl Snapshot {
|
||||||
viewport_width: f64,
|
viewport_width: f64,
|
||||||
viewport_height: f64,
|
viewport_height: f64,
|
||||||
samples: T,
|
samples: T,
|
||||||
|
vsync: bool,
|
||||||
) where
|
) where
|
||||||
T: Iterator<Item = &'a u64>,
|
T: Iterator<Item = &'a u64>,
|
||||||
{
|
{
|
||||||
let width = (viewport_width * 0.4).max(200.).min(600.);
|
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 x_offset = viewport_width - width;
|
||||||
let y_offset = viewport_height - height;
|
let y_offset = viewport_height - height;
|
||||||
let offset = Affine::translate((x_offset, y_offset));
|
let offset = Affine::translate((x_offset, y_offset));
|
||||||
let text_height = height * 0.1;
|
|
||||||
let left_margin = width * 0.01;
|
// Draw the background
|
||||||
let text_size = (text_height * 0.9) as f32;
|
|
||||||
sb.fill(
|
sb.fill(
|
||||||
Fill::NonZero,
|
Fill::NonZero,
|
||||||
offset,
|
offset,
|
||||||
|
@ -58,38 +58,29 @@ impl Snapshot {
|
||||||
None,
|
None,
|
||||||
&Rect::new(0., 0., width, height),
|
&Rect::new(0., 0., width, height),
|
||||||
);
|
);
|
||||||
text.add(
|
|
||||||
sb,
|
let labels = [
|
||||||
None,
|
format!("Frame Time: {:.2} ms", self.frame_time_ms),
|
||||||
text_size,
|
format!("Frame Time (min): {:.2} ms", self.frame_time_min_ms),
|
||||||
Some(&Brush::Solid(Color::WHITE)),
|
format!("Frame Time (max): {:.2} ms", self.frame_time_max_ms),
|
||||||
offset * Affine::translate((left_margin, text_height)),
|
format!("VSync: {}", if vsync { "on" } else { "off" }),
|
||||||
&format!("Frame Time: {:.2} ms", self.frame_time_ms),
|
format!("Resolution: {viewport_width}x{viewport_height}"),
|
||||||
);
|
];
|
||||||
text.add(
|
|
||||||
sb,
|
// height / 2 is dedicated to the text labels and the rest is filled by the bar graph.
|
||||||
None,
|
let text_height = height * 0.5 / (1 + labels.len()) as f64;
|
||||||
text_size,
|
let left_margin = width * 0.01;
|
||||||
Some(&Brush::Solid(Color::WHITE)),
|
let text_size = (text_height * 0.9) as f32;
|
||||||
offset * Affine::translate((left_margin, 2. * text_height)),
|
for (i, label) in labels.iter().enumerate() {
|
||||||
&format!("Frame Time (min): {:.2} ms", self.frame_time_min_ms),
|
text.add(
|
||||||
);
|
sb,
|
||||||
text.add(
|
None,
|
||||||
sb,
|
text_size,
|
||||||
None,
|
Some(&Brush::Solid(Color::WHITE)),
|
||||||
text_size,
|
offset * Affine::translate((left_margin, (i + 1) as f64 * text_height)),
|
||||||
Some(&Brush::Solid(Color::WHITE)),
|
&label,
|
||||||
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}"),
|
|
||||||
);
|
|
||||||
text.add(
|
text.add(
|
||||||
sb,
|
sb,
|
||||||
None,
|
None,
|
||||||
|
@ -112,7 +103,7 @@ impl Snapshot {
|
||||||
LineTo((bar_width, graph_max_height).into()),
|
LineTo((bar_width, graph_max_height).into()),
|
||||||
];
|
];
|
||||||
for (i, sample) in samples.enumerate() {
|
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.
|
// 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
|
// 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
|
// 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());
|
let s = Affine::scale_non_uniform(1., -h.sqrt());
|
||||||
sb.fill(
|
sb.fill(
|
||||||
Fill::NonZero,
|
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),
|
Color::rgb8(0, 240, 0),
|
||||||
None,
|
None,
|
||||||
&bar,
|
&bar,
|
||||||
|
|
|
@ -92,6 +92,13 @@ impl RenderContext {
|
||||||
.configure(&self.devices[surface.dev_id].device, &surface.config);
|
.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.
|
/// Finds or creates a compatible device handle id.
|
||||||
pub async fn device(&mut self, compatible_surface: Option<&Surface>) -> Option<usize> {
|
pub async fn device(&mut self, compatible_surface: Option<&Surface>) -> Option<usize> {
|
||||||
let compatible = match compatible_surface {
|
let compatible = match compatible_surface {
|
||||||
|
|
Loading…
Reference in a new issue