Only draw when terminal state has changed

This is achieved by setting a `dirty` flag when the terminal receives
an event that causes visible state to change. The implementation is
pretty much crap because most methods know about the flag.

Figure out something better later.
This commit is contained in:
Joe Wilm 2016-06-07 21:15:53 -07:00
parent 781c67f0a0
commit 6c82fa9d7b
No known key found for this signature in database
GPG Key ID: 39B57C6972F518DA
2 changed files with 49 additions and 16 deletions

View File

@ -193,26 +193,30 @@ fn main() {
gl::Clear(gl::COLOR_BUFFER_BIT);
}
{
let _sampler = meter.sampler();
if terminal.dirty() {
{
let _sampler = meter.sampler();
renderer.with_api(&props, |mut api| {
// Draw the grid
api.render_grid(terminal.grid(), &mut glyph_cache);
// Also draw the cursor
api.render_cursor(terminal.cursor(), &mut glyph_cache);
})
}
// Draw render timer
let timing = format!("{:.3} usec", meter.average());
let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
renderer.with_api(&props, |mut api| {
// Draw the grid
api.render_grid(terminal.grid(), &mut glyph_cache);
api.render_string(&timing[..], &mut glyph_cache, &color);
});
// Also draw the cursor
api.render_cursor(terminal.cursor(), &mut glyph_cache);
})
terminal.clear_dirty();
window.swap_buffers().unwrap();
}
// Draw render timer
let timing = format!("{:.3} usec", meter.average());
let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
renderer.with_api(&props, |mut api| {
api.render_string(&timing[..], &mut glyph_cache, &color);
});
window.swap_buffers().unwrap();
}
// TODO handle child cleanup

View File

@ -93,6 +93,9 @@ pub struct Term {
/// Cell attributes
attr: grid::CellFlags,
/// Whether state has changed and needs to be updated.
dirty: bool,
}
impl Term {
@ -115,9 +118,18 @@ impl Term {
tty: tty,
tabs: tabs,
attr: CellFlags::empty(),
dirty: false,
}
}
pub fn dirty(&self) -> bool {
self.dirty
}
pub fn clear_dirty(&mut self) {
self.dirty = false;
}
pub fn grid(&self) -> &Grid {
&self.grid
}
@ -153,6 +165,7 @@ impl Term {
/// Set character in current cursor position
fn set_char(&mut self, c: char) {
self.dirty = true;
if self.cursor.x == self.grid.num_cols() as u16 {
self.cursor.y += 1;
self.cursor.x = 0;
@ -187,14 +200,17 @@ impl ansi::Handler for Term {
fn goto(&mut self, x: i64, y: i64) {
println!("goto: x={}, y={}", x, y);
self.dirty = true;
self.cursor.goto(x as u16, y as u16);
}
fn goto_row(&mut self, y: i64) {
self.dirty = true;
println!("goto_row: {}", y);
let x = self.cursor_x();
self.cursor.goto(x, y as u16);
}
fn goto_col(&mut self, x: i64) {
self.dirty = true;
println!("goto_col: {}", x);
let y = self.cursor_y();
self.cursor.goto(x as u16, y);
@ -203,21 +219,25 @@ impl ansi::Handler for Term {
fn insert_blank(&mut self, num: i64) { println!("insert_blank: {}", num); }
fn move_up(&mut self, rows: i64) {
self.dirty = true;
println!("move_up: {}", rows);
self.cursor.advance(-rows, 0);
}
fn move_down(&mut self, rows: i64) {
self.dirty = true;
println!("move_down: {}", rows);
self.cursor.advance(rows, 0);
}
fn move_forward(&mut self, cols: i64) {
self.dirty = true;
println!("move_forward: {}", cols);
self.cursor.advance(0, cols);
}
fn move_backward(&mut self, spaces: i64) {
self.dirty = true;
println!("move_backward: {}", spaces);
self.cursor.advance(0, -spaces);
}
@ -226,6 +246,7 @@ impl ansi::Handler for Term {
fn move_down_and_cr(&mut self, rows: i64) { println!("move_down_and_cr: {}", rows); }
fn move_up_and_cr(&mut self, rows: i64) { println!("move_up_and_cr: {}", rows); }
fn put_tab(&mut self, mut count: i64) {
self.dirty = true;
println!("put_tab: {}", count);
let mut x = self.cursor_x();
@ -245,6 +266,8 @@ impl ansi::Handler for Term {
/// Backspace `count` characters
#[inline]
fn backspace(&mut self, count: i64) {
println!("backspace");
self.dirty = true;
self.cursor.x -= 1;
self.set_char(' ');
}
@ -252,12 +275,15 @@ impl ansi::Handler for Term {
/// Carriage return
#[inline]
fn carriage_return(&mut self) {
println!("carriage_return");
self.dirty = true;
self.cursor.x = 0;
}
/// Linefeed
#[inline]
fn linefeed(&mut self) {
self.dirty = true;
println!("linefeed");
// TODO handle scroll? not clear what parts of this the pty handle
if self.cursor_y() + 1 == self.grid.num_rows() as u16 {
@ -284,6 +310,7 @@ impl ansi::Handler for Term {
fn save_cursor_position(&mut self) { println!("save_cursor_position"); }
fn restore_cursor_position(&mut self) { println!("restore_cursor_position"); }
fn clear_line(&mut self, mode: ansi::LineClearMode) {
self.dirty = true;
println!("clear_line: {:?}", mode);
match mode {
ansi::LineClearMode::Right => {
@ -298,6 +325,7 @@ impl ansi::Handler for Term {
}
}
fn clear_screen(&mut self, mode: ansi::ClearMode) {
self.dirty = true;
println!("clear_screen: {:?}", mode);
match mode {
ansi::ClearMode::Below => {
@ -321,6 +349,7 @@ impl ansi::Handler for Term {
fn clear_tabs(&mut self, mode: ansi::TabulationClearMode) { println!("clear_tabs: {:?}", mode); }
fn reset_state(&mut self) { println!("reset_state"); }
fn reverse_index(&mut self) {
self.dirty = true;
println!("reverse_index");
// if cursor is at the top
if self.cursor.y == 0 {