From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH] speed up scrolling by agglomerating one-line scrolls
Date: Mon, 30 Nov 2009 13:21:53 +0100 [thread overview]
Message-ID: <4B13B8E1.3090508@gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 85 bytes --]
Available in experimental
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: gfxtermscroll.diff --]
[-- Type: text/x-diff; name="gfxtermscroll.diff", Size: 9222 bytes --]
=== 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 <phcoder@gmail.com>
+
+ 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 #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
reply other threads:[~2009-11-30 12:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B13B8E1.3090508@gmail.com \
--to=phcoder@gmail.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.