grub-devel
[Top][All Lists]
Advanced

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

[patch] Added support to optimize fills and blits.


From: Vesa Jääskeläinen
Subject: [patch] Added support to optimize fills and blits.
Date: Thu, 30 Mar 2006 01:48:08 +0300
User-agent: Thunderbird 1.5 (Windows/20051201)

Hi,

Here is patch attached that adds support to video subsystem so fills and
blits could be optimized. It contains sample implementation for VBE
driver (it is not fastest possible, but gives some performance
improvement over previous one).

Thanks,
Vesa Jääskeläinen
Index: ChangeLog
===================================================================
RCS file: /sources/grub/grub2/ChangeLog,v
retrieving revision 1.226
diff -u -r1.226 ChangeLog
--- ChangeLog   14 Mar 2006 19:08:33 -0000      1.226
+++ ChangeLog   29 Mar 2006 22:37:17 -0000
@@ -1,3 +1,41 @@
+2006-03-30  Vesa Jaaskelainen  <address@hidden>
+
+       * DISTLIST: Added include/grub/i386/pc/vbeblit.h,
+       include/grub/i386/pc/vbefill.h, video/i386/pc/vbeblit.c,
+       video/i386/pc/vbefill.c.
+
+       * conf/i386-pc.rmk (vbe_mod_SOURCES): Added video/i386/pc/vbeblit.c,
+       video/i386/pc/vbefill.c.
+
+       * include/grub/video.h (grub_video_blit_format): New enum.
+       (grub_video_mode_info): Added new member blit_format.
+       (grub_video_get_blit_format): New function prototype.
+
+       * include/grub/i386/pc/vbe.h (grub_video_vbe_get_video_ptr): New
+       function prototype.
+       (grub_video_vbe_map_rgb): Likewise.
+       (grub_video_vbe_unmap_color): Likewise.
+
+       * include/grub/i386/pc/vbeblit.h: New file.
+
+       * include/grub/i386/pc/vbefill.h: New file.
+
+       * video/video.c (grub_video_get_blit_format): New function.
+       (grub_video_vbe_get_video_ptr): Re-declared as non-static.
+       (grub_video_vbe_map_rgb): Likewise.
+       (grub_video_vbe_unmap_color): Likewise.
+
+       * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Changed to use more
+       optimized fills.
+       (grub_video_vbe_blit_render_target): Changed to use more optimized
+       blits.
+       (grub_video_vbe_setup): Added detection for optimized settings.
+       (grub_video_vbe_create_render_target): Likewise.
+
+       * video/i386/pc/vbeblit.c: New file.
+
+       * video/i386/pc/vbefill.c: New file.
+
 2006-03-14  Vesa Jaaskelainen  <address@hidden>
 
        * DISTLIST: Added include/grub/video.h, term/gfxterm.c,
Index: DISTLIST
===================================================================
RCS file: /sources/grub/grub2/DISTLIST,v
retrieving revision 1.24
diff -u -r1.24 DISTLIST
--- DISTLIST    14 Mar 2006 19:08:33 -0000      1.24
+++ DISTLIST    29 Mar 2006 22:37:17 -0000
@@ -124,6 +124,8 @@
 include/grub/i386/pc/serial.h
 include/grub/i386/pc/time.h
 include/grub/i386/pc/vbe.h
+include/grub/i386/pc/vbeblit.h
+include/grub/i386/pc/vbefill.h
 include/grub/i386/pc/vga.h
 include/grub/i386/pc/util/biosdisk.h
 include/grub/ieee1275/ieee1275.h
@@ -235,3 +237,5 @@
 util/powerpc/ieee1275/misc.c
 video/video.c
 video/i386/pc/vbe.c
+video/i386/pc/vbeblit.c
+video/i386/pc/vbefill.c
Index: conf/i386-pc.rmk
===================================================================
RCS file: /sources/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.59
diff -u -r1.59 i386-pc.rmk
--- conf/i386-pc.rmk    14 Mar 2006 19:08:33 -0000      1.59
+++ conf/i386-pc.rmk    29 Mar 2006 22:37:23 -0000
@@ -174,7 +174,8 @@
 multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c
+vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
+                 video/i386/pc/vbefill.c
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
Index: include/grub/video.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/video.h,v
retrieving revision 1.1
diff -u -r1.1 video.h
--- include/grub/video.h        14 Mar 2006 19:08:33 -0000      1.1
+++ include/grub/video.h        29 Mar 2006 22:37:24 -0000
@@ -46,6 +46,21 @@
 #define GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER  ((struct 
grub_video_render_target *) 0)
 #define GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER   ((struct 
grub_video_render_target *) 1)
 
+/* Defined blitting formats.  */
+enum grub_video_blit_format
+  {
+    /* Follow exactly field & mask information.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGBA,
+    /* Make optimization assumption.  */
+    GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8,
+    /* Follow exactly field & mask information.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGB,
+    /* Make optimization assumption.  */
+    GRUB_VIDEO_BLIT_FORMAT_R8G8B8,
+    /* When needed, decode color or just use value as is.  */
+    GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
+  };
+
 struct grub_video_mode_info
 {
   /* Width of the screen.  */
@@ -70,6 +85,9 @@
   /* In index color mode, number of colors.  In RGB mode this is 256.  */
   unsigned int number_of_colors;
 
+  /* Optimization hint how binary data is coded.  */
+  enum grub_video_blit_format blit_format;
+
   /* How many bits are reserved for red color.  */
   unsigned int red_mask_size;
 
@@ -235,6 +253,8 @@
 
 grub_err_t EXPORT_FUNC(grub_video_get_info) (struct grub_video_mode_info 
*mode_info);
 
+enum grub_video_blit_format EXPORT_FUNC(grub_video_get_blit_format) (struct 
grub_video_mode_info *mode_info);
+
 grub_err_t EXPORT_FUNC(grub_video_set_palette) (unsigned int start,
                                                unsigned int count,
                                                struct grub_video_palette_data 
*palette_data);
Index: include/grub/i386/pc/vbe.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/i386/pc/vbe.h,v
retrieving revision 1.4
diff -u -r1.4 vbe.h
--- include/grub/i386/pc/vbe.h  14 Mar 2006 19:08:33 -0000      1.4
+++ include/grub/i386/pc/vbe.h  29 Mar 2006 22:37:24 -0000
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005  Free Software Foundation, Inc.
+ *  Copyright (C) 2005,2006  Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 #include <grub/symbol.h>
 #include <grub/types.h>
 #include <grub/err.h>
+#include <grub/video.h>
 
 /* Default video mode to be used.  */
 #define GRUB_VBE_DEFAULT_VIDEO_MODE     0x101
@@ -203,4 +204,18 @@
 grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode,
                                          struct grub_vbe_mode_info_block 
*mode_info);
 
+/* VBE module internal prototypes (should not be used from elsewhere).  */
+grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_render_target 
*source,
+                                             grub_uint32_t x,
+                                             grub_uint32_t y);
+
+grub_video_color_t grub_video_vbe_map_rgb (grub_uint8_t red, 
+                                           grub_uint8_t green,
+                                           grub_uint8_t blue);
+
+void grub_video_vbe_unmap_color (struct grub_video_render_target * source,
+                                 grub_video_color_t color, grub_uint8_t *red,
+                                 grub_uint8_t *green, grub_uint8_t *blue,
+                                 grub_uint8_t *alpha);
+
 #endif /* ! GRUB_VBE_MACHINE_HEADER */
Index: include/grub/i386/pc/vbeblit.h
===================================================================
RCS file: include/grub/i386/pc/vbeblit.h
diff -N include/grub/i386/pc/vbeblit.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ include/grub/i386/pc/vbeblit.h      29 Mar 2006 22:37:24 -0000
@@ -0,0 +1,66 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_VBEBLIT_MACHINE_HEADER
+#define GRUB_VBEBLIT_MACHINE_HEADER    1
+
+void
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target 
*dst,
+                                           struct grub_video_render_target 
*src,
+                                           int x, int y, int width, int height,
+                                           int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
+                                         struct grub_video_render_target *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
+                                        struct grub_video_render_target *src,
+                                        int x, int y, int width, int height,
+                                        int offset_x, int offset_y);
+
+
+void
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
+                                         struct grub_video_render_target *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_render_target *dst,
+                                       struct grub_video_render_target *src,
+                                       int x, int y, int width, int height,
+                                       int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
+                                      struct grub_video_render_target *src,
+                                      int x, int y, int width, int height,
+                                      int offset_x, int offset_y);
+
+void
+grub_video_i386_vbeblit_index_index (struct grub_video_render_target *dst,
+                                     struct grub_video_render_target *src,
+                                     int x, int y, int width, int height,
+                                     int offset_x, int offset_y);
+
+#endif /* ! GRUB_VBEBLIT_MACHINE_HEADER */
Index: include/grub/i386/pc/vbefill.h
===================================================================
RCS file: include/grub/i386/pc/vbefill.h
diff -N include/grub/i386/pc/vbefill.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ include/grub/i386/pc/vbefill.h      29 Mar 2006 22:37:24 -0000
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_VBEFILL_MACHINE_HEADER
+#define GRUB_VBEFILL_MACHINE_HEADER    1
+
+#include <grub/video.h>
+
+void
+grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
+                                  grub_video_color_t color,  int x, int y,
+                                  int width, int height);
+
+void
+grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
+                                grub_video_color_t color, int x, int y,
+                                int width, int height);
+
+void
+grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
+                               grub_video_color_t color, int x, int y,
+                               int width, int height);
+
+#endif /* ! GRUB_VBEFILL_MACHINE_HEADER */
Index: video/video.c
===================================================================
RCS file: /sources/grub/grub2/video/video.c,v
retrieving revision 1.1
diff -u -r1.1 video.c
--- video/video.c       14 Mar 2006 19:08:34 -0000      1.1
+++ video/video.c       29 Mar 2006 22:37:25 -0000
@@ -132,6 +132,53 @@
   return grub_video_adapter_active->get_info (mode_info);
 }
 
+enum grub_video_blit_format
+grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
+{
+  /* Check if we have any knwon 32 bit modes.  */
+  if (mode_info->bpp == 32)
+    {
+      if ((mode_info->red_mask_size == 8)
+          && (mode_info->red_field_pos == 0)
+          && (mode_info->green_mask_size == 8)
+          && (mode_info->green_field_pos == 8)
+          && (mode_info->blue_mask_size == 8)
+          && (mode_info->blue_field_pos == 16)
+          && (mode_info->reserved_mask_size == 8)
+          && (mode_info->reserved_field_pos == 24))
+        {
+          return GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8;
+        }
+    }
+
+  /* Check if we have any known 24 bit modes.  */
+  if (mode_info->bpp == 24)
+    {
+      if ((mode_info->red_mask_size == 8)
+          && (mode_info->red_field_pos == 0)
+          && (mode_info->green_mask_size == 8)
+          && (mode_info->green_field_pos == 8)
+          && (mode_info->blue_mask_size == 8)
+          && (mode_info->blue_field_pos == 16))
+        {
+          return GRUB_VIDEO_BLIT_FORMAT_R8G8B8;
+        }
+    }
+
+  /* If there are more than 8 bits per color, assume RGB(A) mode.  */
+  if (mode_info->bpp > 8)
+    {
+      if (mode_info->reserved_mask_size > 0)
+        {
+          return GRUB_VIDEO_BLIT_FORMAT_RGBA;
+        }
+      return GRUB_VIDEO_BLIT_FORMAT_RGB;
+    }
+
+  /* Assume as indexcolor mode.  */
+  return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR;
+}
+
 grub_err_t
 grub_video_set_palette (unsigned int start, unsigned int count,
                         struct grub_video_palette_data *palette_data)
Index: video/i386/pc/vbe.c
===================================================================
RCS file: /sources/grub/grub2/video/i386/pc/vbe.c,v
retrieving revision 1.5
diff -u -r1.5 vbe.c
--- video/i386/pc/vbe.c 14 Mar 2006 19:08:34 -0000      1.5
+++ video/i386/pc/vbe.c 29 Mar 2006 22:37:25 -0000
@@ -20,6 +20,8 @@
 #include <grub/err.h>
 #include <grub/machine/memory.h>
 #include <grub/machine/vbe.h>
+#include <grub/machine/vbeblit.h>
+#include <grub/machine/vbefill.h>
 #include <grub/types.h>
 #include <grub/dl.h>
 #include <grub/misc.h>
@@ -74,19 +76,9 @@
 static grub_uint16_t *mode_list;
 
 static grub_video_color_t
-grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t 
blue);
-
-static grub_video_color_t
 grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green,
                          grub_uint8_t blue, grub_uint8_t alpha);
 
-static void
-grub_video_vbe_unmap_color (struct grub_video_render_target * source,
-                            grub_video_color_t color,
-                            grub_uint8_t *red, grub_uint8_t *green,
-                            grub_uint8_t *blue, grub_uint8_t *alpha);
-
-
 static void *
 real2pm (grub_vbe_farptr_t ptr)
 {
@@ -314,7 +306,7 @@
   return GRUB_ERR_NONE;
 }
 
-static grub_uint8_t *
+grub_uint8_t *
 grub_video_vbe_get_video_ptr (struct grub_video_render_target *source,
                               grub_uint32_t x, grub_uint32_t y)
 {
@@ -648,6 +640,8 @@
       render_target->mode_info.blue_field_pos = 
active_mode_info.blue_field_position;
       render_target->mode_info.reserved_mask_size = 
active_mode_info.rsvd_mask_size;
       render_target->mode_info.reserved_field_pos = 
active_mode_info.rsvd_field_position;
+
+      render_target->mode_info.blit_format = grub_video_get_blit_format 
(&render_target->mode_info);
      
       /* Reset viewport to match new mode.  */
       render_target->viewport.x = 0;
@@ -793,7 +787,7 @@
   return 0;
 }
 
-static grub_video_color_t
+grub_video_color_t
 grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green,
                         grub_uint8_t blue)
 {
@@ -877,7 +871,7 @@
     }
 }
 
-static void
+void
 grub_video_vbe_unmap_color (struct grub_video_render_target * source,
                             grub_video_color_t color,
                             grub_uint8_t *red, grub_uint8_t *green,
@@ -976,7 +970,29 @@
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
-  /* Fill area.  */
+  /* Try to figure out more optimized version.  */
+  if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+    {
+      grub_video_i386_vbefill_R8G8B8A8 (render_target, color, x, y, 
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+
+  if (render_target->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+    {
+      grub_video_i386_vbefill_R8G8B8 (render_target, color, x, y,
+                                      width, height);
+      return GRUB_ERR_NONE;
+    }
+    
+  if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+    {
+      grub_video_i386_vbefill_index (render_target, color, x, y,
+                                     width, height);
+      return GRUB_ERR_NONE;
+    }
+  
+  /* Use backup method to fill area.  */
   for (j = 0; j < height; j++)
     for (i = 0; i < width; i++)
       grub_video_vbe_draw_pixel (x+i, y+j, color);
@@ -1180,7 +1196,73 @@
   x += render_target->viewport.x;
   y += render_target->viewport.y;
 
-  /* Render.  */
+  /* Try to figure out more optimized version.  */
+  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+    {
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+        {
+          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (render_target, source,
+                                                     x, y, width, height,
+                                                     offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+        {
+          grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (render_target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_R8G8B8A8 (render_target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+    }    
+
+  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+    {
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8)
+        {
+          grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (render_target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_R8G8B8)
+        {
+          grub_video_i386_vbeblit_R8G8B8_R8G8B8 (render_target, source,
+                                                 x, y, width, height,
+                                                 offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_R8G8B8 (render_target, source,
+                                                x, y, width, height,
+                                                offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+    }    
+
+  if (source->mode_info.blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+    {
+      if (render_target->mode_info.blit_format == 
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+        {
+          grub_video_i386_vbeblit_index_index (render_target, source,
+                                               x, y, width, height,
+                                               offset_x, offset_y);
+          return GRUB_ERR_NONE;
+        }
+    }    
+
+  /* Use backup method to render.  */
   for (j = 0; j < height; j++)
     {
       for (i = 0; i < width; i++)
@@ -1380,6 +1462,8 @@
   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: video/i386/pc/vbeblit.c
===================================================================
RCS file: video/i386/pc/vbeblit.c
diff -N video/i386/pc/vbeblit.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ video/i386/pc/vbeblit.c     29 Mar 2006 22:37:25 -0000
@@ -0,0 +1,369 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/vbe.h>
+#include <grub/machine/vbeblit.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+
+void
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8 (struct grub_video_render_target 
*dst,
+                                           struct grub_video_render_target 
*src,
+                                           int x, int y, int width, int height,
+                                           int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                              j + offset_y);
+
+      dstptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+          
+          a = color >> 24;
+          
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          if (a == 255)
+            {
+              *dstptr++ = color;
+              continue;
+            }
+            
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+          
+          color = *dstptr;
+          
+          dr = (color >> 0) & 0xFF;
+          dg = (color >> 8) & 0xFF;
+          db = (color >> 16) & 0xFF;
+          
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+          
+          color = (a << 24) | (db << 16) | (dg << 8) | dr;
+
+          *dstptr++ = color;          
+        }
+    }
+}
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8A8 (struct grub_video_render_target *dst,
+                                         struct grub_video_render_target *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                              j + offset_y);
+
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+          
+          a = color >> 24;
+          
+          if (a == 0)
+            {
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              *dstptr++ = sr;
+              *dstptr++ = sg;
+              *dstptr++ = sb;
+              
+              continue;
+            }
+            
+          dr = dstptr[0];
+          dg = dstptr[1];
+          db = dstptr[2];
+          
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+          
+          *dstptr++ = dr;
+          *dstptr++ = dg;
+          *dstptr++ = db;
+        }
+    }
+}
+
+void
+grub_video_i386_vbeblit_index_R8G8B8A8 (struct grub_video_render_target *dst,
+                                        struct grub_video_render_target *src,
+                                        int x, int y, int width, int height,
+                                        int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned char dr;
+  unsigned char dg;
+  unsigned char db;
+  unsigned char da;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                              j + offset_y);
+
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+          
+          a = color >> 24;
+          
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+          
+          if (a == 255)
+            {
+              color = grub_video_vbe_map_rgb(sr, sg, sb);
+              *dstptr++ = color & 0xFF;              
+              continue;
+            }
+            
+          grub_video_vbe_unmap_color (dst, *dstptr, &dr, &dg, &db, &da);
+          
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+          
+          color = grub_video_vbe_map_rgb(dr, dg, db);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+void
+grub_video_i386_vbeblit_R8G8B8A8_R8G8B8 (struct grub_video_render_target *dst,
+                                         struct grub_video_render_target *src,
+                                         int x, int y, int width, int height,
+                                         int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                             j + offset_y);
+
+      dstptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
+          
+          *dstptr++ = color;
+        }
+    }
+}
+
+
+void
+grub_video_i386_vbeblit_R8G8B8_R8G8B8 (struct grub_video_render_target *dst,
+                                       struct grub_video_render_target *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;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, 
+                                                             offset_x,
+                                                             j + offset_y);
+
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst,
+                                                             x, 
+                                                             y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          *dstptr ++ = *srcptr++;
+          *dstptr ++ = *srcptr++;
+          *dstptr ++ = *srcptr++;
+        }
+    }
+}
+
+void
+grub_video_i386_vbeblit_index_R8G8B8 (struct grub_video_render_target *dst,
+                                      struct grub_video_render_target *src,
+                                      int x, int y, int width, int height,
+                                      int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                             j + offset_y);
+
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+          
+          color = grub_video_vbe_map_rgb(sr, sg, sb);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+
+void
+grub_video_i386_vbeblit_index_index (struct grub_video_render_target *dst,
+                                     struct grub_video_render_target *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;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (src, offset_x,
+                                                             j + offset_y);
+                                                              
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+          *dstptr++ = *srcptr++;
+    }
+}
Index: video/i386/pc/vbefill.c
===================================================================
RCS file: video/i386/pc/vbefill.c
diff -N video/i386/pc/vbefill.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ video/i386/pc/vbefill.c     29 Mar 2006 22:37:25 -0000
@@ -0,0 +1,101 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/vbe.h>
+#include <grub/machine/vbefill.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+
+void
+grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
+                                  grub_video_color_t color, int x, int y,
+                                  int width, int height)
+{
+  int i;
+  int j;
+  grub_uint32_t *dstptr;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      dstptr = (grub_uint32_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        *dstptr++ = color;
+    }
+}
+
+void
+grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
+                                grub_video_color_t color, int x, int y,
+                                int width, int height)
+{
+  int i;
+  int j;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fillr = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fillg = (grub_uint8_t)((color >> 8) & 0xFF);
+  grub_uint8_t fillb = (grub_uint8_t)((color >> 16) & 0xFF);
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fillr;
+          *dstptr++ = fillg;
+          *dstptr++ = fillb;
+        }
+    }
+}
+
+
+void
+grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
+                               grub_video_color_t color, int x, int y,
+                               int width, int height)
+{
+  int i;
+  int j;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
+  
+  // we do not need to worry about data being out of bounds
+  // as we assume that everything has been checked before.
+  
+  for (j = 0; j < height; j++)
+    {
+      dstptr = (grub_uint8_t *)grub_video_vbe_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        *dstptr++ = fill;
+    }
+}

reply via email to

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