* grub-core/term/efi/console.c (grub_efi_console_init): Set text mode.

(grub_efi_console_fini): Likewise.
	* grub-core/video/efi_gop.c (framebuffer): New field offscreen.
	(grub_video_gop_fill_mode_info): Rename to ...
	(grub_video_gop_fill_real_mode_info): ... this.
	(grub_video_gop_fill_mode_info): New function.
	(grub_video_gop_setup): Setup double framebuffer.
	(grub_video_gop_get_info_and_fini): Use original framebuffer.
	Free offscreen.
	(grub_video_gop_swap_buffers): Copy framebuffer.
	(grub_video_gop_fini): Free offscreen buffer.
	* include/grub/efi/graphics_output.h (grub_efi_gop_blt_operation_t):
	New enum.
	(grub_efi_gop_blt_pixel): New struct.
This commit is contained in:
Matthew Garrett 2012-05-26 13:33:34 +02:00 committed by Vladimir 'phcoder' Serbinenko
parent 683031bac4
commit 4ce776d23e
4 changed files with 109 additions and 6 deletions

View file

@ -1,3 +1,20 @@
2012-05-26 Matthew Garrett <mjg@redhat.com>
* grub-core/term/efi/console.c (grub_efi_console_init): Set text mode.
(grub_efi_console_fini): Likewise.
* grub-core/video/efi_gop.c (framebuffer): New field offscreen.
(grub_video_gop_fill_mode_info): Rename to ...
(grub_video_gop_fill_real_mode_info): ... this.
(grub_video_gop_fill_mode_info): New function.
(grub_video_gop_setup): Setup double framebuffer.
(grub_video_gop_get_info_and_fini): Use original framebuffer.
Free offscreen.
(grub_video_gop_swap_buffers): Copy framebuffer.
(grub_video_gop_fini): Free offscreen buffer.
* include/grub/efi/graphics_output.h (grub_efi_gop_blt_operation_t):
New enum.
(grub_efi_gop_blt_pixel): New struct.
2012-05-26 Vladimir Serbinenko <phcoder@gmail.com>
* gentpl.py: Remove error disabling for objconv.

View file

@ -234,6 +234,7 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
static grub_err_t
grub_efi_console_init (struct grub_term_output *term)
{
grub_efi_set_text_mode (1);
grub_console_setcursor (term, 1);
return 0;
}
@ -242,6 +243,7 @@ static grub_err_t
grub_efi_console_fini (struct grub_term_output *term)
{
grub_console_setcursor (term, 0);
grub_efi_set_text_mode (0);
return 0;
}

View file

@ -49,6 +49,7 @@ static struct
struct grub_video_mode_info mode_info;
struct grub_video_render_target *render_target;
grub_uint8_t *ptr;
grub_uint8_t *offscreen;
} framebuffer;
@ -105,6 +106,8 @@ grub_video_gop_fini (void)
efi_call_2 (gop->set_mode, gop, old_mode);
restore_needed = 0;
}
grub_free (framebuffer.offscreen);
framebuffer.offscreen = 0;
return grub_video_fb_fini ();
}
@ -165,9 +168,9 @@ grub_video_gop_get_bitmask (grub_uint32_t mask, unsigned int *mask_size,
}
static grub_err_t
grub_video_gop_fill_mode_info (unsigned mode,
struct grub_efi_gop_mode_info *in,
struct grub_video_mode_info *out)
grub_video_gop_fill_real_mode_info (unsigned mode,
struct grub_efi_gop_mode_info *in,
struct grub_video_mode_info *out)
{
out->mode_number = mode;
out->number_of_colors = 256;
@ -223,6 +226,35 @@ grub_video_gop_fill_mode_info (unsigned mode,
return GRUB_ERR_NONE;
}
static grub_err_t
grub_video_gop_fill_mode_info (unsigned mode,
struct grub_efi_gop_mode_info *in,
struct grub_video_mode_info *out)
{
out->mode_number = mode;
out->number_of_colors = 256;
out->width = in->width;
out->height = in->height;
out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
out->bytes_per_pixel = sizeof (struct grub_efi_gop_blt_pixel);
out->bpp = out->bytes_per_pixel << 3;
out->pitch = in->width * out->bytes_per_pixel;
out->red_mask_size = 8;
out->red_field_pos = 16;
out->green_mask_size = 8;
out->green_field_pos = 8;
out->blue_mask_size = 8;
out->blue_field_pos = 0;
out->reserved_mask_size = 8;
out->reserved_field_pos = 24;
out->blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888;
out->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
return GRUB_ERR_NONE;
}
static int
grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info))
{
@ -327,6 +359,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height,
int found = 0;
unsigned long long best_volume = 0;
unsigned int preferred_width = 0, preferred_height = 0;
grub_uint8_t *buffer;
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
@ -442,13 +475,28 @@ grub_video_gop_setup (unsigned int width, unsigned int height,
}
framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base;
framebuffer.offscreen
= grub_malloc (framebuffer.mode_info.height
* framebuffer.mode_info.width
* sizeof (struct grub_efi_gop_blt_pixel));
buffer = framebuffer.offscreen;
if (!buffer)
{
grub_dprintf ("video", "GOP: couldn't allocate shadow\n");
grub_errno = 0;
err = grub_video_gop_fill_mode_info (gop->mode->mode, info,
&framebuffer.mode_info);
buffer = framebuffer.ptr;
}
grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n",
framebuffer.ptr, framebuffer.mode_info.width,
framebuffer.mode_info.height, framebuffer.mode_info.bpp);
err = grub_video_fb_create_render_target_from_pointer
(&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
(&framebuffer.render_target, &framebuffer.mode_info, buffer);
if (err)
{
@ -478,7 +526,13 @@ grub_video_gop_setup (unsigned int width, unsigned int height,
static grub_err_t
grub_video_gop_swap_buffers (void)
{
/* TODO: Implement buffer swapping. */
if (framebuffer.offscreen)
{
efi_call_10 (gop->blt, gop, framebuffer.offscreen,
GRUB_EFI_BLT_BUFFER_TO_VIDEO, 0, 0, 0, 0,
framebuffer.mode_info.width, framebuffer.mode_info.height,
framebuffer.mode_info.width * 4);
}
return GRUB_ERR_NONE;
}
@ -495,11 +549,23 @@ static grub_err_t
grub_video_gop_get_info_and_fini (struct grub_video_mode_info *mode_info,
void **framebuf)
{
grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
grub_err_t err;
err = grub_video_gop_fill_real_mode_info (gop->mode->mode, gop->mode->info,
mode_info);
if (err)
{
grub_dprintf ("video", "GOP: couldn't fill mode info\n");
return err;
}
*framebuf = (char *) framebuffer.ptr;
grub_video_fb_fini ();
grub_free (framebuffer.offscreen);
framebuffer.offscreen = 0;
return GRUB_ERR_NONE;
}

View file

@ -32,6 +32,24 @@ typedef enum
}
grub_efi_gop_pixel_format_t;
typedef enum
{
GRUB_EFI_BLT_VIDEO_FILL,
GRUB_EFI_BLT_VIDEO_TO_BLT_BUFFER,
GRUB_EFI_BLT_BUFFER_TO_VIDEO,
GRUB_EFI_BLT_VIDEO_TO_VIDEO,
GRUB_EFI_BLT_OPERATION_MAX
}
grub_efi_gop_blt_operation_t;
struct grub_efi_gop_blt_pixel
{
grub_uint8_t blue;
grub_uint8_t green;
grub_uint8_t red;
grub_uint8_t reserved;
};
struct grub_efi_gop_pixel_bitmask
{
grub_uint32_t r;