]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Speed-up gfxterm by saving intermediate results in index+alpha
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 4 May 2013 11:58:30 +0000 (13:58 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 4 May 2013 11:58:30 +0000 (13:58 +0200)
format.

ChangeLog
grub-core/term/gfxterm.c
grub-core/video/fb/fbblit.c
grub-core/video/fb/video_fb.c
include/grub/video.h
include/grub/video_fb.h

index d5f9bb90c980912d30cf33455d4cf354b1cb4e27..74cb13d25bb454a4022074f015fd1fc306d1e32b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * grub-core/tests/lib/functional_test.c: Don't stop on first failed
index 1e33a34b36e4f7eaa78c206e086d8fae7b91a098..54636d771381eb697962938a989f9fd1684a8eb7 100644 (file)
@@ -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;
index 541a0ceaf1e686ffb32bc826b57c2dcd06a44ecc..c206ac872833e4aabdd9398ec3728544a373ae01 100644 (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.  */
 void
 grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
index 836842e15cb5207afd14e9264ea44416c36bcb9d..22a0128a187c2c0d76267df770fd8642670dc3f5 100644 (file)
@@ -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;
index 36e863be3e5abb4ab5855d179d2bfccd1586120d..b2d1458126abe74775d05e49b9d149bf171ccda8 100644 (file)
@@ -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
index ffe16c3ac7769e039ef27d8728744d0c216bea66..88bc75d9de3d6417c7e5db45785fc2c3f95e7fcb 100644 (file)
@@ -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