grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] speed up scrolling by agglomerating one-line scrolls


From: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: [PATCH] speed up scrolling by agglomerating one-line scrolls
Date: Mon, 30 Nov 2009 13:21:53 +0100
User-agent: Mozilla-Thunderbird 2.0.0.22 (X11/20091109)

Available in experimental

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== added file 'ChangeLog.gfxtermscroll'
--- ChangeLog.gfxtermscroll     1970-01-01 00:00:00 +0000
+++ ChangeLog.gfxtermscroll     2009-11-30 11:52:39 +0000
@@ -0,0 +1,18 @@
+2009-11-30  Vladimir Serbinenko  <address@hidden>
+
+       Agglomerate scrolling in gfxterm.
+
+       * term/gfxterm.c (grub_virtual_screen): New member 'total_screen'.
+       (grub_virtual_screen_setup): Initialise 'total_screen'.
+       (write_char): Split to ...
+       (paint_char): ... this ...
+       (write_char): ... and this.
+       (paint_char): Handle delayed scrolling.
+       (draw_cursor): Likewise.
+       (scroll_up): Split to ...
+       (real_scroll): ... this ...
+       (scroll_up): ... and this.
+       (real_scroll): Handle multi-line scroll and draw below-the-bottom
+       characters.
+       (grub_gfxterm_refresh): Call real_scroll.
+

=== modified file 'term/gfxterm.c'
--- term/gfxterm.c      2009-11-20 13:30:58 +0000
+++ term/gfxterm.c      2009-11-30 11:51:20 +0000
@@ -102,6 +102,8 @@
   /* Text buffer for virtual screen.  Contains (columns * rows) number
      of entries.  */
   struct grub_colored_char *text_buffer;
+
+  int total_scroll;
 };
 
 struct grub_gfxterm_window
@@ -225,6 +227,7 @@
   virtual_screen.cursor_x = 0;
   virtual_screen.cursor_y = 0;
   virtual_screen.cursor_state = 1;
+  virtual_screen.total_scroll = 0;
 
   /* Calculate size of text buffer.  */
   virtual_screen.columns = virtual_screen.width / 
virtual_screen.normal_char_width;
@@ -586,8 +589,8 @@
   redraw_screen_rect (x, y, width, height);
 }
 
-static void
-write_char (void)
+static inline void
+paint_char (unsigned cx, unsigned cy)
 {
   struct grub_colored_char *p;
   struct grub_font_glyph *glyph;
@@ -599,10 +602,12 @@
   unsigned int height;
   unsigned int width;
 
+  if (cy + virtual_screen.total_scroll >= virtual_screen.rows)
+    return;
+
   /* Find out active character.  */
   p = (virtual_screen.text_buffer
-       + virtual_screen.cursor_x
-       + (virtual_screen.cursor_y * virtual_screen.columns));
+       + cx + (cy * virtual_screen.columns));
 
   p -= p->index;
 
@@ -616,8 +621,8 @@
   color = p->fg_color;
   bgcolor = p->bg_color;
 
-  x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
-  y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
+  x = cx * virtual_screen.normal_char_width;
+  y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height;
 
   /* Render glyph to text layer.  */
   grub_video_set_active_render_target (text_layer);
@@ -630,64 +635,58 @@
                     width, height);
 }
 
-static void
+static inline void
+write_char (void)
+{
+  paint_char (virtual_screen.cursor_x, virtual_screen.cursor_y);
+}
+
+static inline void
 draw_cursor (int show)
 {
+  unsigned int x;
+  unsigned int y;
+  unsigned int width;
+  unsigned int height;
+  grub_video_color_t color;
+  
   write_char ();
 
-  if (show)
-    {
-      unsigned int x;
-      unsigned int y;
-      unsigned int width;
-      unsigned int height;
-      grub_video_color_t color;
-
-      /* Determine cursor properties and position on text layer. */
-      x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
-      width = virtual_screen.normal_char_width;
-      color = virtual_screen.fg_color;
-      y = (virtual_screen.cursor_y * virtual_screen.normal_char_height
-           + grub_font_get_ascent (virtual_screen.font));
-      height = 2;
-
-      /* Render cursor to text layer.  */
-      grub_video_set_active_render_target (text_layer);
-      grub_video_fill_rect (color, x, y, width, height);
-      grub_video_set_active_render_target (render_target);
-
-      /* Mark cursor to be redrawn.  */
-      dirty_region_add (virtual_screen.offset_x + x,
-                        virtual_screen.offset_y + y,
-                        width, height);
-    }
+  if (!show)
+    return;
+
+  if (virtual_screen.cursor_y + virtual_screen.total_scroll
+      >= virtual_screen.rows)
+    return;
+
+  /* Determine cursor properties and position on text layer. */
+  x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+  width = virtual_screen.normal_char_width;
+  color = virtual_screen.fg_color;
+  y = ((virtual_screen.cursor_y + virtual_screen.total_scroll)
+       * virtual_screen.normal_char_height
+       + grub_font_get_ascent (virtual_screen.font));
+  height = 2;
+  
+  /* Render cursor to text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  grub_video_fill_rect (color, x, y, width, height);
+  grub_video_set_active_render_target (render_target);
+  
+  /* Mark cursor to be redrawn.  */
+  dirty_region_add (virtual_screen.offset_x + x,
+                   virtual_screen.offset_y + y,
+                   width, height);
 }
 
 static void
-scroll_up (void)
+real_scroll (void)
 {
-  unsigned int i;
+  unsigned int i, j, was_scroll;
   grub_video_color_t color;
 
-  /* If we don't have background bitmap, remove cursor. */
-  if (!bitmap)
-    {
-      /* Remove cursor.  */
-      draw_cursor (0);
-    }
-
-  /* Scroll text buffer with one line to up.  */
-  grub_memmove (virtual_screen.text_buffer,
-                virtual_screen.text_buffer + virtual_screen.columns,
-                sizeof (*virtual_screen.text_buffer)
-                * virtual_screen.columns
-                * (virtual_screen.rows - 1));
-
-  /* Clear last line in text buffer.  */
-  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
-       i < virtual_screen.columns * virtual_screen.rows;
-       i++)
-    clear_char (&(virtual_screen.text_buffer[i]));
+  if (!virtual_screen.total_scroll)
+    return;
 
   /* If we have bitmap, re-draw screen, otherwise scroll physical screen too.  
*/
   if (bitmap)
@@ -695,7 +694,8 @@
       /* Scroll physical screen.  */
       grub_video_set_active_render_target (text_layer);
       color = virtual_screen.bg_color;
-      grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
+      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                        * virtual_screen.total_scroll);
 
       /* Mark virtual screen to be redrawn.  */
       dirty_region_add_virtualscreen ();
@@ -704,6 +704,9 @@
     {
       grub_video_rect_t saved_view;
 
+      /* Remove cursor.  */
+      draw_cursor (0);
+
       grub_video_set_active_render_target (render_target);
       /* Save viewport and set it to our window.  */
       grub_video_get_viewport ((unsigned *) &saved_view.x, 
@@ -723,13 +726,15 @@
                                virtual_screen.offset_x,
                                virtual_screen.offset_y,
                                virtual_screen.width,
-                               virtual_screen.normal_char_height);
+                               virtual_screen.normal_char_height
+                               * virtual_screen.total_scroll);
 
          grub_video_set_active_render_target (render_target);
          dirty_region_redraw ();
 
          /* Scroll physical screen.  */
-         grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
+         grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                            * virtual_screen.total_scroll);
 
          if (i)
            grub_video_swap_buffers ();
@@ -739,23 +744,55 @@
       /* Scroll physical screen.  */
       grub_video_set_active_render_target (text_layer);
       color = virtual_screen.bg_color;
-      grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
+      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                        * virtual_screen.total_scroll);
 
       /* Restore saved viewport.  */
       grub_video_set_viewport (saved_view.x, saved_view.y,
                                saved_view.width, saved_view.height);
       grub_video_set_active_render_target (render_target);
 
-      /* Draw cursor if visible.  */
-      if (virtual_screen.cursor_state)
-       draw_cursor (1);
     }
 
+  /* Draw cursor if visible.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+
+  was_scroll = virtual_screen.total_scroll;
+  virtual_screen.total_scroll = 0;
+
+  /* Draw shadow part.  */
+  for (i = virtual_screen.rows - was_scroll;
+       i < virtual_screen.rows; i++)
+    for (j = 0; j < virtual_screen.columns; j++)
+      paint_char (j, i);
+
   if (repaint_callback)
     repaint_callback (window.x, window.y, window.width, window.height);
 }
 
 static void
+scroll_up (void)
+{
+  unsigned int i;
+
+  /* Scroll text buffer with one line to up.  */
+  grub_memmove (virtual_screen.text_buffer,
+                virtual_screen.text_buffer + virtual_screen.columns,
+                sizeof (*virtual_screen.text_buffer)
+                * virtual_screen.columns
+                * (virtual_screen.rows - 1));
+
+  /* Clear last line in text buffer.  */
+  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
+       i < virtual_screen.columns * virtual_screen.rows;
+       i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  virtual_screen.total_scroll++;
+}
+
+static void
 grub_gfxterm_putchar (grub_uint32_t c)
 {
   if (c == '\a')
@@ -1023,6 +1060,8 @@
 static void
 grub_gfxterm_refresh (void)
 {
+  real_scroll ();
+
   /* Redraw only changed regions.  */
   dirty_region_redraw ();
 

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]