diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-08-29 23:50:29 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-08-29 23:51:18 -0700 |
commit | 930e9eae27f354b5ddeda212231b89314cc2802e (patch) | |
tree | 172e2187da8997ac83c2f9ebdd2211a9335c8124 | |
parent | 5cde7d513e7c228dba61729ae1c25b2e119fb5f8 (diff) | |
download | mu-930e9eae27f354b5ddeda212231b89314cc2802e.tar.gz |
2113 - stop updating entire screen on tb_present()
Mu still isn't so optimized that I can be profligate with spare cycles. Instead we'll follow termbox-go's example and create a new API routine called tb_sync() (after discussion with termbox's author). Now we only need use tb_sync() on ctrl-l. For everything else use the optimized render. Now I think I've eradicated all signs of "cursor thrashing" during refresh, in spite of how slow mu is as an interpreted language. We only render the whole screen in some situations, and only if there's no more input, and even then we only refresh the parts of the screen that changed. Thanks Jack and Caleb Couch for providing the impetus behind commits 2109-2113. I've been lazy about writing tests for all this, but it's still good to know I could, if I wanted to.
-rw-r--r-- | 070display.cc | 10 | ||||
-rw-r--r-- | 071print.mu | 10 | ||||
-rw-r--r-- | termbox/termbox.c | 9 | ||||
-rw-r--r-- | termbox/termbox.h | 3 |
4 files changed, 32 insertions, 0 deletions
diff --git a/070display.cc b/070display.cc index 2c52534e..8c02bc57 100644 --- a/070display.cc +++ b/070display.cc @@ -49,6 +49,16 @@ case CLEAR_DISPLAY: { } :(before "End Primitive Recipe Declarations") +SYNC_DISPLAY, +:(before "End Primitive Recipe Numbers") +Recipe_ordinal["sync-display"] = SYNC_DISPLAY; +:(before "End Primitive Recipe Implementations") +case SYNC_DISPLAY: { + tb_sync(); + break; +} + +:(before "End Primitive Recipe Declarations") CLEAR_LINE_ON_DISPLAY, :(before "End Primitive Recipe Numbers") Recipe_ordinal["clear-line-on-display"] = CLEAR_LINE_ON_DISPLAY; diff --git a/071print.mu b/071print.mu index 186f5913..6aeb2042 100644 --- a/071print.mu +++ b/071print.mu @@ -65,6 +65,16 @@ recipe clear-screen [ reply sc/same-as-ingredient:0 ] +recipe sync-screen [ + local-scope + sc:address:screen <- next-ingredient + { + break-if sc + sync-display + } + # do nothing for fake screens +] + recipe fake-screen-is-empty? [ local-scope sc:address:screen <- next-ingredient diff --git a/termbox/termbox.c b/termbox/termbox.c index c9ea6012..76d43753 100644 --- a/termbox/termbox.c +++ b/termbox/termbox.c @@ -181,6 +181,10 @@ void tb_present(void) front = &CELL(&front_buffer, x, y); w = wcwidth(back->ch); if (w < 1) w = 1; + if (memcmp(back, front, sizeof(struct tb_cell)) == 0) { + x += w; + continue; + } memcpy(front, back, sizeof(struct tb_cell)); send_attr(back->fg, back->bg); if (w > 1 && x >= front_buffer.width - (w - 1)) { @@ -205,6 +209,11 @@ void tb_present(void) bytebuffer_flush(&output_buffer, inout); } +void tb_sync(void) { + cellbuf_clear(&front_buffer); + tb_present(); +} + void tb_set_cursor(int cx, int cy) { assert(termw != -1); diff --git a/termbox/termbox.h b/termbox/termbox.h index c629b01c..a94d2b85 100644 --- a/termbox/termbox.h +++ b/termbox/termbox.h @@ -49,6 +49,9 @@ int tb_height(void); * tb_present(). */ void tb_present(void); +/* Variant of tb_present() that always refreshes the entire screen. */ +void tb_sync(void); + /* Returns a pointer to the internal screen state: a 1D array of cells in * raster order. You'll need to call tb_width() and tb_height() for the * array's dimensions. The array stays valid until tb_clear() or tb_present() |