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;
/* Defines used to describe video mode or rendering target. */
/* If following is set render target contains previously displayed image
after swapping buffers (otherwise it contains newly displayedd image).
/* If following is set render target contains currenly displayed 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_ALPHA 0x00000020
#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;
redraw_screen_rect (x, y, width, height);
dirty_region_reset ();
}
static void
@ -566,9 +564,6 @@ scroll_up (void)
{
/* Remove cursor. */
draw_cursor (0);
/* Redraw only changed regions. */
dirty_region_redraw ();
}
/* Scroll text buffer with one line to up. */
@ -584,28 +579,52 @@ scroll_up (void)
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 (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. */
dirty_region_add_virtualscreen ();
}
else
{
/* 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);
int i = 1;
if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP))
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. */
grub_video_set_active_render_target (text_layer);
color = virtual_screen.bg_color;
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
/* Draw cursor if visible. */
if (virtual_screen.cursor_state)
draw_cursor (1);
@ -818,7 +837,6 @@ grub_gfxterm_cls (void)
/* Mark virtual screen to be redrawn. */
dirty_region_add_virtualscreen ();
dirty_region_redraw ();
grub_gfxterm_refresh ();
}
@ -884,6 +902,11 @@ grub_gfxterm_refresh (void)
dirty_region_redraw ();
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

View file

@ -418,10 +418,11 @@ doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
return err;
}
grub_memcpy (framebuffer.ptr + framebuffer.render_page
* framebuffer.page_size, framebuffer.ptr
+ framebuffer.displayed_page * framebuffer.page_size,
framebuffer.page_size);
if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
grub_memcpy (framebuffer.ptr + framebuffer.render_page
* framebuffer.page_size, framebuffer.ptr
+ framebuffer.displayed_page * framebuffer.page_size,
framebuffer.page_size);
target = framebuffer.back_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)
{
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,
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 ();
if (!err)
{
framebuffer.mode_info.mode_type
|= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
return GRUB_ERR_NONE;
}
return GRUB_ERR_NONE;
framebuffer.mode_info.mode_type
&= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
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,
&framebuffer.back_target,
@ -507,11 +527,11 @@ double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
framebuffer.ptr);
if (!err)
{
framebuffer.mode_info.mode_type
|= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
return GRUB_ERR_NONE;
}
return GRUB_ERR_NONE;
framebuffer.mode_info.mode_type
&= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
grub_errno = GRUB_ERR_NONE;
}