]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-03-31 Vesa Jaaskelainen <chaac@nic.fi>
authorchaac <chaac@localhost>
Fri, 31 Mar 2006 14:26:34 +0000 (14:26 +0000)
committerchaac <chaac@localhost>
Fri, 31 Mar 2006 14:26:34 +0000 (14:26 +0000)
        * 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.

12 files changed:
ChangeLog
DISTLIST
conf/i386-pc.mk
conf/i386-pc.rmk
include/grub/i386/pc/vbe.h
include/grub/i386/pc/vbeblit.h [new file with mode: 0644]
include/grub/i386/pc/vbefill.h [new file with mode: 0644]
include/grub/video.h
video/i386/pc/vbe.c
video/i386/pc/vbeblit.c [new file with mode: 0644]
video/i386/pc/vbefill.c [new file with mode: 0644]
video/video.c

index 8ac2d7186c498267aacb944dfb2cad9672954575..dbcbfc90ce825f0c19bd4027b0ff801040490fda 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2006-03-31  Vesa Jaaskelainen  <chaac@nic.fi>
+
+       * 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-30  Vesa Jaaskelainen  <chaac@nic.fi>
 
        * font/manager.c (grub_font_get_glyph): Removed font fixup from
index 1d3f3eaf9d30c19a508b04f2eaaf8c10b8c70679..0deb9be7387a508d7c2939fa3469c07f379f7e22 100644 (file)
--- a/DISTLIST
+++ b/DISTLIST
@@ -124,6 +124,8 @@ include/grub/i386/pc/multiboot.h
 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/grub-mkimage.c
 util/powerpc/ieee1275/misc.c
 video/video.c
 video/i386/pc/vbe.c
+video/i386/pc/vbeblit.c
+video/i386/pc/vbefill.c
index bac43b4b725f257f247a6a5119bbeb88cfe96ff7..8b711936c437db12cc13cf462e8998b856b43972 100644 (file)
@@ -2108,9 +2108,10 @@ multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
 multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c
-CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o def-vbe.lst und-vbe.lst
-MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d
+vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
+                 video/i386/pc/vbefill.c
+CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o def-vbe.lst und-vbe.lst
+MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d vbe_mod-video_i386_pc_vbeblit.d vbe_mod-video_i386_pc_vbefill.d
 DEFSYMFILES += def-vbe.lst
 UNDSYMFILES += und-vbe.lst
 
@@ -2119,7 +2120,7 @@ vbe.mod: pre-vbe.o mod-vbe.o
        $(LD) $(vbe_mod_LDFLAGS) $(LDFLAGS) -r -d -o $@ $^
        $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
 
-pre-vbe.o: vbe_mod-video_i386_pc_vbe.o
+pre-vbe.o: vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o
        -rm -f $@
        $(LD) $(vbe_mod_LDFLAGS) -r -d -o $@ $^
 
@@ -2155,6 +2156,44 @@ fs-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c genfslist.sh
        set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $<           | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
 
 
+vbe_mod-video_i386_pc_vbeblit.o: video/i386/pc/vbeblit.c
+       $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
+
+vbe_mod-video_i386_pc_vbeblit.d: video/i386/pc/vbeblit.c
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -M $<           | sed 's,vbeblit\.o[ :]*,vbe_mod-video_i386_pc_vbeblit.o $@ : ,g' > $@;         [ -s $@ ] || rm -f $@
+
+-include vbe_mod-video_i386_pc_vbeblit.d
+
+CLEANFILES += cmd-vbe_mod-video_i386_pc_vbeblit.lst fs-vbe_mod-video_i386_pc_vbeblit.lst
+COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbeblit.lst
+FSFILES += fs-vbe_mod-video_i386_pc_vbeblit.lst
+
+cmd-vbe_mod-video_i386_pc_vbeblit.lst: video/i386/pc/vbeblit.c gencmdlist.sh
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $<           | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1)
+
+fs-vbe_mod-video_i386_pc_vbeblit.lst: video/i386/pc/vbeblit.c genfslist.sh
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $<           | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
+
+
+vbe_mod-video_i386_pc_vbefill.o: video/i386/pc/vbefill.c
+       $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
+
+vbe_mod-video_i386_pc_vbefill.d: video/i386/pc/vbefill.c
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -M $<           | sed 's,vbefill\.o[ :]*,vbe_mod-video_i386_pc_vbefill.o $@ : ,g' > $@;         [ -s $@ ] || rm -f $@
+
+-include vbe_mod-video_i386_pc_vbefill.d
+
+CLEANFILES += cmd-vbe_mod-video_i386_pc_vbefill.lst fs-vbe_mod-video_i386_pc_vbefill.lst
+COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbefill.lst
+FSFILES += fs-vbe_mod-video_i386_pc_vbefill.lst
+
+cmd-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c gencmdlist.sh
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $<           | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1)
+
+fs-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c genfslist.sh
+       set -e;           $(CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(CPPFLAGS) $(CFLAGS) $(vbe_mod_CFLAGS) -E $<           | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
+
+
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
index f75ab7f3e0161df1bb73ffddc1992eadc5eccd98..d878b136c2d1ebfa36c3bcc0bf7b31e92d626c15 100644 (file)
@@ -174,7 +174,8 @@ multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
 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 b03bf97c601253731d946c2fcf6b04a1c5ec8ba5..e33cfac3efc2aeb02ee1fc35df26353c3416f458 100644 (file)
@@ -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 (grub_uint32_t *mode);
 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 */
diff --git a/include/grub/i386/pc/vbeblit.h b/include/grub/i386/pc/vbeblit.h
new file mode 100644 (file)
index 0000000..890b577
--- /dev/null
@@ -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 */
diff --git a/include/grub/i386/pc/vbefill.h b/include/grub/i386/pc/vbefill.h
new file mode 100644 (file)
index 0000000..14f7b53
--- /dev/null
@@ -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 934e7b939c4342cd61eef47cf4bb69bd6a36236d..7a894e3b9af54b5cd9cffd4beecc27d9971b1bb1 100644 (file)
@@ -46,6 +46,21 @@ struct grub_video_render_target;
 #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 @@ struct grub_video_mode_info
   /* 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_restore) (void);
 
 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 c7e701669d997523f141cc234e4727d34b51f52c..f92c130d75e15ae6c952d51047c2ad191d4447d7 100644 (file)
@@ -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>
@@ -73,20 +75,10 @@ static grub_uint32_t initial_mode;
 static grub_uint32_t mode_in_use = 0x55aa;
 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 @@ grub_vbe_get_video_mode_info (grub_uint32_t mode,
   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 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
       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 @@ grub_video_vbe_map_color (grub_uint32_t color_name)
   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 @@ grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green,
     }
 }
 
-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 @@ grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
   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 @@ grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
   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 @@ grub_video_vbe_create_render_target (struct grub_video_render_target **result,
   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;
   
diff --git a/video/i386/pc/vbeblit.c b/video/i386/pc/vbeblit.c
new file mode 100644 (file)
index 0000000..e14233a
--- /dev/null
@@ -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++;
+    }
+}
diff --git a/video/i386/pc/vbefill.c b/video/i386/pc/vbefill.c
new file mode 100644 (file)
index 0000000..9c8cf19
--- /dev/null
@@ -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;
+    }
+}
index affe72868e920110ba34bd29e9cd130f583e0c1d..3401a55086fd02581dd59988de22998de4f844d9 100644 (file)
@@ -132,6 +132,53 @@ grub_video_get_info (struct grub_video_mode_info *mode_info)
   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)