commit-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[2542] 2009-08-28 Vladimir Serbinenko <address@hidden>


From: Vladimir Serbinenko
Subject: [2542] 2009-08-28 Vladimir Serbinenko <address@hidden>
Date: Fri, 28 Aug 2009 13:54:20 +0000

Revision: 2542
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2542
Author:   phcoder
Date:     2009-08-28 13:54:20 +0000 (Fri, 28 Aug 2009)
Log Message:
-----------
2009-08-28  Vladimir Serbinenko  <address@hidden>

        1-bit optimised blitters.

        * include/grub/fbblit.h (grub_video_fbblit_replace_32bit_1bit): New
        prototype.
        (grub_video_fbblit_replace_24bit_1bit): Likewise.
        (grub_video_fbblit_replace_16bit_1bit): Likewise.
        (grub_video_fbblit_replace_8bit_1bit): Likewise.
        (grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
        (grub_video_fbblit_blend_XXX888_1bit): Likewise.
        (grub_video_fbblit_blend_XXX565_1bit): Likewise.
        * video/fb/fbblit.c (grub_video_fbblit_replace_32bit_1bit): New
        function.
        (grub_video_fbblit_replace_24bit_1bit): Likewise.
        (grub_video_fbblit_replace_16bit_1bit): Likewise.
        (grub_video_fbblit_replace_8bit_1bit): Likewise.
        (grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
        (grub_video_fbblit_blend_XXX888_1bit): Likewise.
        (grub_video_fbblit_blend_XXX565_1bit): Likewise.
        * video/fb/video_fb.c (common_blitter): Use 1-bit optimised blitters
        when possible.
        * video/video.c (grub_video_get_blit_format): Return
        GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED if bpp = 1.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/include/grub/fbblit.h
    trunk/grub2/video/fb/fbblit.c
    trunk/grub2/video/fb/video_fb.c
    trunk/grub2/video/video.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2009-08-28 13:25:10 UTC (rev 2541)
+++ trunk/grub2/ChangeLog       2009-08-28 13:54:20 UTC (rev 2542)
@@ -1,3 +1,28 @@
+2009-08-28  Vladimir Serbinenko  <address@hidden>
+
+       1-bit optimised blitters.
+
+       * include/grub/fbblit.h (grub_video_fbblit_replace_32bit_1bit): New
+       prototype.
+       (grub_video_fbblit_replace_24bit_1bit): Likewise.
+       (grub_video_fbblit_replace_16bit_1bit): Likewise.
+       (grub_video_fbblit_replace_8bit_1bit): Likewise.
+       (grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
+       (grub_video_fbblit_blend_XXX888_1bit): Likewise.
+       (grub_video_fbblit_blend_XXX565_1bit): Likewise.
+       * video/fb/fbblit.c (grub_video_fbblit_replace_32bit_1bit): New
+       function.
+       (grub_video_fbblit_replace_24bit_1bit): Likewise.
+       (grub_video_fbblit_replace_16bit_1bit): Likewise.
+       (grub_video_fbblit_replace_8bit_1bit): Likewise.
+       (grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
+       (grub_video_fbblit_blend_XXX888_1bit): Likewise.
+       (grub_video_fbblit_blend_XXX565_1bit): Likewise.
+       * video/fb/video_fb.c (common_blitter): Use 1-bit optimised blitters
+       when possible.
+       * video/video.c (grub_video_get_blit_format): Return
+       GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED if bpp = 1.
+
 2009-08-28  Colin Watson  <address@hidden>
 
        * normal/cmdline.c (grub_cmdline_get): Supply a format string as

Modified: trunk/grub2/include/grub/fbblit.h
===================================================================
--- trunk/grub2/include/grub/fbblit.h   2009-08-28 13:25:10 UTC (rev 2541)
+++ trunk/grub2/include/grub/fbblit.h   2009-08-28 13:54:20 UTC (rev 2542)
@@ -131,4 +131,52 @@
                                        int width, int height,
                                        int offset_x, int offset_y);
 
+void
+grub_video_fbblit_replace_32bit_1bit (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
+grub_video_fbblit_replace_24bit_1bit (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
+grub_video_fbblit_replace_16bit_1bit (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
+grub_video_fbblit_replace_8bit_1bit (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
+grub_video_fbblit_blend_XXXA8888_1bit (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
+grub_video_fbblit_blend_XXX888_1bit (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
+grub_video_fbblit_blend_XXX565_1bit (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);
 #endif /* ! GRUB_FBBLIT_HEADER */

Modified: trunk/grub2/video/fb/fbblit.c
===================================================================
--- trunk/grub2/video/fb/fbblit.c       2009-08-28 13:25:10 UTC (rev 2541)
+++ trunk/grub2/video/fb/fbblit.c       2009-08-28 13:54:20 UTC (rev 2542)
@@ -90,6 +90,302 @@
     }
 }
 
+/* Optimized replacing blitter for 1-bit to 32bit.  */
+void
+grub_video_fbblit_replace_32bit_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint32_t *) dstptr = fgcolor;
+         else
+           *(grub_uint32_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+
+/* Optimized replacing blitter for 1-bit to 24-bit.  */
+void
+grub_video_fbblit_replace_24bit_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width - 1; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint32_t *) dstptr = fgcolor;
+         else
+           *(grub_uint32_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 3;
+        }
+
+      if (*srcptr & srcmask)
+       {
+         *dstptr++ = fgcolor & 0xff;
+         *dstptr++ = (fgcolor & 0xff00) >> 8;
+         *dstptr++ = (fgcolor & 0xff0000) >> 16;
+       }
+      else
+       {
+         *dstptr++ = bgcolor & 0xff;
+         *dstptr++ = (bgcolor & 0xff00) >> 8;
+         *dstptr++ = (bgcolor & 0xff0000) >> 16;
+       }
+      srcmask >>= 1;
+      if (!srcmask)
+       {
+         srcptr++;
+         srcmask = 0x80;
+       }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 16-bit.  */
+void
+grub_video_fbblit_replace_16bit_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint16_t *) dstptr = fgcolor;
+         else
+           *(grub_uint16_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 8-bit.  */
+void
+grub_video_fbblit_replace_8bit_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint8_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint8_t *) dstptr = fgcolor;
+         else
+           *(grub_uint8_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr++;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
 /* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
 void
 grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info 
*dst,
@@ -826,3 +1122,294 @@
         }
     }
 }
+
+/* Optimized blending blitter for 1-bit to XXXA8888.  */
+void
+grub_video_fbblit_blend_XXXA8888_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+
+         if (*srcptr & srcmask)
+           color = fgcolor;
+         else
+           color = bgcolor;
+         a = (color >> 24) & 0xff;
+
+         if (a == 255)
+           *(grub_uint32_t *) dstptr = color;
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0xFF;
+             grub_uint8_t s2 = (color >> 8) & 0xFF;
+             grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+             d1 = (d1 * (255 - a) + s1 * a) / 255;
+             d2 = (d2 * (255 - a) + s2 * a) / 255;
+             d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+             *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
+               | d1;
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX888_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+         if (*srcptr & srcmask)
+           {
+             color = fgcolor;
+             a = src->mode_info->fg_alpha;
+           }
+         else
+           {
+             color = bgcolor;
+             a = src->mode_info->bg_alpha;
+           }
+
+         if (a == 255)
+           {
+             ((grub_uint8_t *) dstptr)[0] = color & 0xff;
+             ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
+             ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
+           }
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0xFF;
+             grub_uint8_t s2 = (color >> 8) & 0xFF;
+             grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+             ((grub_uint8_t *) dstptr)[0] = (d1 * (255 - a) + s1 * a) / 255;
+             ((grub_uint8_t *) dstptr)[1] = (d2 * (255 - a) + s2 * a) / 255;
+             ((grub_uint8_t *) dstptr)[2] = (d3 * (255 - a) + s3 * a) / 255;
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 3;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX565_1bit (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;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* 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;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+         if (*srcptr & srcmask)
+           {
+             color = fgcolor;
+             a = src->mode_info->fg_alpha;
+           }
+         else
+           {
+             color = bgcolor;
+             a = src->mode_info->bg_alpha;
+           }
+
+         if (a == 255)
+           *(grub_uint16_t *) dstptr = color;
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0x1F;
+             grub_uint8_t s2 = (color >> 5) & 0x3F;
+             grub_uint8_t s3 = (color >> 11) & 0x1F;
+
+             grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F;
+             grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F;
+             grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F;
+
+             d1 = (d1 * (255 - a) + s1 * a) / 255;
+             d2 = (d2 * (255 - a) + s2 * a) / 255;
+             d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+             *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
+               | ((d3 & 0x1f) << 11);
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}

Modified: trunk/grub2/video/fb/video_fb.c
===================================================================
--- trunk/grub2/video/fb/video_fb.c     2009-08-28 13:25:10 UTC (rev 2541)
+++ trunk/grub2/video/fb/video_fb.c     2009-08-28 13:54:20 UTC (rev 2542)
@@ -587,6 +587,37 @@
              return;
            }
        }
+      else if (source->mode_info->blit_format == 
GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+       {
+         if (target->mode_info->bpp == 32)
+           {
+             grub_video_fbblit_replace_32bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 24)
+           {
+             grub_video_fbblit_replace_24bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 16)
+           {
+             grub_video_fbblit_replace_16bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 8)
+           {
+             grub_video_fbblit_replace_8bit_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
+       }
 
       /* No optimized replace operator found, use default (slow) blitter.  */
       grub_video_fbblit_replace (target, source, x, y, width, height,
@@ -674,7 +705,42 @@
              return;
            }
        }
+      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)
+           {
+             grub_video_fbblit_blend_XXXA8888_1bit (target, source,
+                                                    x, y, width, height,
+                                                    offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_BGR_888
+                  || target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_blend_XXX888_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_BGR_565
+                  || target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+           {
+             grub_video_fbblit_blend_XXX565_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
 
+       }
+
+
       /* No optimized blend operation found, use default (slow) blitter.  */
       grub_video_fbblit_blend (target, source, x, y, width, height,
                                     offset_x, offset_y);

Modified: trunk/grub2/video/video.c
===================================================================
--- trunk/grub2/video/video.c   2009-08-28 13:25:10 UTC (rev 2541)
+++ trunk/grub2/video/video.c   2009-08-28 13:54:20 UTC (rev 2542)
@@ -181,6 +181,8 @@
          return GRUB_VIDEO_BLIT_FORMAT_RGB_565;
        }
     }
+  else if (mode_info->bpp == 1)
+    return GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
 
   /* Backup route.  Unknown format.  */
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]