From 35c8fd79c014c4f51a23585f6f445f16bf165798 Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Sun, 28 Jun 2015 23:37:04 +0200 Subject: [PATCH] speed up browsing backlog have a "beacon": single point where the link between an offset in the backlog and one in screen coordinates --- src/bin/miniview.c | 8 +- src/bin/termio.c | 1 - src/bin/termpty.c | 229 +++++++++++++++++++++++++++++-------------- src/bin/termpty.h | 18 ++-- src/bin/termptyops.c | 3 + 5 files changed, 173 insertions(+), 86 deletions(-) diff --git a/src/bin/miniview.c b/src/bin/miniview.c index 90b34779..477a7e99 100644 --- a/src/bin/miniview.c +++ b/src/bin/miniview.c @@ -140,11 +140,12 @@ Eina_Bool _is_top_bottom_reached(Miniview *mv) { int history_len; + Termpty *ty; EINA_SAFETY_ON_NULL_RETURN_VAL(mv, EINA_FALSE); - /* TODO: RESIZE */ - history_len = 42; //termpty_backscroll_len_get(ty); + ty = termio_pty_get(mv->termio); + history_len = termpty_backscroll_length(ty); if (( (- mv->img_hist) > (int)(mv->img_h - mv->rows - (mv->rows / 2))) && ( (- mv->img_hist) < (int)(history_len + (mv->rows / 2)))) @@ -522,8 +523,7 @@ _deferred_renderer(void *data) evas_object_geometry_get(mv->termio, &ox, &oy, &ow, &oh); if ((ow == 0) || (oh == 0)) return EINA_TRUE; - /* TODO: RESIZE */ - history_len = 42; //termpty_backscroll_len_get(ty); + history_len = termpty_backscroll_length(ty); evas_object_image_size_set(mv->img, mv->cols, mv->img_h); ow = mv->cols; diff --git a/src/bin/termio.c b/src/bin/termio.c index c9640793..c85fcca0 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -2041,7 +2041,6 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y, EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL); termpty_cellcomp_freeze(sd->pty); - /* TODO: RESIZE use/save the reference point */ for (y = c1y; y <= c2y; y++) { Termcell *cells; diff --git a/src/bin/termpty.c b/src/bin/termpty.c index 9a0a1438..b72510de 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c @@ -626,7 +626,49 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells) } #define BACKLOG_ROW_GET(Ty, Y) \ - (&Ty->back[(Ty->backsize + ty->backpos - (Y)) % Ty->backsize]) + (&Ty->back[(Ty->backsize + ty->backpos - ((Y) - 1 )) % Ty->backsize]) + + +#if 0 +static void +verify_beacon(Termpty *ty) +{ + Termsave *ts; + int nb_lines; + int backlog_y = ty->backlog_beacon.backlog_y; + int screen_y = ty->backlog_beacon.screen_y; + + assert(ty->backlog_beacon.screen_y >= 0); + assert(ty->backlog_beacon.backlog_y >= 0); + assert(ty->backlog_beacon.screen_y >= ty->backlog_beacon.backlog_y); + + //ERR("FROM screen_y:%d backlog_y:%d", + // screen_y, backlog_y); + while (backlog_y > 0) + { + ts = BACKLOG_ROW_GET(ty, backlog_y); + if (!ts->cells) + { + ERR("went too far: screen_y:%d backlog_y:%d", + screen_y, backlog_y); + return; + } + + nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; + screen_y -= nb_lines; + backlog_y--; + //ERR("nb_lines:%d screen_y:%d backlog_y:%d ts->w:%d ty->w:%d", + // nb_lines, screen_y, backlog_y, ts->w, ty->w); + assert(screen_y >= backlog_y); + + } + //ERR("TO screen_y:%d backlog_y:%d", + // screen_y, backlog_y); + assert (backlog_y == 0); + assert (screen_y == 0); +} +#endif + void termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max) @@ -643,19 +685,22 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max) w = termpty_line_length(cells, w_max); if (ty->backsize >= 1) { - ts = BACKLOG_ROW_GET(ty, 0); + ts = BACKLOG_ROW_GET(ty, 1); if (!ts->cells) goto add_new_ts; /* TODO: RESIZE uncompress ? */ if (ts->w && ts->cells[ts->w - 1].att.autowrapped) { + int old_len = ts->w; termpty_save_expand(ts, cells, w); + ty->backlog_beacon.screen_y += (ts->w + ty->w - 1) / ty->w + - (old_len + ty->w - 1) / ty->w; return; } } add_new_ts: - ts = BACKLOG_ROW_GET(ty, -1); + ts = BACKLOG_ROW_GET(ty, 0); ts = termpty_save_new(ts, w); if (!ts) return; @@ -664,6 +709,14 @@ add_new_ts: if (ty->backpos >= ty->backsize) ty->backpos = 0; termpty_save_thaw(); + + ty->backlog_beacon.screen_y++; + ty->backlog_beacon.backlog_y++; + if (ty->backlog_beacon.backlog_y >= ty->backsize) + { + ty->backlog_beacon.screen_y = 0; + ty->backlog_beacon.backlog_y = 0; + } } @@ -677,7 +730,7 @@ termpty_row_length(Termpty *ty, int y) Termcell *cells; if (y >= ty->h) { - ERR("invalid row given"); + ERR("invalid row given: %d while ty->h=%d", y, ty->h); return 0; } cells = &(TERMPTY_SCREEN(ty, 0, y)); @@ -685,7 +738,8 @@ termpty_row_length(Termpty *ty, int y) } if ((y < -ty->backsize) || !ty->back) { - ERR("invalid row given"); + ERR("invalid row given: %d; ty->back:%p ty->backsize:%d", + y, ty->back, ty->backsize); return 0; } ts = BACKLOG_ROW_GET(ty, y); @@ -693,60 +747,119 @@ termpty_row_length(Termpty *ty, int y) return ts->cells ? ts->w : 0; } -/* TODO: RESIZE reference point */ +ssize_t +termpty_backscroll_length(Termpty *ty) +{ + int backlog_y = ty->backlog_beacon.backlog_y; + int screen_y = ty->backlog_beacon.screen_y; + + if (!ty->backsize) + return 0; + + while (42) + { + int nb_lines; + Termsave *ts; + + ts = BACKLOG_ROW_GET(ty, backlog_y); + if (!ts->cells || backlog_y >= ty->backsize) + return ty->backlog_beacon.screen_y; + + nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; + ty->backlog_beacon.screen_y = screen_y; + ty->backlog_beacon.backlog_y = backlog_y; + screen_y += nb_lines; + backlog_y++; + } +} void termpty_backscroll_adjust(Termpty *ty, int *scroll) { - Termsave *ts; - int y; - int screen_y; + int backlog_y = ty->backlog_beacon.backlog_y; + int screen_y = ty->backlog_beacon.screen_y; if (!ty->backsize || *scroll <= 0) { *scroll = 0; return; } - ERR("ty->backsize:%d ty->backpos:%d *scroll:%d", - ty->backsize, ty->backpos, *scroll); - /* TODO: RESIZE have a reference point? */ - y = ty->backsize; - do - { - y--; - ts = BACKLOG_ROW_GET(ty, y); - } - while (!ts->cells); - ERR("y:%d", y); - if (*scroll <= y) + if (*scroll < screen_y) return; - screen_y = 0; - while (y >= 0) + + while (42) { int nb_lines; + Termsave *ts; - ts = BACKLOG_ROW_GET(ty, y); - assert(ts != NULL); + ts = BACKLOG_ROW_GET(ty, backlog_y); + if (!ts->cells || backlog_y >= ty->backsize) + { + *scroll = ty->backlog_beacon.screen_y; + return; + } - nb_lines = (ts->w + ty->w) / ty->w; - ERR("[%d] ts->w:%d ty->w:%d, nb_lines:%d", - y, ts->w, ty->w, nb_lines); + nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; + ty->backlog_beacon.screen_y = screen_y; + ty->backlog_beacon.backlog_y = backlog_y; screen_y += nb_lines; - y--; + backlog_y++; } - - ERR("screen_y:%d", screen_y); - *scroll = screen_y; } +static Termcell* +_termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, int *wret) +{ + int backlog_y = ty->backlog_beacon.backlog_y; + int screen_y = ty->backlog_beacon.screen_y; + Eina_Bool going_forward = EINA_TRUE; + + requested_y = -requested_y; + + while (42) { + Termsave *ts; + int nb_lines; + + ts = BACKLOG_ROW_GET(ty, backlog_y); + assert (ts->cells); + if (!ts->cells) + { + ERR("went too far: requested_y:%d screen_y:%d backlog_y:%d", + requested_y, screen_y, backlog_y); + return NULL; + } + nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; + if (!going_forward) { + screen_y -= nb_lines; + } + + if ((screen_y <= requested_y) && (requested_y < screen_y + nb_lines)) + { + int delta = screen_y + nb_lines - 1 - requested_y; + *wret = ts->w - delta * ty->w; + if (*wret > ts->w) + *wret = ts->w; + return &ts->cells[delta * ty->w]; + } + + if (requested_y > screen_y) + { + screen_y += nb_lines; + backlog_y++; + } + else + { + backlog_y--; + going_forward = EINA_FALSE; + } + } + + return NULL; +} Termcell * termpty_cellrow_get(Termpty *ty, int y_requested, int *wret) { - int screen_y = 0; - int backlog_y = 0; - - //ERR("y_requested:%d", y_requested); if (y_requested >= 0) { if (y_requested >= ty->h) @@ -757,38 +870,8 @@ termpty_cellrow_get(Termpty *ty, int y_requested, int *wret) if (!ty->back) return NULL; - y_requested = -y_requested; - while (backlog_y <= ty->backsize) - { - Termsave *ts; - int nb_lines; + return _termpty_cellrow_from_beacon_get(ty, y_requested, wret); - ts = BACKLOG_ROW_GET(ty, backlog_y); - if (!ts->cells) - { - //ERR("went too far: y_requested:%d screen_y:%d backlog_y:%d", - // y_requested, screen_y, backlog_y); - return NULL; - } - nb_lines = (ts->w + ty->w) / ty->w; - - /* TODO: uncompress */ - /* TODO: optimize */ - - //ERR("y_requested:%d screen_y:%d nb_lines:%d backlog_y:%d", - // y_requested, screen_y, nb_lines, backlog_y); - if (screen_y + nb_lines >= y_requested) - { - int delta = screen_y + nb_lines - y_requested; - *wret = ts->w - delta * ty->w; - if (*wret > ts->w) - *wret = ts->w; - return &ts->cells[delta * ty->w]; - } - screen_y += nb_lines; - backlog_y++; - } - return NULL; } void @@ -822,8 +905,6 @@ _check_screen_info(Termpty *ty, struct screen_info *si) { Termcell *cells = &SCREEN_INFO_GET_CELLS(si, 0, 0); - ERR("adjusting"); - si->y--; termpty_text_save_top(ty, cells, si->w); termpty_cells_clear(ty, cells, si->w); @@ -843,8 +924,6 @@ _termpty_line_rewrap(Termpty *ty, Termcell *cells, int len, { int autowrapped = cells[len-1].att.autowrapped; - ERR("si->x:%d si->y:%d si->cx:%d si->cy:%d", - si->x, si->y, si->cx, si->cy); if (len == 0) { if (set_cursor) @@ -861,7 +940,6 @@ _termpty_line_rewrap(Termpty *ty, Termcell *cells, int len, { int copy_width = MIN(len, si->w - si->x); - ERR("len:%d copy_width:%d", len, copy_width); termpty_cell_copy(ty, /*src*/ cells, /*dst*/&SCREEN_INFO_GET_CELLS(si, si->x, si->y), @@ -880,7 +958,6 @@ _termpty_line_rewrap(Termpty *ty, Termcell *cells, int len, } len -= copy_width; si->x += copy_width; - ERR("si->x:%d si->w:%d", si->x, si->w); if (si->x >= si->w) { si->y++; @@ -888,7 +965,6 @@ _termpty_line_rewrap(Termpty *ty, Termcell *cells, int len, } _check_screen_info(ty, si); } - ERR("autowrapped:%d", autowrapped); if (!autowrapped) { si->y++; @@ -951,7 +1027,6 @@ termpty_resize(Termpty *ty, int new_w, int new_h) int len; len = termpty_line_length(cells, old_w); - ERR("[%d] len:%d", old_y, len); _termpty_line_rewrap(ty, cells, len, &new_si, old_y == ty->cursor_state.cy); } @@ -976,6 +1051,10 @@ termpty_resize(Termpty *ty, int new_w, int new_h) _pty_size(ty); termpty_save_thaw(); + + ty->backlog_beacon.backlog_y = 0; + ty->backlog_beacon.screen_y = 0; + return; bad: diff --git a/src/bin/termpty.h b/src/bin/termpty.h index 26c5de05..b9b339a1 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h @@ -99,15 +99,19 @@ struct _Termpty } prop; const char *cur_cmd; Termcell *screen, *screen2; - Termsave *back; - unsigned char oldbuf[4]; - Eina_Unicode *buf; - size_t buflen; - int w, h; - int fd, slavefd; int circular_offset; int circular_offset2; + Eina_Unicode *buf; + size_t buflen; + unsigned char oldbuf[4]; + Termsave *back; int backsize, backpos; + struct { + int screen_y; + int backlog_y; + } backlog_beacon; + int w, h; + int fd, slavefd; struct { int curid; Eina_Hash *blocks; @@ -230,12 +234,14 @@ Termpty *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, void termpty_free(Termpty *ty); void termpty_cellcomp_freeze(Termpty *ty); void termpty_cellcomp_thaw(Termpty *ty); + Termcell *termpty_cellrow_get(Termpty *ty, int y, int *wret); ssize_t termpty_row_length(Termpty *ty, int y); void termpty_write(Termpty *ty, const char *input, int len); void termpty_resize(Termpty *ty, int new_w, int new_h); void termpty_backscroll_set(Termpty *ty, int size); void termpty_backscroll_adjust(Termpty *ty, int *scroll); +ssize_t termpty_backscroll_length(Termpty *ty); pid_t termpty_pid_get(const Termpty *ty); void termpty_block_free(Termblock *tb); diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c index 0df51f89..95b89228 100644 --- a/src/bin/termptyops.c +++ b/src/bin/termptyops.c @@ -381,6 +381,9 @@ termpty_reset_state(Termpty *ty) ty->mouse_ext = MOUSE_EXT_NONE; ty->bracketed_paste = 0; + ty->backlog_beacon.screen_y = 0; + ty->backlog_beacon.backlog_y = 0; + termpty_save_freeze(); if (ty->back) {