Optimise gfxterm in gfxmenu by avoiding indirect repainting

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-24 04:22:22 +01:00
parent 8f41eb5582
commit 93fd2dd809
1 changed files with 46 additions and 47 deletions

View File

@ -42,6 +42,8 @@
status changes. */ status changes. */
#define TIMEOUT_COMPONENT_ID "__timeout__" #define TIMEOUT_COMPONENT_ID "__timeout__"
static grub_gfxmenu_view_t term_view;
static void init_terminal (grub_gfxmenu_view_t view); static void init_terminal (grub_gfxmenu_view_t view);
static void destroy_terminal (void); static void destroy_terminal (void);
static grub_err_t set_graphics_mode (void); static grub_err_t set_graphics_mode (void);
@ -310,86 +312,82 @@ set_text_mode (void)
static int term_target_width; static int term_target_width;
static int term_target_height; static int term_target_height;
static struct grub_video_render_target *term_target;
static int term_initialized; static int term_initialized;
static grub_term_output_t term_original; static grub_term_output_t term_original;
static grub_gfxmenu_view_t term_view;
static void static void
repaint_terminal (int x __attribute ((unused)), draw_terminal_box (void)
int y __attribute ((unused)),
int width __attribute ((unused)),
int height __attribute ((unused)))
{ {
if (! term_view) grub_gfxmenu_box_t term_box;
int termx;
int termy;
term_box = term_view->terminal_box;
if (!term_box)
return; return;
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); termx = term_view->screen.x + term_view->screen.width * (10 - 7) / 10 / 2;
grub_gfxmenu_view_draw (term_view); termy = term_view->screen.y + term_view->screen.height * (10 - 7) / 10 / 2;
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
term_box->set_content_size (term_box, term_target_width,
int termx = term_view->screen.x term_target_height);
+ term_view->screen.width * (10 - 7) / 10 / 2;
int termy = term_view->screen.y term_box->draw (term_box,
+ term_view->screen.height * (10 - 7) / 10 / 2; termx - term_box->get_left_pad (term_box),
termy - term_box->get_top_pad (term_box));
grub_gfxmenu_box_t term_box = term_view->terminal_box;
if (term_box)
{
term_box->set_content_size (term_box,
term_target_width, term_target_height);
term_box->draw (term_box,
termx - term_box->get_left_pad (term_box),
termy - term_box->get_top_pad (term_box));
}
grub_video_blit_render_target (term_target, GRUB_VIDEO_BLIT_REPLACE,
termx, termy,
0, 0, term_target_width, term_target_height);
grub_video_swap_buffers ();
} }
static void static void
init_terminal (grub_gfxmenu_view_t view) init_terminal (grub_gfxmenu_view_t view)
{ {
int termx;
int termy;
struct grub_video_mode_info mode_info;
grub_err_t err;
int double_repaint;
term_original = grub_term_get_current_output (); term_original = grub_term_get_current_output ();
term_target_width = view->screen.width * 7 / 10; term_target_width = view->screen.width * 7 / 10;
term_target_height = view->screen.height * 7 / 10; term_target_height = view->screen.height * 7 / 10;
grub_video_create_render_target (&term_target, termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2;
term_target_width, termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2;
term_target_height,
GRUB_VIDEO_MODE_TYPE_RGB err = grub_video_get_info (&mode_info);
| GRUB_VIDEO_MODE_TYPE_ALPHA); if (err)
if (grub_errno != GRUB_ERR_NONE) {
return; grub_errno = GRUB_ERR_NONE;
double_repaint = 1;
}
else
double_repaint = (mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
&& !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
/* Note: currently there is no API for changing the gfxterm font /* Note: currently there is no API for changing the gfxterm font
on the fly, so whatever font the initially loaded theme specifies on the fly, so whatever font the initially loaded theme specifies
will be permanent. */ will be permanent. */
grub_gfxterm_init_window (term_target, 0, 0, grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy,
term_target_width, term_target_height, 0, term_target_width, term_target_height,
view->terminal_font_name, 3); double_repaint, view->terminal_font_name, 3);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
return; return;
term_initialized = 1; term_initialized = 1;
/* XXX: store static pointer to the 'view' object so the repaint callback can access it. */ grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
grub_gfxmenu_view_draw (view);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
term_view = view; term_view = view;
grub_gfxterm_set_repaint_callback (repaint_terminal);
grub_term_set_current_output (grub_gfxterm_get_term ()); grub_term_set_current_output (grub_gfxterm_get_term ());
} }
static void destroy_terminal (void) static void destroy_terminal (void)
{ {
term_view = 0;
if (term_initialized) if (term_initialized)
grub_gfxterm_destroy_window (); grub_gfxterm_destroy_window ();
grub_gfxterm_set_repaint_callback (0);
if (term_target)
grub_video_delete_render_target (term_target);
if (term_original) if (term_original)
grub_term_set_current_output (term_original); grub_term_set_current_output (term_original);
} }
@ -493,5 +491,6 @@ grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view,
void void
grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused))) grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused)))
{ {
draw_terminal_box ();
grub_cmdline_run (1); grub_cmdline_run (1);
} }