1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-26 06:42:12 +03:00

wezterm: tidy up atlas reallocation code path

refs: #306
This commit is contained in:
Wez Furlong 2020-10-23 17:58:45 -07:00
parent f4066747d2
commit 18c2c6838a

View File

@ -723,7 +723,54 @@ impl WindowCallbacks for TermWindow {
} }
fn paint_opengl(&mut self, frame: &mut glium::Frame) { fn paint_opengl(&mut self, frame: &mut glium::Frame) {
self.paint_opengl_pass(frame, 0); self.check_for_config_reload();
let config = configuration();
let start = std::time::Instant::now();
{
let palette = self.palette();
let background_alpha = (config.window_background_opacity * 255.0) as u8;
let background = rgbcolor_alpha_to_window_color(palette.background, background_alpha);
let (r, g, b, a) = background.to_tuple_rgba();
frame.clear_color_srgb(r, g, b, a);
}
for pass in 0.. {
match self.paint_opengl_pass(frame) {
Ok(_) => break,
Err(err) => {
if let Some(&OutOfTextureSpace { size: Some(size) }) =
err.downcast_ref::<OutOfTextureSpace>()
{
let result = if pass == 0 {
// Let's try clearing out the atlas and trying again
self.render_state.clear_texture_atlas(&self.render_metrics)
} else {
log::error!("grow texture atlas to {}", size);
self.recreate_texture_atlas(Some(size))
};
if let Err(err) = result {
log::error!(
"Failed to {} texture: {}",
if pass == 0 { "clear" } else { "resize" },
err
);
break;
}
} else {
log::error!("paint_opengl_pass failed: {}", err);
break;
}
}
}
}
self.call_draw(frame).ok();
log::debug!("paint_pane_opengl elapsed={:?}", start.elapsed());
metrics::value!("gui.paint.opengl", start.elapsed());
self.update_title();
} }
} }
@ -2310,31 +2357,17 @@ impl TermWindow {
Ok(()) Ok(())
} }
fn paint_opengl_pass(&mut self, frame: &mut glium::Frame, pass: usize) { fn paint_opengl_pass(&mut self, frame: &mut glium::Frame) -> anyhow::Result<()> {
let panes = self.get_panes_to_render(); let panes = self.get_panes_to_render();
if panes.is_empty() { if panes.is_empty() {
frame.clear_color_srgb(0., 0., 0., 1.); frame.clear_color_srgb(0., 0., 0., 1.);
return; return Ok(());
}
self.check_for_config_reload();
let config = configuration();
let start = std::time::Instant::now();
{
let palette = self.palette();
let background_alpha = (config.window_background_opacity * 255.0) as u8;
let background = rgbcolor_alpha_to_window_color(palette.background, background_alpha);
let (r, g, b, a) = background.to_tuple_rgba();
frame.clear_color_srgb(r, g, b, a);
} }
if let Some(pane) = self.get_active_pane_or_overlay() { if let Some(pane) = self.get_active_pane_or_overlay() {
let splits = self.get_splits(); let splits = self.get_splits();
for split in &splits { for split in &splits {
self.paint_split_opengl(split, &pane).ok(); self.paint_split_opengl(split, &pane)?;
} }
} }
@ -2342,46 +2375,10 @@ impl TermWindow {
if pos.is_active { if pos.is_active {
self.update_text_cursor(&pos.pane); self.update_text_cursor(&pos.pane);
} }
if let Err(err) = self.paint_pane_opengl(&pos) { self.paint_pane_opengl(&pos)?;
if let Some(&OutOfTextureSpace { size: Some(size) }) =
err.downcast_ref::<OutOfTextureSpace>()
{
if pass == 0 {
// Let's try clearing out the atlas and trying again
if let Ok(()) = self.render_state.clear_texture_atlas(&self.render_metrics)
{
log::trace!("cleared atlas");
return self.paint_opengl_pass(frame, pass + 1);
}
}
log::error!("out of texture space, allocating {}", size);
match self.recreate_texture_atlas(Some(size)) {
Ok(_) => {
// Recursively initiate a new paint
return self.paint_opengl_pass(frame, pass + 1);
}
Err(err) => {
log::error!("failed recreate atlas with size {}: {}", size, err);
// Failed to increase the size.
// This might happen if a lot of images have been displayed in the
// terminal over time and we've hit a texture size limit.
// Let's just try recreating at the current size.
self.recreate_texture_atlas(None)
.expect("OutOfTextureSpace and failed to recreate atlas");
}
}
} else {
log::error!("paint_pane_opengl failed: {}", err);
}
}
} }
self.call_draw(frame).ok(); Ok(())
log::debug!("paint_pane_opengl elapsed={:?}", start.elapsed());
metrics::value!("gui.paint.opengl", start.elapsed());
self.update_title();
} }
fn paint_pane_opengl(&mut self, pos: &PositionedPane) -> anyhow::Result<()> { fn paint_pane_opengl(&mut self, pos: &PositionedPane) -> anyhow::Result<()> {