Speed-up gfxterm by saving intermediate results in index+alpha

format.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-05-04 13:58:30 +02:00
parent 0fb356a385
commit 92323d1fb0
6 changed files with 613 additions and 121 deletions

View file

@ -1,3 +1,8 @@
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> 2013-05-04 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/tests/lib/functional_test.c: Don't stop on first failed * grub-core/tests/lib/functional_test.c: Don't stop on first failed

View file

@ -254,7 +254,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
grub_video_create_render_target (&text_layer, grub_video_create_render_target (&text_layer,
virtual_screen.width, virtual_screen.width,
virtual_screen.height, virtual_screen.height,
GRUB_VIDEO_MODE_TYPE_RGB GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
| GRUB_VIDEO_MODE_TYPE_ALPHA); | GRUB_VIDEO_MODE_TYPE_ALPHA);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
return grub_errno; return grub_errno;

View file

@ -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. */ /* Optimized replacing blitter for RGBX8888 to BGRX8888. */
void void
grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst, grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,

View file

@ -542,11 +542,18 @@ grub_video_color_t
grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
grub_uint8_t blue, grub_uint8_t alpha) grub_uint8_t blue, grub_uint8_t alpha)
{ {
if ((framebuffer.render_target->mode_info.mode_type if ((framebuffer.render_target->mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
/* No alpha available in index color modes, just use {
same value as in only RGB modes. */ if ((framebuffer.render_target->mode_info.mode_type
return grub_video_fb_map_rgb (red, green, blue); & 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 else if ((framebuffer.render_target->mode_info.mode_type
& GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) & 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 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
& 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 we have an out-of-bounds color, return transparent black. */
if (color > 255) if (color > 255)
{ {
@ -772,134 +790,153 @@ common_blitter (struct grub_video_fbblit_info *target,
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. */
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, grub_video_fbblit_replace_directN (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
{
grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source, grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
{
grub_video_fbblit_replace_BGR888_RGBX8888 (target, source, grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
{
grub_video_fbblit_replace_RGB888_RGBX8888 (target, source, grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
{
grub_video_fbblit_replace_index_RGBX8888 (target, source, grub_video_fbblit_replace_index_RGBX8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
{ switch (target->mode_info->blit_format)
if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
{ {
case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_BGRX8888_RGB888 (target, source, grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
{
grub_video_fbblit_replace_RGBX8888_RGB888 (target, source, grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
{
grub_video_fbblit_replace_BGR888_RGB888 (target, source, grub_video_fbblit_replace_BGR888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
{
grub_video_fbblit_replace_directN (target, source, grub_video_fbblit_replace_directN (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
{
grub_video_fbblit_replace_index_RGB888 (target, source, grub_video_fbblit_replace_index_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
{ switch (target->mode_info->blit_format)
if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
{ {
case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
grub_video_fbblit_replace_directN (target, source, grub_video_fbblit_replace_directN (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
{ switch (target->mode_info->blit_format)
if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
{ {
case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA:
grub_video_fbblit_replace_directN (target, source, grub_video_fbblit_replace_directN (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA:
{ switch (target->mode_info->bytes_per_pixel)
if (target->mode_info->bpp == 32)
{ {
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, grub_video_fbblit_replace_32bit_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
}
#ifdef GRUB_HAVE_UNALIGNED_ACCESS #ifdef GRUB_HAVE_UNALIGNED_ACCESS
else if (target->mode_info->bpp == 24) case 3:
{
grub_video_fbblit_replace_24bit_1bit (target, source, grub_video_fbblit_replace_24bit_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
}
#endif #endif
else if (target->mode_info->bpp == 16) case 2:
{
grub_video_fbblit_replace_16bit_1bit (target, source, grub_video_fbblit_replace_16bit_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case 1:
else if (target->mode_info->bpp == 8)
{
grub_video_fbblit_replace_8bit_1bit (target, source, grub_video_fbblit_replace_8bit_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} }
break;
default:
break;
} }
/* No optimized replace operator found, use default (slow) blitter. */ /* No optimized replace operator found, use default (slow) blitter. */
@ -909,123 +946,131 @@ common_blitter (struct grub_video_fbblit_info *target,
else else
{ {
/* Try to figure out more optimized blend operator. */ /* 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, grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
{
grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source, grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
{
grub_video_fbblit_blend_BGR888_RGBA8888 (target, source, grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
{
grub_video_fbblit_blend_RGB888_RGBA8888 (target, source, grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
{
grub_video_fbblit_blend_index_RGBA8888 (target, source, grub_video_fbblit_blend_index_RGBA8888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
{
/* Note: There is really no alpha information here, so blend is /* Note: There is really no alpha information here, so blend is
changed to replace. */ 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, grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
{
grub_video_fbblit_replace_RGBX8888_RGB888 (target, source, grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
{
grub_video_fbblit_replace_BGR888_RGB888 (target, source, grub_video_fbblit_replace_BGR888_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
{
grub_video_fbblit_replace_directN (target, source, grub_video_fbblit_replace_directN (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
} case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
{
grub_video_fbblit_replace_index_RGB888 (target, source, grub_video_fbblit_replace_index_RGB888 (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
default:
break;
} }
} break;
else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) case GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED:
{ switch (target->mode_info->blit_format)
if (target->mode_info->blit_format
== GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
|| target->mode_info->blit_format
== GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
{ {
case GRUB_VIDEO_BLIT_FORMAT_BGRA_8888:
case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
grub_video_fbblit_blend_XXXA8888_1bit (target, source, grub_video_fbblit_blend_XXXA8888_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
}
#ifdef GRUB_HAVE_UNALIGNED_ACCESS #ifdef GRUB_HAVE_UNALIGNED_ACCESS
else if (target->mode_info->blit_format case GRUB_VIDEO_BLIT_FORMAT_BGR_888:
== GRUB_VIDEO_BLIT_FORMAT_BGR_888 case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
|| target->mode_info->blit_format
== GRUB_VIDEO_BLIT_FORMAT_RGB_888)
{
grub_video_fbblit_blend_XXX888_1bit (target, source, grub_video_fbblit_blend_XXX888_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; return;
}
#endif #endif
else if (target->mode_info->blit_format case GRUB_VIDEO_BLIT_FORMAT_BGR_565:
== GRUB_VIDEO_BLIT_FORMAT_BGR_565 case GRUB_VIDEO_BLIT_FORMAT_RGB_565:
|| target->mode_info->blit_format
== GRUB_VIDEO_BLIT_FORMAT_RGB_565)
{
grub_video_fbblit_blend_XXX565_1bit (target, source, grub_video_fbblit_blend_XXX565_1bit (target, source,
x, y, width, height, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
return; 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. */ /* No optimized blend operation found, use default (slow) blitter. */
grub_video_fbblit_blend (target, source, x, y, width, height, grub_video_fbblit_blend (target, source, x, y, width, height,
offset_x, offset_y); offset_x, offset_y);
@ -1411,22 +1456,35 @@ 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.mode_type = GRUB_VIDEO_MODE_TYPE_RGB switch (mode_type)
| GRUB_VIDEO_MODE_TYPE_ALPHA; {
target->mode_info.bpp = 32; case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
target->mode_info.bytes_per_pixel = 4; | 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.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. */ /* Calculate size needed for the data. */
size = (width * target->mode_info.bytes_per_pixel) * height; size = (width * target->mode_info.bytes_per_pixel) * height;

View file

@ -101,6 +101,11 @@ enum grub_video_blit_format
/* When needed, decode color or just use value as is. */ /* When needed, decode color or just use value as is. */
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR, 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. */ /* Two color bitmap; bits packed: rows are not padded to byte boundary. */
GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED

View file

@ -118,6 +118,60 @@ EXPORT_FUNC(grub_video_fb_get_active_render_target) (struct grub_video_fbrender_
grub_err_t grub_err_t
EXPORT_FUNC(grub_video_fb_set_active_render_target) (struct grub_video_fbrender_target *target); 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); typedef grub_err_t (*grub_video_fb_set_page_t) (int page);
grub_err_t grub_err_t