From 18f0215d54546b2d4ccb1ff4877c48d5de00e1b3 Mon Sep 17 00:00:00 2001
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Date: Sat, 4 May 2013 13:58:30 +0200
Subject: [PATCH 422/482] Speed-up gfxterm by saving intermediate
results in index+alpha format.
---
ChangeLog | 5 +
grub-core/term/gfxterm.c | 2 +-
grub-core/video/fb/fbblit.c | 370 ++++++++++++++++++++++++++++++++++++++++++
grub-core/video/fb/video_fb.c | 298 ++++++++++++++++++++--------------
include/grub/video.h | 5 +
include/grub/video_fb.h | 54 ++++++
6 files changed, 613 insertions(+), 121 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d5f9bb9..74cb13d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2013-05-04 Vladimir Serbinenko <phcoder@gmail.com>
+ Speed-up gfxterm by saving intermediate results in index+alpha
+ format.
+
+2013-05-04 Vladimir Serbinenko <phcoder@gmail.com>
+
* grub-core/tests/lib/functional_test.c: Don't stop on first failed
test.
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
index 1e33a34..54636d7 100644
--- a/grub-core/term/gfxterm.c
+++ b/grub-core/term/gfxterm.c
@@ -254,7 +254,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
grub_video_create_render_target (&text_layer,
virtual_screen.width,
virtual_screen.height,
- GRUB_VIDEO_MODE_TYPE_RGB
+ GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
| GRUB_VIDEO_MODE_TYPE_ALPHA);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c
index 541a0ce..c206ac8 100644
--- a/grub-core/video/fb/fbblit.c
+++ b/grub-core/video/fb/fbblit.c
@@ -389,6 +389,376 @@ grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
}
}
+void
+grub_video_fbblit_replace_32bit_indexa (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 *srcptr;
+ grub_uint32_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint32_t palette[17];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+ palette[16] = grub_video_fb_map_rgba (0, 0, 0, 0);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr == 0xf0)
+ *dstptr = palette[16];
+ else
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 16bit. */
+void
+grub_video_fbblit_replace_24bit_indexa (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 *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint32_t palette[17];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+ palette[16] = grub_video_fb_map_rgba (0, 0, 0, 0);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ register grub_uint32_t col;
+ if (*srcptr == 0xf0)
+ col = palette[16];
+ else
+ col = palette[*srcptr & 0xf];
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ *dstptr++ = col >> 16;
+ *dstptr++ = col >> 8;
+ *dstptr++ = col >> 0;
+#else
+ *dstptr++ = col >> 0;
+ *dstptr++ = col >> 8;
+ *dstptr++ = col >> 16;
+#endif
+ srcptr++;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 16bit. */
+void
+grub_video_fbblit_replace_16bit_indexa (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 *srcptr;
+ grub_uint16_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint16_t palette[17];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+ palette[16] = grub_video_fb_map_rgba (0, 0, 0, 0);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr == 0xf0)
+ *dstptr = palette[16];
+ else
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 8bit. */
+void
+grub_video_fbblit_replace_8bit_indexa (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 *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint8_t palette[17];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+ palette[16] = grub_video_fb_map_rgba (0, 0, 0, 0);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr == 0xf0)
+ *dstptr = palette[16];
+ else
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+
+void
+grub_video_fbblit_blend_32bit_indexa (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 *srcptr;
+ grub_uint32_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint32_t palette[16];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr != 0xf0)
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 16bit. */
+void
+grub_video_fbblit_blend_24bit_indexa (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 *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint32_t palette[16];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ register grub_uint32_t col;
+ if (*srcptr != 0xf0)
+ {
+ col = palette[*srcptr & 0xf];
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ *dstptr++ = col >> 16;
+ *dstptr++ = col >> 8;
+ *dstptr++ = col >> 0;
+#else
+ *dstptr++ = col >> 0;
+ *dstptr++ = col >> 8;
+ *dstptr++ = col >> 16;
+#endif
+ }
+ else
+ dstptr += 3;
+ srcptr++;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 16bit. */
+void
+grub_video_fbblit_blend_16bit_indexa (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 *srcptr;
+ grub_uint16_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint16_t palette[17];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr != 0xf0)
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
+ }
+}
+
+/* Optimized replacing blitter for 1-bit to 8bit. */
+void
+grub_video_fbblit_blend_8bit_indexa (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 *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int dstrowskip;
+ unsigned int srcrowskip;
+ grub_uint8_t palette[16];
+
+ srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = grub_video_fb_get_video_ptr (dst, x, y);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ srcrowskip = src->mode_info->pitch - width;
+
+ for (i = 0; i < 16; i++)
+ palette[i] = grub_video_fb_map_color (i);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ if (*srcptr != 0xf0)
+ *dstptr = palette[*srcptr & 0xf];
+ srcptr++;
+ dstptr++;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+
/* Optimized replacing blitter for RGBX8888 to BGRX8888. */
void
grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
index 836842e..22a0128 100644
--- a/grub-core/video/fb/video_fb.c
+++ b/grub-core/video/fb/video_fb.c
@@ -542,11 +542,18 @@ grub_video_color_t
grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
grub_uint8_t blue, grub_uint8_t alpha)
{
+
if ((framebuffer.render_target->mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- /* No alpha available in index color modes, just use
- same value as in only RGB modes. */
- return grub_video_fb_map_rgb (red, green, blue);
+ {
+ if ((framebuffer.render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_ALPHA) != 0
+ && alpha == 0)
+ return 0xf0;
+ /* No alpha available in index color modes, just use
+ same value as in only RGB modes. */
+ return grub_video_fb_map_rgb (red, green, blue);
+ }
else if ((framebuffer.render_target->mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
{
@@ -605,6 +612,17 @@ 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
+ & GRUB_VIDEO_MODE_TYPE_ALPHA) != 0
+ && color == 0xf0)
+ {
+ *red = 0;
+ *green = 0;
+ *blue = 0;
+ *alpha = 0;
+ return;
+ }
+
/* If we have an out-of-bounds color, return transparent black. */
if (color > 255)
{
@@ -772,134 +790,153 @@ common_blitter (struct grub_video_fbblit_info *target,
if (oper == GRUB_VIDEO_BLIT_REPLACE)
{
/* Try to figure out more optimized version for replace operator. */
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ switch (source->mode_info->blit_format)
{
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_replace_directN (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
grub_video_fbblit_replace_index_RGBX8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
grub_video_fbblit_replace_BGR888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
grub_video_fbblit_replace_directN (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
grub_video_fbblit_replace_index_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_directN (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA:
grub_video_fbblit_replace_directN (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
- {
- if (target->mode_info->bpp == 32)
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA:
+ switch (target->mode_info->bytes_per_pixel)
+ {
+ case 4:
+ grub_video_fbblit_replace_32bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 3:
+ grub_video_fbblit_replace_24bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 2:
+ grub_video_fbblit_replace_16bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 1:
+ grub_video_fbblit_replace_8bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ default:
+ break;
+ }
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED:
+ switch (target->mode_info->bytes_per_pixel)
{
+ case 4:
grub_video_fbblit_replace_32bit_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
#ifdef GRUB_HAVE_UNALIGNED_ACCESS
- else if (target->mode_info->bpp == 24)
- {
+ case 3:
grub_video_fbblit_replace_24bit_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
#endif
- else if (target->mode_info->bpp == 16)
- {
+ case 2:
grub_video_fbblit_replace_16bit_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->bpp == 8)
- {
+ case 1:
grub_video_fbblit_replace_8bit_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
}
+ break;
+ default:
+ break;
}
/* No optimized replace operator found, use default (slow) blitter. */
@@ -909,123 +946,131 @@ common_blitter (struct grub_video_fbblit_info *target,
else
{
/* Try to figure out more optimized blend operator. */
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ switch (source->mode_info->blit_format)
{
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
grub_video_fbblit_blend_index_RGBA8888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
/* Note: There is really no alpha information here, so blend is
changed to replace. */
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
grub_video_fbblit_replace_BGR888_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
grub_video_fbblit_replace_directN (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
grub_video_fbblit_replace_index_RGB888 (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
- {
- if (target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
- || target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED:
+ switch (target->mode_info->blit_format)
{
+ case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
+ case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_blend_XXXA8888_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
#ifdef GRUB_HAVE_UNALIGNED_ACCESS
- else if (target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_BGR_888
- || target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
grub_video_fbblit_blend_XXX888_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
- }
#endif
- else if (target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_BGR_565
- || target->mode_info->blit_format
- == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
- {
+ case GRUB_VIDEO_BLIT_FORMAT_BGR_565:
+ case GRUB_VIDEO_BLIT_FORMAT_RGB_565:
grub_video_fbblit_blend_XXX565_1bit (target, source,
x, y, width, height,
offset_x, offset_y);
return;
+ default:
+ break;
}
-
+ break;
+ case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA:
+ switch (target->mode_info->bytes_per_pixel)
+ {
+ case 4:
+ grub_video_fbblit_blend_32bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 3:
+ grub_video_fbblit_blend_24bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 2:
+ grub_video_fbblit_blend_16bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ case 1:
+ grub_video_fbblit_blend_8bit_indexa (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ break;
+ default:
+ break;
}
-
/* No optimized blend operation found, use default (slow) blitter. */
grub_video_fbblit_blend (target, source, x, y, width, height,
offset_x, offset_y);
@@ -1411,22 +1456,35 @@ 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.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
- | GRUB_VIDEO_MODE_TYPE_ALPHA;
- target->mode_info.bpp = 32;
- target->mode_info.bytes_per_pixel = 4;
+ switch (mode_type)
+ {
+ case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
+ | GRUB_VIDEO_MODE_TYPE_ALPHA:
+ target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
+ | GRUB_VIDEO_MODE_TYPE_ALPHA;
+ target->mode_info.bpp = 8;
+ target->mode_info.bytes_per_pixel = 1;
+ target->mode_info.number_of_colors = 16;
+ target->mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA;
+ break;
+ default:
+ target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+ | GRUB_VIDEO_MODE_TYPE_ALPHA;
+ target->mode_info.bpp = 32;
+ target->mode_info.bytes_per_pixel = 4;
+ target->mode_info.red_mask_size = 8;
+ target->mode_info.red_field_pos = 0;
+ target->mode_info.green_mask_size = 8;
+ target->mode_info.green_field_pos = 8;
+ target->mode_info.blue_mask_size = 8;
+ target->mode_info.blue_field_pos = 16;
+ target->mode_info.reserved_mask_size = 8;
+ target->mode_info.reserved_field_pos = 24;
+ target->mode_info.number_of_colors = framebuffer.palette_size; /* Emulated palette. */
+ target->mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
+ break;
+ }
target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
- target->mode_info.number_of_colors = framebuffer.palette_size; /* Emulated palette. */
- target->mode_info.red_mask_size = 8;
- target->mode_info.red_field_pos = 0;
- target->mode_info.green_mask_size = 8;
- target->mode_info.green_field_pos = 8;
- target->mode_info.blue_mask_size = 8;
- target->mode_info.blue_field_pos = 16;
- target->mode_info.reserved_mask_size = 8;
- target->mode_info.reserved_field_pos = 24;
-
- target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
/* Calculate size needed for the data. */
size = (width * target->mode_info.bytes_per_pixel) * height;
diff --git a/include/grub/video.h b/include/grub/video.h
index 36e863b..b2d1458 100644
--- a/include/grub/video.h
+++ b/include/grub/video.h
@@ -101,6 +101,11 @@ enum grub_video_blit_format
/* When needed, decode color or just use value as is. */
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
+ /* Like index but only 16-colors and F0 is a special value for transparency.
+ Could be extended to 4 bits of alpha and 4 bits of color if necessary.
+ Used internally for text rendering.
+ */
+ GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA,
/* Two color bitmap; bits packed: rows are not padded to byte boundary. */
GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
index ffe16c3..88bc75d 100644
--- a/include/grub/video_fb.h
+++ b/include/grub/video_fb.h
@@ -118,6 +118,60 @@ EXPORT_FUNC(grub_video_fb_get_active_render_target) (struct grub_video_fbrender_
grub_err_t
EXPORT_FUNC(grub_video_fb_set_active_render_target) (struct grub_video_fbrender_target *target);
+void
+EXPORT_FUNC (grub_video_fbblit_blend_32bit_indexa) (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);
+
+void
+EXPORT_FUNC (grub_video_fbblit_blend_24bit_indexa) (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);
+void
+EXPORT_FUNC (grub_video_fbblit_blend_16bit_indexa) (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);
+void
+EXPORT_FUNC (grub_video_fbblit_blend_8bit_indexa) (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);
+
+
+void
+EXPORT_FUNC (grub_video_fbblit_replace_32bit_indexa) (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);
+
+void
+EXPORT_FUNC (grub_video_fbblit_replace_24bit_indexa) (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);
+
+void
+EXPORT_FUNC (grub_video_fbblit_replace_16bit_indexa) (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);
+void
+EXPORT_FUNC (grub_video_fbblit_replace_8bit_indexa) (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);
+
typedef grub_err_t (*grub_video_fb_set_page_t) (int page);
grub_err_t
--
1.8.2.1