[Top][All Lists]
[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 ();
signature.asc
Description: OpenPGP digital signature
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] speed up scrolling by agglomerating one-line scrolls,
Vladimir 'φ-coder/phcoder' Serbinenko <=