Improved performance by not requiring updating swap in gfxterm

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-14 17:59:11 +01:00
parent 1f56d83788
commit bbe73b0995
3 changed files with 77 additions and 33 deletions

View file

@ -34,9 +34,10 @@ struct grub_video_render_target;
struct grub_video_bitmap; struct grub_video_bitmap;
/* Defines used to describe video mode or rendering target. */ /* Defines used to describe video mode or rendering target. */
/* If following is set render target contains previously displayed image /* If following is set render target contains currenly displayed image
after swapping buffers (otherwise it contains newly displayedd image). after swapping buffers (otherwise it contains previously displayed image).
*/ */
#define GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP 0x00000080
#define GRUB_VIDEO_MODE_TYPE_PURE_TEXT 0x00000040 #define GRUB_VIDEO_MODE_TYPE_PURE_TEXT 0x00000040
#define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020 #define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020
#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010

View file

@ -474,8 +474,6 @@ dirty_region_redraw (void)
height = dirty_region.bottom_right_y - y + 1; height = dirty_region.bottom_right_y - y + 1;
redraw_screen_rect (x, y, width, height); redraw_screen_rect (x, y, width, height);
dirty_region_reset ();
} }
static void static void
@ -566,9 +564,6 @@ scroll_up (void)
{ {
/* Remove cursor. */ /* Remove cursor. */
draw_cursor (0); draw_cursor (0);
/* Redraw only changed regions. */
dirty_region_redraw ();
} }
/* Scroll text buffer with one line to up. */ /* Scroll text buffer with one line to up. */
@ -584,28 +579,52 @@ scroll_up (void)
i++) i++)
clear_char (&(virtual_screen.text_buffer[i])); clear_char (&(virtual_screen.text_buffer[i]));
/* 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_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
/* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */ /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
if (bitmap) if (bitmap)
{ {
/* 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);
/* Mark virtual screen to be redrawn. */ /* Mark virtual screen to be redrawn. */
dirty_region_add_virtualscreen (); dirty_region_add_virtualscreen ();
} }
else else
{ {
/* Clear new border area. */ int i = 1;
grub_video_fill_rect (color, if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
virtual_screen.offset_x, virtual_screen.offset_y, && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP))
virtual_screen.width, virtual_screen.normal_char_height); i++;
color = virtual_screen.bg_color;
while (i--)
{
/* Clear new border area. */
grub_video_fill_rect (color,
virtual_screen.offset_x,
virtual_screen.offset_y,
virtual_screen.width,
virtual_screen.normal_char_height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
dirty_region_redraw ();
/* Scroll physical screen. */
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
if (i)
grub_video_swap_buffers ();
}
dirty_region_reset ();
/* Scroll physical screen. */ /* 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);
/* Draw cursor if visible. */ /* Draw cursor if visible. */
if (virtual_screen.cursor_state) if (virtual_screen.cursor_state)
draw_cursor (1); draw_cursor (1);
@ -818,7 +837,6 @@ grub_gfxterm_cls (void)
/* Mark virtual screen to be redrawn. */ /* Mark virtual screen to be redrawn. */
dirty_region_add_virtualscreen (); dirty_region_add_virtualscreen ();
dirty_region_redraw ();
grub_gfxterm_refresh (); grub_gfxterm_refresh ();
} }
@ -884,6 +902,11 @@ grub_gfxterm_refresh (void)
dirty_region_redraw (); dirty_region_redraw ();
grub_video_swap_buffers (); grub_video_swap_buffers ();
if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP))
dirty_region_redraw ();
dirty_region_reset ();
} }
static grub_err_t static grub_err_t

View file

@ -418,10 +418,11 @@ doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
return err; return err;
} }
grub_memcpy (framebuffer.ptr + framebuffer.render_page if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
* framebuffer.page_size, framebuffer.ptr grub_memcpy (framebuffer.ptr + framebuffer.render_page
+ framebuffer.displayed_page * framebuffer.page_size, * framebuffer.page_size, framebuffer.ptr
framebuffer.page_size); + framebuffer.displayed_page * framebuffer.page_size,
framebuffer.page_size);
target = framebuffer.back_target; target = framebuffer.back_target;
framebuffer.back_target = framebuffer.front_target; framebuffer.back_target = framebuffer.front_target;
@ -486,19 +487,38 @@ static grub_err_t
double_buffering_init (unsigned int mode_type, unsigned int mode_mask) double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
{ {
grub_err_t err; grub_err_t err;
int updating_swap_needed;
updating_swap_needed
= grub_video_check_mode_flag (mode_type, mode_mask,
GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0);
/* Do double buffering only if it's either requested or efficient. */
if (grub_video_check_mode_flag (mode_type, mode_mask, if (grub_video_check_mode_flag (mode_type, mode_mask,
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1)) GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
!updating_swap_needed))
{ {
framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
if (updating_swap_needed)
framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP;
err = doublebuf_pageflipping_init (); err = doublebuf_pageflipping_init ();
if (!err) if (!err)
{ return GRUB_ERR_NONE;
framebuffer.mode_info.mode_type
|= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; framebuffer.mode_info.mode_type
return GRUB_ERR_NONE; &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
} | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
}
if (grub_video_check_mode_flag (mode_type, mode_mask,
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
0))
{
framebuffer.mode_info.mode_type
|= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target,
&framebuffer.back_target, &framebuffer.back_target,
@ -507,11 +527,11 @@ double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
framebuffer.ptr); framebuffer.ptr);
if (!err) if (!err)
{ return GRUB_ERR_NONE;
framebuffer.mode_info.mode_type
|= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; framebuffer.mode_info.mode_type
return GRUB_ERR_NONE; &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
} | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }