aboutsummaryrefslogtreecommitdiff
path: root/src/server/render_scale_benchmark.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-14 22:36:04 +0300
committerGitHub <noreply@github.com>2026-09-14 22:36:04 +0300
commitd8b36691d10c6055293ad45324b22af8b8f570e5 (patch)
tree42f6ff4b7ba20a59884a994b38368edd02b16ae2 /src/server/render_scale_benchmark.rs
parent4c3b613c8470885df44f0844b8eaecca744c84fb (diff)
fix: avoid resending terminal cells for metadata updates (#4137)
Diffstat (limited to 'src/server/render_scale_benchmark.rs')
-rw-r--r--src/server/render_scale_benchmark.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/server/render_scale_benchmark.rs b/src/server/render_scale_benchmark.rs
index 7503f06d..82f7ba91 100644
--- a/src/server/render_scale_benchmark.rs
+++ b/src/server/render_scale_benchmark.rs
@@ -312,6 +312,91 @@ fn print_token_rule_profiles() {
}
}
+fn print_surface_reuse_profiles() {
+ println!("surface encode + decode at {COLS}x{ROWS}");
+ println!(" layout panes cells_changed reuse median_us bytes_per_update");
+ for (label, build) in [
+ ("background", workspaces as fn(usize) -> Vec<Workspace>),
+ ("active", active_panes),
+ ] {
+ for count in [1, 15] {
+ let mut pipeline = RenderPipeline::new(build(count));
+ pipeline.render_once();
+ let rendered = super::client_shell::render_pane_surface(
+ &mut pipeline.app,
+ Some(crate::ui::TabSurfaceTarget {
+ workspace_index: 0,
+ tab_index: 0,
+ }),
+ Rect::new(0, 0, COLS, ROWS),
+ true,
+ false,
+ HostCellSize::default(),
+ &pipeline.graphics_delivery,
+ 1,
+ );
+ let surface = PaneSurfaceFrame {
+ boot_id: "bench-boot".into(),
+ projection_revision: 1,
+ surface_revision: 0,
+ frame: rendered.frame,
+ panes: rendered.panes,
+ splits: rendered.splits,
+ popup: rendered.popup,
+ graphics: rendered.graphics,
+ };
+ for cells_changed in [false, true] {
+ for enabled in [false, true] {
+ let mut state = super::render_stream::ClientRenderState::new(
+ crate::protocol::RenderEncoding::SemanticFrame,
+ );
+ state.enable_surface_reuse(enabled);
+ let mut decoder = crate::protocol::surface_reuse::Decoder::default();
+ let initial = state.prepare_pane_surface(surface.clone()).unwrap();
+ if enabled {
+ decoder.decode(initial.message().clone()).unwrap();
+ }
+ state.commit_sent_frame(initial);
+ let mut samples = Vec::new();
+ let mut bytes_per_update = 0;
+ for index in 0..WARMUP_COUNT + SAMPLE_COUNT {
+ let mut candidate = surface.clone();
+ candidate.projection_revision = index as u64 + 2;
+ if cells_changed {
+ candidate.frame.cells[0].symbol =
+ if index % 2 == 0 { "a" } else { "b" }.into();
+ }
+ let started = Instant::now();
+ let prepared = state.prepare_pane_surface(candidate).unwrap();
+ let mut bytes = Vec::new();
+ crate::protocol::write_message(&mut bytes, prepared.message()).unwrap();
+ bytes_per_update = bytes.len();
+ let decoded = crate::protocol::read_message(
+ &mut bytes.as_slice(),
+ crate::protocol::MAX_FRAME_SIZE,
+ )
+ .unwrap();
+ black_box(if enabled {
+ decoder.decode(decoded).unwrap()
+ } else {
+ decoded
+ });
+ state.commit_sent_frame(prepared);
+ if index >= WARMUP_COUNT {
+ samples.push(started.elapsed());
+ }
+ }
+ let stats = summarize(samples);
+ println!(
+ " {label:<10} {count:>5} {cells_changed:>13} {enabled:>5} {:>9} {bytes_per_update:>16}",
+ stats.median_us
+ );
+ }
+ }
+ }
+ }
+}
+
#[tokio::test(flavor = "current_thread")]
#[ignore = "manual client-rendered pipeline scaling profile"]
async fn render_scale_profile() {
@@ -320,4 +405,5 @@ async fn render_scale_profile() {
print_profiles("active panes (one workspace)", active_panes);
print_snapshot_encoding_profiles("active panes", active_panes);
print_token_rule_profiles();
+ print_surface_reuse_profiles();
}