diff --git a/wezterm-gui/src/quad.rs b/wezterm-gui/src/quad.rs index a2fcda29f..9ae18e586 100644 --- a/wezterm-gui/src/quad.rs +++ b/wezterm-gui/src/quad.rs @@ -354,7 +354,7 @@ impl TripleLayerQuadAllocatorTrait for HeapQuadAllocator { } pub enum TripleLayerQuadAllocator<'a> { - Gpu(BorrowedLayers<'a>), + Gpu(BorrowedLayers), Heap(&'a mut HeapQuadAllocator), } diff --git a/wezterm-gui/src/renderstate.rs b/wezterm-gui/src/renderstate.rs index 6569eb5b9..bd5ec2e79 100644 --- a/wezterm-gui/src/renderstate.rs +++ b/wezterm-gui/src/renderstate.rs @@ -7,7 +7,7 @@ use ::window::glium::buffer::{BufferMutSlice, Mapping}; use ::window::glium::{CapabilitiesSource, IndexBuffer, VertexBuffer}; use ::window::*; use anyhow::Context; -use std::cell::{RefCell, RefMut}; +use std::cell::{Ref, RefCell, RefMut}; use std::rc::Rc; use wezterm_font::FontConfiguration; @@ -169,6 +169,23 @@ impl RenderLayer { } } + pub fn quad_allocator(&self) -> TripleLayerQuadAllocator { + // We're creating a self-referential struct here to manage the lifetimes + // of these related items. The transmutes are safe because we're only + // transmuting the lifetimes (not the types), and we're keeping hold + // of the owner in the returned struct. + unsafe { + let vbs: Ref<'static, [TripleVertexBuffer; 3]> = std::mem::transmute(self.vb.borrow()); + let layer0: MappedQuads<'static> = std::mem::transmute(vbs[0].map()); + let layer1: MappedQuads<'static> = std::mem::transmute(vbs[1].map()); + let layer2: MappedQuads<'static> = std::mem::transmute(vbs[2].map()); + TripleLayerQuadAllocator::Gpu(BorrowedLayers { + layers: [layer0, layer1, layer2], + _owner: vbs, + }) + } + } + pub fn need_more_quads(&self, vb_idx: usize) -> Option { self.vb.borrow()[vb_idx].need_more_quads() } @@ -231,15 +248,20 @@ impl RenderLayer { } } -pub struct BorrowedLayers<'a>(pub [MappedQuads<'a>; 3]); +pub struct BorrowedLayers { + pub layers: [MappedQuads<'static>; 3], -impl<'a> TripleLayerQuadAllocatorTrait for BorrowedLayers<'a> { + // layers references _owner, so it must be dropped after layers. + _owner: Ref<'static, [TripleVertexBuffer; 3]>, +} + +impl TripleLayerQuadAllocatorTrait for BorrowedLayers { fn allocate(&mut self, layer_num: usize) -> anyhow::Result { - self.0[layer_num].allocate() + self.layers[layer_num].allocate() } fn extend_with(&mut self, layer_num: usize, vertices: &[Vertex]) { - self.0[layer_num].extend_with(vertices) + self.layers[layer_num].extend_with(vertices) } } diff --git a/wezterm-gui/src/termwindow/box_model.rs b/wezterm-gui/src/termwindow/box_model.rs index bdf434df3..530b8147a 100644 --- a/wezterm-gui/src/termwindow/box_model.rs +++ b/wezterm-gui/src/termwindow/box_model.rs @@ -4,7 +4,7 @@ use crate::customglyph::{BlockKey, Poly}; use crate::glyphcache::CachedGlyph; use crate::quad::{QuadImpl, QuadTrait, TripleLayerQuadAllocator, TripleLayerQuadAllocatorTrait}; use crate::termwindow::{ - BorrowedLayers, ColorEase, MouseCapture, RenderState, TermWindowNotif, UIItem, UIItemType, + ColorEase, MouseCapture, RenderState, TermWindowNotif, UIItem, UIItemType, }; use crate::utilsprites::RenderMetrics; use ::window::{RectF, WindowOps}; @@ -813,10 +813,7 @@ impl super::TermWindow { inherited_colors: Option<&ElementColors>, ) -> anyhow::Result<()> { let layer = gl_state.layer_for_zindex(element.zindex)?; - let vbs = layer.vb.borrow(); - let vb = [&vbs[0], &vbs[1], &vbs[2]]; - let mut layers = - TripleLayerQuadAllocator::Gpu(BorrowedLayers([vb[0].map(), vb[1].map(), vb[2].map()])); + let mut layers = layer.quad_allocator(); let colors = match &element.hover_colors { Some(hc) => { diff --git a/wezterm-gui/src/termwindow/render.rs b/wezterm-gui/src/termwindow/render.rs index 84d05971e..d72ceaa4f 100644 --- a/wezterm-gui/src/termwindow/render.rs +++ b/wezterm-gui/src/termwindow/render.rs @@ -6,7 +6,6 @@ use crate::quad::{ HeapQuadAllocator, QuadAllocator, QuadImpl, QuadTrait, TripleLayerQuadAllocator, TripleLayerQuadAllocatorTrait, }; -use crate::renderstate::BorrowedLayers; use crate::selection::SelectionRange; use crate::shapecache::*; use crate::tabbar::{TabBarItem, TabEntry}; @@ -2135,10 +2134,7 @@ impl super::TermWindow { let start = Instant::now(); let gl_state = self.render_state.as_ref().unwrap(); let layer = gl_state.layer_for_zindex(0)?; - let vbs = layer.vb.borrow(); - let vb = [&vbs[0], &vbs[1], &vbs[2]]; - let mut layers = - TripleLayerQuadAllocator::Gpu(BorrowedLayers([vb[0].map(), vb[1].map(), vb[2].map()])); + let mut layers = layer.quad_allocator(); log::trace!("quad map elapsed {:?}", start.elapsed()); metrics::histogram!("quad.map", start.elapsed());