billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=35c8fd79c014c4f51a23585f6f445f16bf165798

commit 35c8fd79c014c4f51a23585f6f445f16bf165798
Author: Boris Faure <bill...@gmail.com>
Date:   Sun Jun 28 23:37:04 2015 +0200

    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    | 221 ++++++++++++++++++++++++++++++++++-----------------
 src/bin/termpty.h    |  16 ++--
 src/bin/termptyops.c |   3 +
 5 files changed, 168 insertions(+), 81 deletions(-)

diff --git a/src/bin/miniview.c b/src/bin/miniview.c
index 90b3477..477a7e9 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 c964079..c85fcca 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 9a0a143..b72510d 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,104 +747,133 @@ 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;
 }
 
-
-Termcell *
-termpty_cellrow_get(Termpty *ty, int y_requested, int *wret)
+static Termcell*
+_termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, int *wret)
 {
-   int screen_y = 0;
-   int backlog_y = 0;
+   int backlog_y = ty->backlog_beacon.backlog_y;
+   int screen_y = ty->backlog_beacon.screen_y;
+   Eina_Bool going_forward = EINA_TRUE;
 
-   //ERR("y_requested:%d", y_requested);
-   if (y_requested >= 0)
-     {
-        if (y_requested >= ty->h)
-          return NULL;
-        *wret = ty->w;
-        return &(TERMPTY_SCREEN(ty, 0, y_requested));
-     }
-   if (!ty->back)
-     return NULL;
+   requested_y = -requested_y;
 
-   y_requested = -y_requested;
-   while (backlog_y <= ty->backsize)
-     {
+   while (42) {
         Termsave *ts;
         int nb_lines;
 
         ts = BACKLOG_ROW_GET(ty, backlog_y);
+        assert (ts->cells);
         if (!ts->cells)
           {
-             //ERR("went too far: y_requested:%d screen_y:%d backlog_y:%d",
-             //    y_requested, screen_y, backlog_y);
+             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 + ty->w) / ty->w;
-
-        /* TODO: uncompress */
-        /* TODO: optimize */
+        nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
+        if (!going_forward) {
+             screen_y -= nb_lines;
+        }
 
-        //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)
+        if ((screen_y <= requested_y) && (requested_y < screen_y + nb_lines))
           {
-             int delta = screen_y + nb_lines - y_requested;
+             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];
           }
-        screen_y += nb_lines;
-        backlog_y++;
-     }
+
+        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)
+{
+   if (y_requested >= 0)
+     {
+        if (y_requested >= ty->h)
+          return NULL;
+        *wret = ty->w;
+        return &(TERMPTY_SCREEN(ty, 0, y_requested));
+     }
+   if (!ty->back)
+     return NULL;
+
+   return _termpty_cellrow_from_beacon_get(ty, y_requested, wret);
+
+}
+
 void
 termpty_write(Termpty *ty, const char *input, int len)
 {
@@ -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 26c5de0..b9b339a 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];
+   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;
-   int circular_offset;
-   int circular_offset2;
-   int backsize, backpos;
    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 0df51f8..95b8922 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)
      {

-- 


Reply via email to