mirror of
http://cgit.git.savannah.gnu.org/git/grub.git
synced 2026-04-28 14:33:34 +00:00
Compare commits
2 Commits
phcoder/ve
...
phcoder/ro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e29466b0b5 | ||
|
|
281b8b44ed |
@@ -34,39 +34,37 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/video.h>
|
||||
|
||||
/* Generic replacing blitter (slow). Works for every supported format. */
|
||||
static void
|
||||
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)
|
||||
static inline grub_uint8_t
|
||||
alpha_dilute (grub_uint8_t bg, grub_uint8_t fg, grub_uint8_t alpha)
|
||||
{
|
||||
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 + i, y + j, dst_color);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
#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. */
|
||||
static void
|
||||
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. */
|
||||
static void
|
||||
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,
|
||||
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)
|
||||
{
|
||||
/* Try to figure out more optimized version for replace operator. */
|
||||
|
||||
96
grub-core/video/fb/fbblit_rot.c
Normal file
96
grub-core/video/fb/fbblit_rot.c
Normal 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
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/fbutil.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/video.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
/* Generic filler that works for every supported mode. */
|
||||
static void
|
||||
|
||||
@@ -743,7 +743,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
|
||||
if ((mode_info->mode_type
|
||||
& 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
|
||||
&& color == 0xf0)
|
||||
{
|
||||
@@ -830,7 +830,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
|
||||
}
|
||||
|
||||
static void
|
||||
dirty (int y, int height)
|
||||
dirty_untrans (int y, int height)
|
||||
{
|
||||
if (framebuffer.render_target != framebuffer.back_target)
|
||||
return;
|
||||
@@ -840,6 +840,66 @@ dirty (int y, int 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_video_fb_fill_rect (grub_video_color_t color, int x, int y,
|
||||
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;
|
||||
y += area_y;
|
||||
|
||||
dirty (y, height);
|
||||
dirty (x, width, y, height);
|
||||
|
||||
/* Use fbblit_info to encapsulate rendering. */
|
||||
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);
|
||||
grub_video_rect_t orig = {
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -1008,7 +1076,7 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
|
||||
target.data = framebuffer.render_target->data;
|
||||
|
||||
/* Do actual blitting. */
|
||||
dirty (y, height);
|
||||
dirty (x, width, y, height);
|
||||
grub_video_fb_dispatch_blit (&target, source, oper, x, y, width, height,
|
||||
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 dst_x;
|
||||
int dst_y;
|
||||
grub_video_rect_t transformed_viewport;
|
||||
|
||||
/* 1. Check if we have something to do. */
|
||||
if ((dx == 0) && (dy == 0))
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
width = framebuffer.render_target->viewport.width - grub_abs (dx);
|
||||
height = framebuffer.render_target->viewport.height - grub_abs (dy);
|
||||
transformed_viewport = grub_video_transform_rectangle (framebuffer.render_target->viewport,
|
||||
&framebuffer.render_target->mode_info);
|
||||
|
||||
dirty (framebuffer.render_target->viewport.y,
|
||||
framebuffer.render_target->viewport.height);
|
||||
dirty (transformed_viewport.x,
|
||||
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)
|
||||
{
|
||||
src_x = framebuffer.render_target->viewport.x - dx;
|
||||
dst_x = framebuffer.render_target->viewport.x;
|
||||
src_x = transformed_viewport.x - dx;
|
||||
dst_x = transformed_viewport.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_x = framebuffer.render_target->viewport.x;
|
||||
dst_x = framebuffer.render_target->viewport.x + dx;
|
||||
src_x = transformed_viewport.x;
|
||||
dst_x = transformed_viewport.x + dx;
|
||||
}
|
||||
|
||||
if (dy < 0)
|
||||
{
|
||||
src_y = framebuffer.render_target->viewport.y - dy;
|
||||
dst_y = framebuffer.render_target->viewport.y;
|
||||
src_y = transformed_viewport.y - dy;
|
||||
dst_y = transformed_viewport.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_y = framebuffer.render_target->viewport.y;
|
||||
dst_y = framebuffer.render_target->viewport.y + dy;
|
||||
src_y = transformed_viewport.y;
|
||||
dst_y = transformed_viewport.y + dy;
|
||||
}
|
||||
|
||||
/* 2. Check if there is need to copy data. */
|
||||
if ((grub_abs (dx) < framebuffer.render_target->viewport.width)
|
||||
&& (grub_abs (dy) < framebuffer.render_target->viewport.height))
|
||||
if ((grub_abs (dx) < transformed_viewport.width)
|
||||
&& (grub_abs (dy) < transformed_viewport.height))
|
||||
{
|
||||
/* 3. Move data in render target. */
|
||||
struct grub_video_fbblit_info target;
|
||||
@@ -1109,7 +1205,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
|
||||
src = (void *) grub_video_fb_get_video_ptr (&target, \
|
||||
src_x, src_y); \
|
||||
/* 3a. Move data upwards. */ \
|
||||
for (j = 0; j < height; j++) \
|
||||
for (j = 0; j < height; j++) \
|
||||
{ \
|
||||
for (i = 0; i < linelen; i++) \
|
||||
*(dst++) = *(src++); \
|
||||
@@ -1128,7 +1224,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
|
||||
src_y + height - 1); \
|
||||
dst--; \
|
||||
src--; \
|
||||
for (j = 0; j < height; j++) \
|
||||
for (j = 0; j < height; j++) \
|
||||
{ \
|
||||
for (i = 0; i < linelen; i++) \
|
||||
*(dst--) = *(src--); \
|
||||
@@ -1178,27 +1274,27 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
|
||||
|
||||
/* 4a. Fill top & bottom parts. */
|
||||
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)
|
||||
{
|
||||
if (framebuffer.render_target->viewport.height < grub_abs (dy))
|
||||
dy = -framebuffer.render_target->viewport.height;
|
||||
if (transformed_viewport.height < grub_abs (dy))
|
||||
dy = -transformed_viewport.height;
|
||||
|
||||
grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy,
|
||||
framebuffer.render_target->viewport.width, -dy);
|
||||
grub_video_fb_fill_rect_untrans (color, 0, transformed_viewport.height + dy,
|
||||
transformed_viewport.width, -dy);
|
||||
}
|
||||
|
||||
/* 4b. Fill left & right parts. */
|
||||
if (dx > 0)
|
||||
grub_video_fb_fill_rect (color, 0, 0,
|
||||
dx, framebuffer.render_target->viewport.height);
|
||||
grub_video_fb_fill_rect_untrans (color, 0, 0,
|
||||
dx, transformed_viewport.height);
|
||||
else if (dx < 0)
|
||||
{
|
||||
if (framebuffer.render_target->viewport.width < grub_abs (dx))
|
||||
dx = -framebuffer.render_target->viewport.width;
|
||||
if (transformed_viewport.width < grub_abs (dx))
|
||||
dx = -transformed_viewport.width;
|
||||
|
||||
grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0,
|
||||
-dx, framebuffer.render_target->viewport.height);
|
||||
grub_video_fb_fill_rect_untrans (color, transformed_viewport.width + dx, 0,
|
||||
-dx, transformed_viewport.height);
|
||||
}
|
||||
|
||||
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.
|
||||
Currently only 32bit render targets are supported. */
|
||||
|
||||
target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
|
||||
|
||||
/* Mark render target as allocated. */
|
||||
target->is_allocated = 1;
|
||||
|
||||
@@ -1253,6 +1351,8 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
|
||||
/* Setup render target format. */
|
||||
target->mode_info.width = width;
|
||||
target->mode_info.height = height;
|
||||
target->mode_info.original_width = width;
|
||||
target->mode_info.original_height = height;
|
||||
switch (mode_type)
|
||||
{
|
||||
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));
|
||||
|
||||
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. */
|
||||
target->viewport.x = 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;
|
||||
|
||||
/* 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,
|
||||
mode_info->bytes_per_pixel * mode_info->width);
|
||||
mode_info->bytes_per_pixel * target->mode_info.original_width);
|
||||
|
||||
/* Save result to caller. */
|
||||
*result = target;
|
||||
@@ -1427,7 +1538,7 @@ doublebuf_blit_update_screen (void)
|
||||
* (framebuffer.current_dirty.last_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;
|
||||
|
||||
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.set_page = 0;
|
||||
framebuffer.current_dirty.first_line
|
||||
= framebuffer.back_target->mode_info.height;
|
||||
= framebuffer.back_target->mode_info.original_height;
|
||||
framebuffer.current_dirty.last_line = 0;
|
||||
|
||||
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),
|
||||
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
|
||||
kernel drivers expect that. */
|
||||
if (framebuffer.set_page && framebuffer.displayed_page != 0)
|
||||
|
||||
@@ -75,6 +75,13 @@ typedef enum grub_video_mode_type
|
||||
GRUB_VIDEO_MODE_TYPE_INFO_MASK = 0x00FF0000,
|
||||
} 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
|
||||
renders to the back buffer when double-buffering is in use. */
|
||||
#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
|
||||
@@ -122,12 +129,20 @@ enum grub_video_blit_operators
|
||||
|
||||
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;
|
||||
|
||||
/* Height of the screen. */
|
||||
/* Height of the screen, after the rotation. */
|
||||
unsigned int height;
|
||||
|
||||
enum grub_video_rotation rotation;
|
||||
|
||||
/* Mode type bitmask. Contains information like is it Index color or
|
||||
RGB mode. */
|
||||
grub_video_mode_type_t mode_type;
|
||||
|
||||
Reference in New Issue
Block a user