Compare commits

...
Author SHA1 Message Date
Vladimir Serbinenko e29466b0b5 WIP: rotate. 2017-02-09 02:25:12 +01:00
Vladimir Serbinenko 281b8b44ed video_fb: Fix blue collor if using unoptimized blitter.
when unmapping the color what matters is the mode of source, not target.
2017-02-09 02:22:24 +01:00
5 changed files with 330 additions and 139 deletions

No files matched your search

+67 -102
View File
@@ -34,39 +34,37 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/video.h> #include <grub/video.h>
/* Generic replacing blitter (slow). Works for every supported format. */ static inline grub_uint8_t
static void alpha_dilute (grub_uint8_t bg, grub_uint8_t fg, grub_uint8_t alpha)
grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
struct grub_video_fbblit_info *src,
int x, int y, int width, int height,
int offset_x, int offset_y)
{ {
int i; grub_uint16_t s;
int j; grub_uint16_t h, l;
grub_uint8_t src_red; s = (fg * alpha) + (bg * (255 ^ alpha));
grub_uint8_t src_green; /* Optimised division by 255. */
grub_uint8_t src_blue; h = s >> 8;
grub_uint8_t src_alpha; l = s & 0xff;
grub_video_color_t src_color; if (h + l >= 255)
grub_video_color_t dst_color; h++;
return h;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
src_color = get_pixel (src, i + offset_x, j + offset_y);
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
dst_color = grub_video_fb_map_rgba (src_red, src_green,
src_blue, src_alpha);
set_pixel (dst, x + i, y + j, dst_color);
}
}
} }
#define SUFFIX(x) x
#define ADD_X 0
#define ADD_Y 0
#define TRANS_X(x, y) x
#define TRANS_Y(x, y) y
#include "fbblit_rot.c"
#define SUFFIX(x) x ## _90
#define TRANS_X(x, y) (y)
#define TRANS_Y(x, y) (-(x))
#include "fbblit_rot.c"
#define SUFFIX(x) x ## _270
#define TRANS_X(x, y) (-(y))
#define TRANS_Y(x, y) (x)
#include "fbblit_rot.c"
/* Block copy replacing blitter. Works with modes multiple of 8 bits. */ /* Block copy replacing blitter. Works with modes multiple of 8 bits. */
static void static void
grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst, grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
@@ -1145,78 +1143,6 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
} }
} }
static inline grub_uint8_t
alpha_dilute (grub_uint8_t bg, grub_uint8_t fg, grub_uint8_t alpha)
{
grub_uint16_t s;
grub_uint16_t h, l;
s = (fg * alpha) + (bg * (255 ^ alpha));
/* Optimised division by 255. */
h = s >> 8;
l = s & 0xff;
if (h + l >= 255)
h++;
return h;
}
/* Generic blending blitter. Works for every supported format. */
static void
grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
struct grub_video_fbblit_info *src,
int x, int y, int width, int height,
int offset_x, int offset_y)
{
int i;
int j;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
grub_uint8_t src_red;
grub_uint8_t src_green;
grub_uint8_t src_blue;
grub_uint8_t src_alpha;
grub_uint8_t dst_red;
grub_uint8_t dst_green;
grub_uint8_t dst_blue;
grub_uint8_t dst_alpha;
grub_video_color_t src_color;
grub_video_color_t dst_color;
src_color = get_pixel (src, i + offset_x, j + offset_y);
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
if (src_alpha == 0)
continue;
if (src_alpha == 255)
{
dst_color = grub_video_fb_map_rgba (src_red, src_green,
src_blue, src_alpha);
set_pixel (dst, x + i, y + j, dst_color);
continue;
}
dst_color = get_pixel (dst, x + i, y + j);
grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
&dst_green, &dst_blue, &dst_alpha);
dst_red = alpha_dilute (dst_red, src_red, src_alpha);
dst_green = alpha_dilute (dst_green, src_green, src_alpha);
dst_blue = alpha_dilute (dst_blue, src_blue, src_alpha);
dst_alpha = src_alpha;
dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
dst_alpha);
set_pixel (dst, x + i, y + j, dst_color);
}
}
}
/* Optimized blending blitter for RGBA8888 to BGRA8888. */ /* Optimized blending blitter for RGBA8888 to BGRA8888. */
static void static void
grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst, grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
@@ -1936,6 +1862,45 @@ grub_video_fb_dispatch_blit (struct grub_video_fbblit_info *target,
unsigned int width, unsigned int height, unsigned int width, unsigned int height,
int offset_x, int offset_y) int offset_x, int offset_y)
{ {
if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_90)
{
int nx = y;
int ny = target->mode_info->width - x;
if (oper == GRUB_VIDEO_BLIT_REPLACE)
{
/* No optimized replace operator found, use default (slow) blitter. */
grub_video_fbblit_replace_90 (target, source, nx, ny, width, height,
offset_x, offset_y);
return;
}
else
{
/* No optimized replace operator found, use default (slow) blitter. */
grub_video_fbblit_blend_90 (target, source, nx, ny, width, height,
offset_x, offset_y);
return;
}
}
if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_270)
{
int nx = target->mode_info->height - y;
int ny = x;
if (oper == GRUB_VIDEO_BLIT_REPLACE)
{
/* No optimized replace operator found, use default (slow) blitter. */
grub_video_fbblit_replace_270 (target, source, nx, ny, width, height,
offset_x, offset_y);
return;
}
else
{
/* No optimized replace operator found, use default (slow) blitter. */
grub_video_fbblit_blend_270 (target, source, nx, ny, width, height,
offset_x, offset_y);
return;
}
}
if (oper == GRUB_VIDEO_BLIT_REPLACE) if (oper == GRUB_VIDEO_BLIT_REPLACE)
{ {
/* Try to figure out more optimized version for replace operator. */ /* Try to figure out more optimized version for replace operator. */
+96
View File
@@ -0,0 +1,96 @@
/* Generic replacing blitter (slow). Works for every supported format. */
static void
SUFFIX(grub_video_fbblit_replace) (struct grub_video_fbblit_info *dst,
struct grub_video_fbblit_info *src,
int x, int y, int width, int height,
int offset_x, int offset_y)
{
int i;
int j;
grub_uint8_t src_red;
grub_uint8_t src_green;
grub_uint8_t src_blue;
grub_uint8_t src_alpha;
grub_video_color_t src_color;
grub_video_color_t dst_color;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
src_color = get_pixel (src, i + offset_x, j + offset_y);
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
dst_color = grub_video_fb_map_rgba (src_red, src_green,
src_blue, src_alpha);
set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
}
}
}
/* Generic blending blitter. Works for every supported format. */
static void
SUFFIX(grub_video_fbblit_blend) (struct grub_video_fbblit_info *dst,
struct grub_video_fbblit_info *src,
int x, int y, int width, int height,
int offset_x, int offset_y)
{
int i;
int j;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
grub_uint8_t src_red;
grub_uint8_t src_green;
grub_uint8_t src_blue;
grub_uint8_t src_alpha;
grub_uint8_t dst_red;
grub_uint8_t dst_green;
grub_uint8_t dst_blue;
grub_uint8_t dst_alpha;
grub_video_color_t src_color;
grub_video_color_t dst_color;
src_color = get_pixel (src, i + offset_x, j + offset_y);
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
&src_blue, &src_alpha);
if (src_alpha == 0)
continue;
if (src_alpha == 255)
{
dst_color = grub_video_fb_map_rgba (src_red, src_green,
src_blue, src_alpha);
set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
continue;
}
dst_color = get_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j));
grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
&dst_green, &dst_blue, &dst_alpha);
dst_red = alpha_dilute (dst_red, src_red, src_alpha);
dst_green = alpha_dilute (dst_green, src_green, src_alpha);
dst_blue = alpha_dilute (dst_blue, src_blue, src_alpha);
dst_alpha = src_alpha;
dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
dst_alpha);
set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
}
}
}
#undef SUFFIX
#undef ADD_X
#undef ADD_Y
#undef TRANS_X
#undef TRANS_Y
+1
View File
@@ -32,6 +32,7 @@
#include <grub/fbutil.h> #include <grub/fbutil.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/video.h> #include <grub/video.h>
#include <grub/misc.h>
/* Generic filler that works for every supported mode. */ /* Generic filler that works for every supported mode. */
static void static void
+149 -35
View File
@@ -743,7 +743,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
if ((mode_info->mode_type if ((mode_info->mode_type
& GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
{ {
if ((framebuffer.render_target->mode_info.mode_type if ((mode_info->mode_type
& GRUB_VIDEO_MODE_TYPE_ALPHA) != 0 & GRUB_VIDEO_MODE_TYPE_ALPHA) != 0
&& color == 0xf0) && color == 0xf0)
{ {
@@ -830,7 +830,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
} }
static void static void
dirty (int y, int height) dirty_untrans (int y, int height)
{ {
if (framebuffer.render_target != framebuffer.back_target) if (framebuffer.render_target != framebuffer.back_target)
return; return;
@@ -840,6 +840,66 @@ dirty (int y, int height)
framebuffer.current_dirty.last_line = y + height; framebuffer.current_dirty.last_line = y + height;
} }
static void
dirty (int x, int width, int y, int height)
{
if (framebuffer.render_target != framebuffer.back_target)
return;
if (framebuffer.render_target->mode_info.rotation == GRUB_VIDEO_ROTATE_90
|| framebuffer.render_target->mode_info.rotation == GRUB_VIDEO_ROTATE_270)
{
if (framebuffer.current_dirty.first_line > x)
framebuffer.current_dirty.first_line = x;
if (framebuffer.current_dirty.last_line < x + width)
framebuffer.current_dirty.last_line = x + width;
}
else
{
if (framebuffer.current_dirty.first_line > y)
framebuffer.current_dirty.first_line = y;
if (framebuffer.current_dirty.last_line < y + height)
framebuffer.current_dirty.last_line = y + height;
}
}
static void
grub_video_fb_fill_rect_untrans (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height)
{
struct grub_video_fbblit_info target;
target.mode_info = &framebuffer.render_target->mode_info;
target.data = framebuffer.render_target->data;
grub_video_fb_fill_dispatch (&target, color, x, y,
width, height);
dirty_untrans (y, height);
}
static grub_video_rect_t
grub_video_transform_rectangle (grub_video_rect_t r, const struct grub_video_mode_info *mode_info)
{
grub_video_rect_t n;
switch (mode_info->rotation)
{
case GRUB_VIDEO_ROTATE_NONE:
return r;
case GRUB_VIDEO_ROTATE_90:
n.width = r.height;
n.height = r.width;
n.x = r.y;
n.y = mode_info->width - r.x - r.width;
return n;
case GRUB_VIDEO_ROTATE_270:
n.width = r.height;
n.height = r.width;
n.x = mode_info->height - r.y - r.height;
n.y = r.x;
return n;
}
return r;
}
grub_err_t grub_err_t
grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height) unsigned int width, unsigned int height)
@@ -895,14 +955,22 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
x += area_x; x += area_x;
y += area_y; y += area_y;
dirty (y, height); dirty (x, width, y, height);
/* Use fbblit_info to encapsulate rendering. */ /* Use fbblit_info to encapsulate rendering. */
target.mode_info = &framebuffer.render_target->mode_info; target.mode_info = &framebuffer.render_target->mode_info;
target.data = framebuffer.render_target->data; target.data = framebuffer.render_target->data;
grub_video_fb_fill_dispatch (&target, color, x, y, grub_video_rect_t orig = {
width, height); .x = x,
.y = y,
.width = width,
.height = height
};
grub_video_rect_t tran = grub_video_transform_rectangle (orig, &framebuffer.render_target->mode_info);
grub_video_fb_fill_dispatch (&target, color, tran.x, tran.y,
tran.width, tran.height);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@@ -1008,7 +1076,7 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
target.data = framebuffer.render_target->data; target.data = framebuffer.render_target->data;
/* Do actual blitting. */ /* Do actual blitting. */
dirty (y, height); dirty (x, width, y, height);
grub_video_fb_dispatch_blit (&target, source, oper, x, y, width, height, grub_video_fb_dispatch_blit (&target, source, oper, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
@@ -1052,42 +1120,70 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
int src_y; int src_y;
int dst_x; int dst_x;
int dst_y; int dst_y;
grub_video_rect_t transformed_viewport;
/* 1. Check if we have something to do. */ /* 1. Check if we have something to do. */
if ((dx == 0) && (dy == 0)) if ((dx == 0) && (dy == 0))
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
width = framebuffer.render_target->viewport.width - grub_abs (dx); transformed_viewport = grub_video_transform_rectangle (framebuffer.render_target->viewport,
height = framebuffer.render_target->viewport.height - grub_abs (dy); &framebuffer.render_target->mode_info);
dirty (framebuffer.render_target->viewport.y, dirty (transformed_viewport.x,
framebuffer.render_target->viewport.height); transformed_viewport.width,
transformed_viewport.y,
transformed_viewport.height);
switch (framebuffer.render_target->mode_info.rotation)
{
case GRUB_VIDEO_ROTATE_NONE:
break;
case GRUB_VIDEO_ROTATE_90:
{
int ndx = dy;
int ndy = -dx;
dx = ndx;
dy = ndy;
}
break;
case GRUB_VIDEO_ROTATE_270:
{
int ndx = -dy;
int ndy = dx;
dx = ndx;
dy = ndy;
}
break;
}
width = transformed_viewport.width - grub_abs (dx);
height = transformed_viewport.height - grub_abs (dy);
if (dx < 0) if (dx < 0)
{ {
src_x = framebuffer.render_target->viewport.x - dx; src_x = transformed_viewport.x - dx;
dst_x = framebuffer.render_target->viewport.x; dst_x = transformed_viewport.x;
} }
else else
{ {
src_x = framebuffer.render_target->viewport.x; src_x = transformed_viewport.x;
dst_x = framebuffer.render_target->viewport.x + dx; dst_x = transformed_viewport.x + dx;
} }
if (dy < 0) if (dy < 0)
{ {
src_y = framebuffer.render_target->viewport.y - dy; src_y = transformed_viewport.y - dy;
dst_y = framebuffer.render_target->viewport.y; dst_y = transformed_viewport.y;
} }
else else
{ {
src_y = framebuffer.render_target->viewport.y; src_y = transformed_viewport.y;
dst_y = framebuffer.render_target->viewport.y + dy; dst_y = transformed_viewport.y + dy;
} }
/* 2. Check if there is need to copy data. */ /* 2. Check if there is need to copy data. */
if ((grub_abs (dx) < framebuffer.render_target->viewport.width) if ((grub_abs (dx) < transformed_viewport.width)
&& (grub_abs (dy) < framebuffer.render_target->viewport.height)) && (grub_abs (dy) < transformed_viewport.height))
{ {
/* 3. Move data in render target. */ /* 3. Move data in render target. */
struct grub_video_fbblit_info target; struct grub_video_fbblit_info target;
@@ -1178,27 +1274,27 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
/* 4a. Fill top & bottom parts. */ /* 4a. Fill top & bottom parts. */
if (dy > 0) if (dy > 0)
grub_video_fb_fill_rect (color, 0, 0, framebuffer.render_target->viewport.width, dy); grub_video_fb_fill_rect_untrans (color, 0, 0, transformed_viewport.width, dy);
else if (dy < 0) else if (dy < 0)
{ {
if (framebuffer.render_target->viewport.height < grub_abs (dy)) if (transformed_viewport.height < grub_abs (dy))
dy = -framebuffer.render_target->viewport.height; dy = -transformed_viewport.height;
grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy, grub_video_fb_fill_rect_untrans (color, 0, transformed_viewport.height + dy,
framebuffer.render_target->viewport.width, -dy); transformed_viewport.width, -dy);
} }
/* 4b. Fill left & right parts. */ /* 4b. Fill left & right parts. */
if (dx > 0) if (dx > 0)
grub_video_fb_fill_rect (color, 0, 0, grub_video_fb_fill_rect_untrans (color, 0, 0,
dx, framebuffer.render_target->viewport.height); dx, transformed_viewport.height);
else if (dx < 0) else if (dx < 0)
{ {
if (framebuffer.render_target->viewport.width < grub_abs (dx)) if (transformed_viewport.width < grub_abs (dx))
dx = -framebuffer.render_target->viewport.width; dx = -transformed_viewport.width;
grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0, grub_video_fb_fill_rect_untrans (color, transformed_viewport.width + dx, 0,
-dx, framebuffer.render_target->viewport.height); -dx, transformed_viewport.height);
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@@ -1228,6 +1324,8 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
/* TODO: Implement other types too. /* TODO: Implement other types too.
Currently only 32bit render targets are supported. */ Currently only 32bit render targets are supported. */
target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
/* Mark render target as allocated. */ /* Mark render target as allocated. */
target->is_allocated = 1; target->is_allocated = 1;
@@ -1253,6 +1351,8 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
/* Setup render target format. */ /* Setup render target format. */
target->mode_info.width = width; target->mode_info.width = width;
target->mode_info.height = height; target->mode_info.height = height;
target->mode_info.original_width = width;
target->mode_info.original_height = height;
switch (mode_type) switch (mode_type)
{ {
case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
@@ -1336,6 +1436,17 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info)); grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
target->mode_info.rotation = GRUB_VIDEO_ROTATE_270; ///!!!
target->mode_info.original_width = target->mode_info.width;
target->mode_info.original_height = target->mode_info.height;
if (target->mode_info.rotation == GRUB_VIDEO_ROTATE_90
|| target->mode_info.rotation == GRUB_VIDEO_ROTATE_270)
{
target->mode_info.width = target->mode_info.original_height;
target->mode_info.height = target->mode_info.original_width;
}
/* Reset viewport, region and area to match new mode. */ /* Reset viewport, region and area to match new mode. */
target->viewport.x = 0; target->viewport.x = 0;
target->viewport.y = 0; target->viewport.y = 0;
@@ -1356,9 +1467,9 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
target->area_offset_y = 0; target->area_offset_y = 0;
/* Clear render target with black and maximum transparency. */ /* Clear render target with black and maximum transparency. */
for (y = 0; y < mode_info->height; y++) for (y = 0; y < target->mode_info.original_height; y++)
grub_memset (target->data + mode_info->pitch * y, 0, grub_memset (target->data + mode_info->pitch * y, 0,
mode_info->bytes_per_pixel * mode_info->width); mode_info->bytes_per_pixel * target->mode_info.original_width);
/* Save result to caller. */ /* Save result to caller. */
*result = target; *result = target;
@@ -1427,7 +1538,7 @@ doublebuf_blit_update_screen (void)
* (framebuffer.current_dirty.last_line * (framebuffer.current_dirty.last_line
- framebuffer.current_dirty.first_line)); - framebuffer.current_dirty.first_line));
framebuffer.current_dirty.first_line framebuffer.current_dirty.first_line
= framebuffer.back_target->mode_info.height; = framebuffer.back_target->mode_info.original_height;
framebuffer.current_dirty.last_line = 0; framebuffer.current_dirty.last_line = 0;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@@ -1636,7 +1747,7 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask,
framebuffer.render_page = 0; framebuffer.render_page = 0;
framebuffer.set_page = 0; framebuffer.set_page = 0;
framebuffer.current_dirty.first_line framebuffer.current_dirty.first_line
= framebuffer.back_target->mode_info.height; = framebuffer.back_target->mode_info.original_height;
framebuffer.current_dirty.last_line = 0; framebuffer.current_dirty.last_line = 0;
mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
@@ -1668,6 +1779,9 @@ grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info,
grub_memcpy (mode_info, &(framebuffer.back_target->mode_info), grub_memcpy (mode_info, &(framebuffer.back_target->mode_info),
sizeof (*mode_info)); sizeof (*mode_info));
mode_info->width = framebuffer.back_target->mode_info.original_width;
mode_info->height = framebuffer.back_target->mode_info.original_height;
/* We are about to load a kernel. Switch back to page zero, since some /* We are about to load a kernel. Switch back to page zero, since some
kernel drivers expect that. */ kernel drivers expect that. */
if (framebuffer.set_page && framebuffer.displayed_page != 0) if (framebuffer.set_page && framebuffer.displayed_page != 0)
+17 -2
View File
@@ -75,6 +75,13 @@ typedef enum grub_video_mode_type
GRUB_VIDEO_MODE_TYPE_INFO_MASK = 0x00FF0000, GRUB_VIDEO_MODE_TYPE_INFO_MASK = 0x00FF0000,
} grub_video_mode_type_t; } grub_video_mode_type_t;
enum grub_video_rotation
{
GRUB_VIDEO_ROTATE_NONE,
GRUB_VIDEO_ROTATE_90,
GRUB_VIDEO_ROTATE_270,
};
/* The basic render target representing the whole display. This always /* The basic render target representing the whole display. This always
renders to the back buffer when double-buffering is in use. */ renders to the back buffer when double-buffering is in use. */
#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \ #define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
@@ -122,12 +129,20 @@ enum grub_video_blit_operators
struct grub_video_mode_info struct grub_video_mode_info
{ {
/* Width of the screen. */ /* Width of the screen, before the rotation. */
unsigned int original_width;
/* Height of the screen, before the rotation. */
unsigned int original_height;
/* Width of the screen, after the rotation. */
unsigned int width; unsigned int width;
/* Height of the screen. */ /* Height of the screen, after the rotation. */
unsigned int height; unsigned int height;
enum grub_video_rotation rotation;
/* Mode type bitmask. Contains information like is it Index color or /* Mode type bitmask. Contains information like is it Index color or
RGB mode. */ RGB mode. */
grub_video_mode_type_t mode_type; grub_video_mode_type_t mode_type;