172 lines
6.2 KiB
Rust
172 lines
6.2 KiB
Rust
//! 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})
|
|
);
|
|
}
|
|
}
|
|
}
|