From 0141d340f39f6310d3906b8fe57492d0c0d09a46 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 23 Aug 2022 17:39:56 -0700 Subject: [PATCH] gui: cache get_lines_with_hyperlinks_applied If the pane is unchanged and we're at the same viewport, cache the values from the last call. --- wezterm-gui/src/termwindow/mod.rs | 17 ++++++++-- wezterm-gui/src/termwindow/render.rs | 50 +++++++++++++++++++++------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/wezterm-gui/src/termwindow/mod.rs b/wezterm-gui/src/termwindow/mod.rs index 475685006..f7d9dd55d 100644 --- a/wezterm-gui/src/termwindow/mod.rs +++ b/wezterm-gui/src/termwindow/mod.rs @@ -49,13 +49,13 @@ use smol::channel::Sender; use smol::Timer; use std::cell::{RefCell, RefMut}; use std::collections::HashMap; -use std::ops::Add; +use std::ops::{Add, Range}; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use termwiz::hyperlink::Hyperlink; -use termwiz::surface::SequenceNo; +use termwiz::surface::{Line, SequenceNo}; use wezterm_dynamic::Value; use wezterm_font::FontConfiguration; use wezterm_gui_subcommands::GuiPosition; @@ -191,6 +191,19 @@ pub struct PaneState { bell_start: Option, pub mouse_terminal_coords: Option<(ClickPosition, StableRowIndex)>, + + /// Cache to avoid calling pane.get_lines_with_hyperlinks_applied + /// if the pane hasn't changed since the last render + pub logical_line_cache: Option, +} + +pub struct CachedLogicalLines { + // Key fields + pub seqno: SequenceNo, + pub stable_range: Range, + // Value fields + pub top: StableRowIndex, + pub lines: Rc>, } /// Data used when synchronously formatting pane and window titles diff --git a/wezterm-gui/src/termwindow/render.rs b/wezterm-gui/src/termwindow/render.rs index 2a4b8d996..ad83ebdff 100644 --- a/wezterm-gui/src/termwindow/render.rs +++ b/wezterm-gui/src/termwindow/render.rs @@ -10,7 +10,8 @@ use crate::renderstate::BorrowedLayers; use crate::shapecache::*; use crate::tabbar::{TabBarItem, TabEntry}; use crate::termwindow::{ - BorrowedShapeCacheKey, RenderState, ScrollHit, ShapedInfo, TermWindowNotif, UIItem, UIItemType, + BorrowedShapeCacheKey, CachedLogicalLines, RenderState, ScrollHit, ShapedInfo, TermWindowNotif, + UIItem, UIItemType, }; use crate::uniforms::UniformBuilder; use crate::utilsprites::RenderMetrics; @@ -1363,17 +1364,42 @@ impl super::TermWindow { None => dims.physical_top..dims.physical_top + dims.viewport_rows as StableRowIndex, }; - let start = Instant::now(); - let (top, vp_lines) = pos - .pane - .get_lines_with_hyperlinks_applied(stable_range, &self.config.hyperlink_rules); - metrics::histogram!("get_lines_with_hyperlinks_applied.latency", start.elapsed()); - log::trace!( - "get_lines_with_hyperlinks_applied took {:?}", - start.elapsed() - ); - stable_top = top; - lines = vp_lines; + let seqno = pos.pane.get_current_seqno(); + let mut state = self.pane_state(pos.pane.pane_id()); + + (stable_top, lines) = state + .logical_line_cache + .as_ref() + .and_then(|cached| { + if cached.seqno == seqno && cached.stable_range == stable_range { + Some((cached.top, Rc::clone(&cached.lines))) + } else { + None + } + }) + .unwrap_or_else(|| { + let start = Instant::now(); + let (top, vp_lines) = pos.pane.get_lines_with_hyperlinks_applied( + stable_range.clone(), + &self.config.hyperlink_rules, + ); + metrics::histogram!( + "get_lines_with_hyperlinks_applied.latency", + start.elapsed() + ); + log::trace!( + "get_lines_with_hyperlinks_applied took {:?}", + start.elapsed() + ); + let lines = Rc::new(vp_lines); + state.logical_line_cache = Some(CachedLogicalLines { + seqno, + stable_range, + top, + lines: Rc::clone(&lines), + }); + (top, lines) + }); } let gl_state = self.render_state.as_ref().unwrap();