diff options
author | Joe Wilm <joe@jwilm.com> | 2016-11-28 14:13:11 -0800 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-12-11 20:23:41 -0800 |
commit | 30bee80a6902eb09c51bed9c9f54c7617c4d53db (patch) | |
tree | 187853fdf17d3382595be8a416e604c6f2bea0f0 /src/renderer/mod.rs | |
parent | 941818d88ebc1f0d90ef9b1ef7d1313174afb36b (diff) | |
download | alacritty-30bee80a6902eb09c51bed9c9f54c7617c4d53db.tar.gz alacritty-30bee80a6902eb09c51bed9c9f54c7617c4d53db.zip |
Refactor cell selection out of renderer
The terminal now has a `renderable_cells()` function that returns a
`RenderableCellIter` iterator. This allows reuse of the cell selection
code by multiple renderers, makes it testable, and makes it
independently optimizable.
The render API now takes an `Iterator<Item=IndexedCell>` to support both
the new renderable cells iterator and the `render_string()` method which
generates its own iterator.
The `vim_large_window_scoll` ref test was added here because it provides
a nice large and busy grid to benchmark the cell selection with.
Diffstat (limited to 'src/renderer/mod.rs')
-rw-r--r-- | src/renderer/mod.rs | 144 |
1 files changed, 61 insertions, 83 deletions
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index dfaf6b30..2868a226 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -24,10 +24,10 @@ use font::{self, Rasterizer, RasterizedGlyph, FontDesc, GlyphKey, FontKey}; use gl::types::*; use gl; use notify::{Watcher as WatcherApi, RecommendedWatcher as Watcher, op}; +use index::{Line, Column}; use config::Config; -use grid::Grid; -use term::{self, cell, Cell}; +use term::{self, cell, IndexedCell, Cell}; use super::Rgb; @@ -286,7 +286,7 @@ impl Batch { } } - pub fn add_item(&mut self, row: f32, col: f32, cell: &Cell, glyph: &Glyph) { + pub fn add_item(&mut self, cell: &IndexedCell, glyph: &Glyph) { if self.is_empty() { self.tex = glyph.tex_id; } @@ -310,9 +310,9 @@ impl Batch { ::term::cell::Color::Ansi(ansi) => self.colors[ansi as usize], }; - let mut instance = InstanceData { - col: col, - row: row, + self.instances.push(InstanceData { + col: cell.column.0 as f32, + row: cell.line.0 as f32, top: glyph.top, left: glyph.left, @@ -331,19 +331,7 @@ impl Batch { bg_r: bg.r as f32, bg_g: bg.g as f32, bg_b: bg.b as f32, - }; - - if cell.flags.contains(cell::INVERSE) { - instance.r = bg.r as f32; - instance.g = bg.g as f32; - instance.b = bg.b as f32; - - instance.bg_r = fg.r as f32; - instance.bg_g = fg.g as f32; - instance.bg_b = fg.b as f32; - } - - self.instances.push(instance); + }); } #[inline] @@ -631,6 +619,19 @@ impl QuadRenderer { } impl<'a> RenderApi<'a> { + pub fn clear(&self) { + let color = self.colors[::ansi::Color::Background as usize]; + unsafe { + gl::ClearColor( + color.r as f32 / 255.0, + color.g as f32 / 255.0, + color.b as f32 / 255.0, + 1.0 + ); + gl::Clear(gl::COLOR_BUFFER_BIT); + } + } + fn render_batch(&mut self) { unsafe { gl::BufferSubData(gl::ARRAY_BUFFER, 0, self.batch.size() as isize, @@ -663,36 +664,32 @@ impl<'a> RenderApi<'a> { /// optimization. pub fn render_string( &mut self, - s: &str, + string: &str, glyph_cache: &mut GlyphCache, color: &::term::cell::Color, ) { - let row = 40.0; - let mut col = 100.0; - - for c in s.chars() { - let glyph_key = GlyphKey { - font_key: glyph_cache.font_key, - size: glyph_cache.font_size, - c: c - }; - - if let Some(glyph) = glyph_cache.get(&glyph_key, self) { - let cell = Cell { + let line = Line(23); + let col = Column(0); + + let cells = string.chars() + .enumerate() + .map(|(i, c)| IndexedCell { + line: line, + column: col + i, + inner: Cell { c: c, - fg: color.clone(), - bg: cell::Color::Rgb(Rgb { r: 0, g: 0, b: 0}), - flags: cell::INVERSE, - }; - self.add_render_item(row, col, &cell, glyph); - } + bg: *color, + fg: cell::Color::Rgb(Rgb { r: 0, g: 0, b: 0}), + flags: cell::Flags::empty(), + } + }) + .collect::<Vec<_>>(); - col += 1.0; - } + self.render_grid(cells.into_iter(), glyph_cache); } #[inline] - fn add_render_item(&mut self, row: f32, col: f32, cell: &Cell, glyph: &Glyph) { + fn add_render_item(&mut self, cell: &IndexedCell, glyph: &Glyph) { // Flush batch if tex changing if !self.batch.is_empty() { if self.batch.tex != glyph.tex_id { @@ -700,7 +697,7 @@ impl<'a> RenderApi<'a> { } } - self.batch.add_item(row, col, cell, glyph); + self.batch.add_item(cell, glyph); // Render batch and clear if it's full if self.batch.full() { @@ -708,51 +705,32 @@ impl<'a> RenderApi<'a> { } } - pub fn render_grid( + pub fn render_grid<I>( &mut self, - grid: &Grid<Cell>, + occupied_cells: I, glyph_cache: &mut GlyphCache - ) { - // TODO should be built into renderer - let color = self.colors[::ansi::Color::Background as usize]; - unsafe { - gl::ClearColor( - color.r as f32 / 255.0, - color.g as f32 / 255.0, - color.b as f32 / 255.0, - 1.0 - ); - gl::Clear(gl::COLOR_BUFFER_BIT); - } - - for (i, line) in grid.lines().enumerate() { - for (j, cell) in line.cells().enumerate() { - // Skip empty cells - if cell.c == ' ' && cell.bg == cell::Color::Ansi(::ansi::Color::Background) && - !cell.flags.contains(cell::INVERSE) - { - continue; - } - - // Get font key for cell - // FIXME this is super inefficient. - let mut font_key = glyph_cache.font_key; - if cell.flags.contains(cell::BOLD) { - font_key = glyph_cache.bold_key; - } else if cell.flags.contains(cell::ITALIC) { - font_key = glyph_cache.italic_key; - } + ) + where I: Iterator<Item=::term::IndexedCell> + { + for cell in occupied_cells { + // Get font key for cell + // FIXME this is super inefficient. + let mut font_key = glyph_cache.font_key; + if cell.flags.contains(cell::BOLD) { + font_key = glyph_cache.bold_key; + } else if cell.flags.contains(cell::ITALIC) { + font_key = glyph_cache.italic_key; + } - let glyph_key = GlyphKey { - font_key: font_key, - size: glyph_cache.font_size, - c: cell.c - }; + let glyph_key = GlyphKey { + font_key: font_key, + size: glyph_cache.font_size, + c: cell.c + }; - // Add cell to batch if glyph available - if let Some(glyph) = glyph_cache.get(&glyph_key, self) { - self.add_render_item(i as f32, j as f32, cell, glyph); - } + // Add cell to batch if glyph available + if let Some(glyph) = glyph_cache.get(&glyph_key, self) { + self.add_render_item(&cell, glyph); } } } |