Blame SOURCES/0422-Speed-up-gfxterm-by-saving-intermediate-results-in-i.patch

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