perf(settings): coalesce refreshes and cache resize previews
This commit is contained in:
1 parent
6671960d5e
commit
81b99709bb
16 files changed
+906
-74
No files matched your search
@@ -0,0 +1,171 @@
|
||||
//! Opt-in, reproducible category/resize measurements. No hardware settings change.
|
||||
use super::*;
|
||||
use cosmic::Application;
|
||||
use cosmic::iced::advanced::renderer::{Headless, Renderer as _};
|
||||
use cosmic::iced::advanced::{Layout, Shell, clipboard, layout, mouse, renderer, widget::Tree};
|
||||
use cosmic::iced::{Color, Event, Font, Pixels, Rectangle, Size, window};
|
||||
|
||||
fn fixture() -> App {
|
||||
let source = std::env::var_os("FERESE_BENCH_CONFIG")
|
||||
.map(|p| std::fs::read_to_string(p).unwrap())
|
||||
.unwrap_or_else(|| include_str!("../../../packaging/config.kdl").into());
|
||||
let (mut app, _) = App::init(
|
||||
Core::default(),
|
||||
(
|
||||
"/unused/settings-performance.kdl".into(),
|
||||
Snapshot::parse(source),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
);
|
||||
app.options_loaded(all_options::catalog());
|
||||
app.connections.snapshot = Some(connections::performance_snapshot());
|
||||
app.tray_apps = (0..12)
|
||||
.map(|i| tray_controls::Application {
|
||||
id: format!("app-{i}"),
|
||||
title: format!("Application {i}"),
|
||||
})
|
||||
.collect();
|
||||
app.displays = (0..3)
|
||||
.map(|i| displays::Display {
|
||||
connector: format!("DP-{}", i + 1),
|
||||
identity: format!("Test display {i}"),
|
||||
profile: None,
|
||||
logical_width: Some(1920),
|
||||
focused: i == 0,
|
||||
current: Some(displays::Mode {
|
||||
width: 3840,
|
||||
height: 2160,
|
||||
refresh: 60000,
|
||||
}),
|
||||
modes: vec![
|
||||
displays::Mode {
|
||||
width: 3840,
|
||||
height: 2160,
|
||||
refresh: 60000,
|
||||
},
|
||||
displays::Mode {
|
||||
width: 2560,
|
||||
height: 1440,
|
||||
refresh: 60000,
|
||||
},
|
||||
],
|
||||
})
|
||||
.collect();
|
||||
app
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "category/resize profile; requires the matching compositor schema binary"]
|
||||
fn profile_all_categories_and_resizing() {
|
||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
let backend = std::env::var("FERESE_BENCH_BACKEND").unwrap_or_else(|_| "wgpu".into());
|
||||
let mut renderer = runtime
|
||||
.block_on(cosmic::Renderer::new(
|
||||
Font::default(),
|
||||
Pixels(14.),
|
||||
Some(&backend),
|
||||
))
|
||||
.unwrap();
|
||||
let scale = 2.;
|
||||
for page in Page::ALL {
|
||||
let mut app = fixture();
|
||||
drop(app.update(Message::Page(page)));
|
||||
let theme = app.native_palette.native_theme();
|
||||
let mut tree: Option<Tree> = None;
|
||||
for frame in 0..18 {
|
||||
let scenario = if frame == 0 {
|
||||
"cold"
|
||||
} else if frame < 4 {
|
||||
"warm"
|
||||
} else if frame < 14 {
|
||||
"resize"
|
||||
} else {
|
||||
"switch"
|
||||
};
|
||||
if frame >= 14 {
|
||||
drop(app.update(Message::Page(Page::General)));
|
||||
drop(app.update(Message::Page(page)));
|
||||
}
|
||||
let size = if (4..14).contains(&frame) && frame % 2 == 0 {
|
||||
Size::new(631., 568.)
|
||||
} else {
|
||||
Size::new(1272., 760.)
|
||||
};
|
||||
let viewport = Rectangle::with_size(size);
|
||||
let mut messages = Vec::new();
|
||||
let started = std::time::Instant::now();
|
||||
let mut view = app.page_view();
|
||||
let tree = tree.get_or_insert_with(|| Tree::new(&view));
|
||||
cosmic::iced::advanced::widget::tree::NAMED
|
||||
.with(|named| *named.borrow_mut() = tree.take_all_named());
|
||||
tree.diff(view.as_widget_mut());
|
||||
let node = view.as_widget_mut().layout(
|
||||
tree,
|
||||
&renderer,
|
||||
&layout::Limits::new(Size::ZERO, size),
|
||||
);
|
||||
cosmic::iced::advanced::widget::tree::NAMED.with(|named| named.borrow_mut().clear());
|
||||
view.as_widget_mut().update(
|
||||
tree,
|
||||
&Event::Window(window::Event::RedrawRequested(std::time::Instant::now())),
|
||||
Layout::new(&node),
|
||||
mouse::Cursor::Unavailable,
|
||||
&renderer,
|
||||
&mut clipboard::Null,
|
||||
&mut Shell::new(&mut messages),
|
||||
&viewport,
|
||||
);
|
||||
let layout_us = started.elapsed().as_micros();
|
||||
renderer.reset(viewport);
|
||||
let started = std::time::Instant::now();
|
||||
view.as_widget().draw(
|
||||
tree,
|
||||
&mut renderer,
|
||||
&theme,
|
||||
&renderer::Style {
|
||||
text_color: Color::WHITE,
|
||||
icon_color: Color::WHITE,
|
||||
scale_factor: scale as f64,
|
||||
},
|
||||
Layout::new(&node),
|
||||
mouse::Cursor::Unavailable,
|
||||
&viewport,
|
||||
);
|
||||
let draw_us = started.elapsed().as_micros();
|
||||
drop(view);
|
||||
let started = std::time::Instant::now();
|
||||
let pixels = Headless::screenshot(
|
||||
&mut renderer,
|
||||
Size::new((size.width * scale) as u32, (size.height * scale) as u32),
|
||||
scale,
|
||||
theme.cosmic().bg_color().into(),
|
||||
);
|
||||
let render_us = started.elapsed().as_micros();
|
||||
if matches!(frame, 0 | 4 | 5)
|
||||
&& let Some(dir) = std::env::var_os("FERESE_BENCH_IMAGES_DIR")
|
||||
{
|
||||
let path = PathBuf::from(dir);
|
||||
std::fs::create_dir_all(&path).unwrap();
|
||||
image::save_buffer(
|
||||
path.join(format!("{page:?}-{frame}.png")),
|
||||
&pixels,
|
||||
(size.width * scale) as u32,
|
||||
(size.height * scale) as u32,
|
||||
image::ColorType::Rgba8,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
for message in messages {
|
||||
drop(app.update(message));
|
||||
}
|
||||
eprintln!(
|
||||
"AUDIT {}",
|
||||
serde_json::json!({"backend":backend,"page":format!("{page:?}"),"frame":frame,"scenario":scenario,"width":size.width,"layout_us":layout_us,"draw_us":draw_us,"render_us":render_us})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user