diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-04-16 15:02:42 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-04-16 15:05:31 -0700 |
commit | ace7ffb714ce5314c665f28945ee0f3f1664f9ca (patch) | |
tree | 191088837e3a6c6fa6a38aae59431efa88c86cb9 /termbox | |
parent | ef73b04e744a69973208096a49d4ae52ddbb84d2 (diff) | |
download | mu-ace7ffb714ce5314c665f28945ee0f3f1664f9ca.tar.gz |
3824 - experiment: stop buffering in termbox
Now it's much more apparent why things are slow. You can see each repaint happening. Already I fixed one performance bug -- in clear-rest-of-screen. Since this subverts Mu's fake screen there may be bugs. Another salubrious side effect: I've finally internalized that switching to raw mode doesn't have to clear the screen. That was just an artifact of how termbox abstracted operations. Now I can conceive of using termbox to build a repl as well. (I was inspired to poke into termbox internals by http://viewsourcecode.org/snaptoken/kilo and https://github.com/antirez/linenoise)
Diffstat (limited to 'termbox')
-rw-r--r-- | termbox/termbox.c | 151 | ||||
-rw-r--r-- | termbox/termbox.h | 33 | ||||
-rw-r--r-- | termbox/x.cc | 7 |
3 files changed, 14 insertions, 177 deletions
diff --git a/termbox/termbox.c b/termbox/termbox.c index e7757f9a..7fff7d7c 100644 --- a/termbox/termbox.c +++ b/termbox/termbox.c @@ -23,20 +23,11 @@ extern int wcwidth (wchar_t); #include "output.inl" #include "input.inl" -struct cellbuf { - int width; - int height; - struct tb_cell *cells; -}; - -#define CELL(buf, x, y) (buf)->cells[(y) * (buf)->width + (x)] #define IS_CURSOR_HIDDEN(cx, cy) (cx == -1 || cy == -1) #define LAST_COORD_INIT -1 static struct termios orig_tios; -static struct cellbuf back_buffer; -static struct cellbuf front_buffer; static struct bytebuffer output_buffer; static struct bytebuffer input_buffer; @@ -57,11 +48,6 @@ static uint16_t foreground = TB_WHITE; static void write_cursor(int x, int y); static void write_sgr(uint16_t fg, uint16_t bg); -static void cellbuf_init(struct cellbuf *buf, int width, int height); -static void cellbuf_resize(struct cellbuf *buf, int width, int height); -static void cellbuf_clear(struct cellbuf *buf); -static void cellbuf_free(struct cellbuf *buf); - static void update_size(void); static void update_term_size(void); static void send_attr(uint16_t fg, uint16_t bg); @@ -121,14 +107,8 @@ int tb_init(void) bytebuffer_puts(&output_buffer, funcs[T_HIDE_CURSOR]); bytebuffer_puts(&output_buffer, funcs[T_ENTER_MOUSE]); bytebuffer_puts(&output_buffer, funcs[T_ENTER_BRACKETED_PASTE]); - send_clear(); update_term_size(); - cellbuf_init(&back_buffer, termw, termh); - cellbuf_init(&front_buffer, termw, termh); - cellbuf_clear(&back_buffer); - cellbuf_clear(&front_buffer); - return 0; } @@ -151,8 +131,6 @@ void tb_shutdown(void) close(winch_fds[0]); close(winch_fds[1]); - cellbuf_free(&back_buffer); - cellbuf_free(&front_buffer); bytebuffer_free(&output_buffer); bytebuffer_free(&input_buffer); termw = termh = -1; @@ -163,65 +141,6 @@ int tb_is_active(void) return termw != -1; } -static void tb_repaint(bool force) { - int x,y,w,i; - struct tb_cell *back, *front; - - assert(termw != -1); - - /* invalidate cursor position */ - lastx = LAST_COORD_INIT; - lasty = LAST_COORD_INIT; - - if (buffer_size_change_request) { - update_size(); - buffer_size_change_request = 0; - } - - for (y = 0; y < front_buffer.height; ++y) { - for (x = 0; x < front_buffer.width; ) { - back = &CELL(&back_buffer, x, y); - front = &CELL(&front_buffer, x, y); - w = wcwidth(back->ch); - if (w < 1) w = 1; - if (!force && 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)) { - // Not enough room for wide ch, so send spaces - for (i = x; i < front_buffer.width; ++i) { - send_char(i, y, ' '); - } - } else { - send_char(x, y, back->ch); - for (i = 1; i < w; ++i) { - front = &CELL(&front_buffer, x + i, y); - front->ch = 0; - front->fg = back->fg; - front->bg = back->bg; - } - } - x += w; - } - } - if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) - write_cursor(cursor_x, cursor_y); - bytebuffer_flush(&output_buffer, inout); -} - -void tb_present(void) -{ - tb_repaint(false); -} - -void tb_sync(void) -{ - tb_repaint(true); -} - void tb_set_cursor(int cx, int cy) { assert(termw != -1); @@ -233,22 +152,15 @@ void tb_set_cursor(int cx, int cy) cursor_y = cy; if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); + bytebuffer_flush(&output_buffer, inout); } void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg) { assert(termw != -1); - if ((unsigned)x >= (unsigned)back_buffer.width) - return; - if ((unsigned)y >= (unsigned)back_buffer.height) - return; - struct tb_cell c = {ch, fg, bg}; - CELL(&back_buffer, x, y) = c; -} - -struct tb_cell *tb_cell_buffer() -{ - return back_buffer.cells; + send_attr(fg, bg); + send_char(x, y, ch); + bytebuffer_flush(&output_buffer, inout); } int tb_poll_event(struct tb_event *event) @@ -285,7 +197,7 @@ void tb_clear(void) update_size(); buffer_size_change_request = 0; } - cellbuf_clear(&back_buffer); + send_clear(); } void tb_set_clear_attributes(uint16_t fg, uint16_t bg) @@ -334,56 +246,6 @@ static void write_sgr(uint16_t fg, uint16_t bg) { WRITE_LITERAL("m"); } -static void cellbuf_init(struct cellbuf *buf, int width, int height) -{ - buf->cells = (struct tb_cell*)malloc(sizeof(struct tb_cell) * width * height); - assert(buf->cells); - buf->width = width; - buf->height = height; -} - -static void cellbuf_resize(struct cellbuf *buf, int width, int height) -{ - if (buf->width == width && buf->height == height) - return; - - int oldw = buf->width; - int oldh = buf->height; - struct tb_cell *oldcells = buf->cells; - - cellbuf_init(buf, width, height); - cellbuf_clear(buf); - - int minw = (width < oldw) ? width : oldw; - int minh = (height < oldh) ? height : oldh; - int i; - - for (i = 0; i < minh; ++i) { - struct tb_cell *csrc = oldcells + (i * oldw); - struct tb_cell *cdst = buf->cells + (i * width); - memcpy(cdst, csrc, sizeof(struct tb_cell) * minw); - } - - free(oldcells); -} - -static void cellbuf_clear(struct cellbuf *buf) -{ - int i; - int ncells = buf->width * buf->height; - - for (i = 0; i < ncells; ++i) { - buf->cells[i].ch = ' '; - buf->cells[i].fg = foreground; - buf->cells[i].bg = background; - } -} - -static void cellbuf_free(struct cellbuf *buf) -{ - free(buf->cells); -} - static void get_term_size(int *w, int *h) { struct winsize sz; @@ -478,9 +340,6 @@ static void sigwinch_handler(int xxx) static void update_size(void) { update_term_size(); - cellbuf_resize(&back_buffer, termw, termh); - cellbuf_resize(&front_buffer, termw, termh); - cellbuf_clear(&front_buffer); send_clear(); } diff --git a/termbox/termbox.h b/termbox/termbox.h index c6cda6e1..a86bc6ca 100644 --- a/termbox/termbox.h +++ b/termbox/termbox.h @@ -9,18 +9,12 @@ extern "C" { /*** 1. Controlling the screen. */ /* The screen is a 2D array of cells. */ -struct tb_cell { - uint32_t ch; /* unicode character */ - uint16_t fg; /* foreground color (0-255) and attributes */ - uint16_t bg; /* background color (0-255) and attributes */ -}; -/* Names for some colors in tb_cell.fg and tb_cell.bg. */ +/* Names for some colors. */ #define TB_BLACK 232 #define TB_WHITE 255 -/* Colors in tb_cell can be combined using bitwise-OR with multiple - * of the following attributes. */ +/* Some attributes of screen cells that can be combined with colors using bitwise-OR. */ #define TB_BOLD 0x0100 #define TB_UNDERLINE 0x0200 #define TB_REVERSE 0x0400 @@ -44,34 +38,17 @@ int tb_is_active(void); int tb_width(void); int tb_height(void); -/* Update the screen with internal state. Most methods below modify just the - * internal state of the screen. Changes won't be visible until you call - * 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() - * are called. */ -struct tb_cell *tb_cell_buffer(); - -/* Clear the internal screen state using either TB_DEFAULT or the - * color/attributes set by tb_set_clear_attributes(). */ +/* Clear the screen. */ void tb_clear(void); void tb_set_clear_attributes(uint16_t fg, uint16_t bg); -/* Move the cursor. Upper-left character is (0, 0). - */ +/* Move the cursor. Upper-left character is (0, 0). */ void tb_set_cursor(int cx, int cy); /* To hide the cursor, call tb_set_cursor(TB_HIDE_CURSOR, TB_HIDE_CURSOR). * Cursor starts out hidden. */ #define TB_HIDE_CURSOR -1 -/* Modify a specific cell of the screen. Don't forget to call tb_present() to - * commit your changes. */ +/* Modify a specific cell of the screen. */ void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg); /*** 2. Controlling keyboard events. */ diff --git a/termbox/x.cc b/termbox/x.cc index 73373818..5c7fb0a6 100644 --- a/termbox/x.cc +++ b/termbox/x.cc @@ -2,10 +2,11 @@ #include"termbox.h" int main() { - tb_event event; tb_init(); - tb_poll_event(&event); + tb_clear(); + tb_change_cell(0, 0, 'a', TB_WHITE, TB_BLACK); + tb_event x; + tb_poll_event(&x); tb_shutdown(); - std::cerr << (int)event.type << '\n'; return 0; } |