Skip to contentSkip to conversation

Added bitmap support to Video API

PATCH In review Vesa Jääskeläinen 2 participants 4 messages Jul 29, 2006 – Aug 4, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Added bitmap support to Video API

Hi,

I have just made a patch to add bitmap support to Video API. It contains example bitmap loader for .tga files. At this point there is no real example how to use them, but I have tried to update wiki to reflect changes (except that bitmap handling is not there yet).

New functionality was introduced to Video API to specify blitting operator. Now there is only two operators specified, replace and blend. Replace just uses source pixel data and blits it destination and blend uses source pixel alpha value to blend source and destination pixels.

Reason why I wanted to give patch before better example how to use is ready is that I want it to get to next grub release and I don't want to block other development. And I didn't include that background bitmap loading to gfxterm in this patch as I would rather like some development to improve menu system than to stall it :).

Patch is attached to this message, any comments are welcome.

Thanks,
Vesa Jääskeläinen

Index: ChangeLog
===================================================================
RCS file: /sources/grub/grub2/ChangeLog,v
retrieving revision 1.288

ChangeLog +85 -0
diff -u -r1.288 ChangeLog
@@ -1,5 +1,90 @@
 2006-07-29  Vesa Jaaskelainen  <[email protected]>
 
+	* include/grub/bitmap.h: New file.
+
+	* include/grub/i386/pc/vbeutil.h: Likewise.
+
+	* video/bitmap.c: Likewise.
+
+	* video/readers/tga.c: Likewise.
+
+	* video/i386/pc/vbeutil.c: Likewise.
+
+	* commands/videotest.c: Code cleanup and updated to reflect to new
+	video API.
+
+	* term/gfxterm.c: Likewise.
+
+	* video/video.c: Likewise.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod.
+	(vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c.
+	(bitmap_mod_SOURCES): New entry.
+	(bitmap_mod_CFLAGS): Likewise.
+	(bitmap_mod_LDFLAGS): Likewise.
+	(tga_mod_SOURCES): Likewise.
+	(tga_mod_CFLAGS): Likewise.
+	(tga_mod_LDFLAGS): Likewise.
+
+	* include/grub/video.h (grub_video_blit_operators): New enum type.
+	(grub_video_render_target): Changed as forward declaration and moved
+	actual definition to be video driver specific.
+	(grub_video_adapter.blit_bitmap): Added blitting operator.
+	(grub_video_adapter.blit_render_target): Likewise.
+	(grub_video_blit_bitmap): Likewise.
+	(grub_video_blit_render_target): Likewise.
+
+	* include/grub/i386/pc/vbe.h (grub_video_render_target): Added
+	driver specific render target definition.
+	(grub_video_vbe_map_rgba): Added driver internal helper.
+	(grub_video_vbe_unmap_color): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_vbe_get_video_ptr): Likewise.
+
+	* include/grub/i386/pc/vbeblit.h
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_index): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_blend): Added generic blitter for blend
+	operator.
+	(grub_video_i386_vbeblit_replace): Added generic blitter for replace
+	operator.
+
+	* video/i386/pc/vbeblit.c: Updated to reflect changes on
+	include/grub/i386/pc/vbeblit.h.
+
+	* include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8):
+	Updated to use grub_video_i386_vbeblit_info.
+	(grub_video_i386_vbefill_R8G8B8): Likewise.
+	(grub_video_i386_vbefill_index): Likewise.
+	(grub_video_i386_vbefill): Added generic filler.
+
+	* video/i386/pc/vbefill.c: Updated to reflect changes on
+	include/grub/i386/pc/vbefill.h.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_vbe_unmap_color): Likewise.
+	(grub_video_vbe_blit_glyph): Likewise.
+	(grub_video_vbe_scroll): Likewise.
+	(grub_video_vbe_draw_pixel): Removed function.
+	(grub_video_vbe_get_pixel): Likewise.
+	(grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and
+	updated code to use it.
+	(common_blitter): Added common blitter for render target and bitmap.
+	(grub_video_vbe_blit_bitmap): Updated to use common_blitter.
+	(grub_video_vbe_blit_render_target): Likewise.
+
+2006-07-29  Vesa Jaaskelainen  <[email protected]>
+
 	* include/grub/video.h: Code cleanup.
 
 	* include/grub/i386/pc/vbe.h: Likewise.

Index: commands/videotest.c
===================================================================
RCS file: /sources/grub/grub2/commands/videotest.c,v retrieving revision 1.1

videotest.c +19 -18
diff -u -r1.1 videotest.c
@@ -36,7 +36,7 @@
   if (grub_video_setup (1024, 768,
                         GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE)
     return grub_errno;
-  
+
   grub_getkey ();
 
   grub_video_color_t color;
@@ -48,21 +48,21 @@
   struct grub_font_glyph glyph;
   struct grub_video_render_target *text_layer;
   grub_video_color_t palette[16];
-  
+
   grub_video_get_viewport (&x, &y, &width, &height);
 
   grub_video_create_render_target (&text_layer, width, height,
                                    GRUB_VIDEO_MODE_TYPE_RGB
                                    | GRUB_VIDEO_MODE_TYPE_ALPHA);
 
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);                                   
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
 
   color = grub_video_map_rgb (0, 0, 0);
   grub_video_fill_rect (color, 0, 0, width, height);
-  
+
   color = grub_video_map_rgb (255, 0, 0);
   grub_video_fill_rect (color, 0, 0, 100, 100);
-  
+
   color = grub_video_map_rgb (0, 255, 255);
   grub_video_fill_rect (color, 100, 100, 100, 100);
 
@@ -73,18 +73,18 @@
                            width - 150 * 2, height - 150 * 2);
   color = grub_video_map_rgb (77, 33, 77);
   grub_video_fill_rect (color, 0, 0, width, height);
-  
+
   grub_video_set_active_render_target (text_layer);
-  
+
   color = grub_video_map_rgb (255, 255, 255);
-  
-  grub_font_get_glyph ('A', &glyph);  
+
+  grub_font_get_glyph ('A', &glyph);
   grub_video_blit_glyph (&glyph, color, 16, 16);
-  grub_font_get_glyph ('B', &glyph);  
+  grub_font_get_glyph ('B', &glyph);
   grub_video_blit_glyph (&glyph, color, 16 * 2, 16);
 
-  grub_font_get_glyph ('*', &glyph);  
-  
+  grub_font_get_glyph ('*', &glyph);
+
   for (i = 0; i < 16; i++)
     {
       color = grub_video_map_color (i);
@@ -98,18 +98,19 @@
     {
       color = grub_video_map_rgb (i, 33, 77);
       grub_video_fill_rect (color, 0, 0, width, height);
-      grub_video_blit_render_target (text_layer, 0, 0, 0, 0, width, height);
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
+                                     0, 0, width, height);
     }
-  
+
   grub_getkey ();
-  
+
   grub_video_delete_render_target (text_layer);
-  
+
   grub_video_restore ();
-  
+
   for (i = 0; i < 16; i++)
     grub_printf("color %d: %08x\n", i, palette[i]);
-  
+
   grub_errno = GRUB_ERR_NONE;
   return grub_errno;
 }

Index: conf/i386-pc.rmk
===================================================================
RCS file: /sources/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.66

i386-pc.rmk +12 -2
diff -u -r1.66 i386-pc.rmk
@@ -112,7 +112,7 @@
 pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
 	_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod	\
 	vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
-	videotest.mod play.mod
+	videotest.mod play.mod bitmap.mod tga.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -171,7 +171,7 @@
 
 # For vbe.mod.
 vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
-		  video/i386/pc/vbefill.c
+		  video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
@@ -205,4 +205,14 @@
 videotest_mod_CFLAGS = $(COMMON_CFLAGS)
 videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/common.mk

Index: include/grub/bitmap.h
===================================================================
RCS file: include/grub/bitmap.h

grub/bitmap.h new file +71 -0

71 lines not on this page · raw message

Index: include/grub/video.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/video.h,v retrieving revision 1.4

grub/video.h +21 -26

95 lines not on this page · raw message

Index: include/grub/i386/pc/vbe.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/i386/pc/vbe.h,v retrieving revision 1.6

grub/i386/pc/vbe.h +32 -2
diff -u -r1.6 vbe.h
@@ -205,13 +205,43 @@
                                          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,
+struct grub_video_i386_vbeblit_info;
+
+struct grub_video_render_target
+{
+  /* Copy of the screen's mode info structure, except that width, height and
+     mode_type has been re-adjusted to requested render target settings.  */
+  struct grub_video_mode_info mode_info;
+
+  struct
+  {
+    unsigned int x;
+    unsigned int y;
+    unsigned int width;
+    unsigned int height;
+  } viewport;
+
+  /* Indicates wether the data has been allocated by us and must be freed
+     when render target is destroyed.  */
+  int is_allocated;
+
+  /* Pointer to data.  Can either be in video card memory or in local host's
+     memory.  */
+  void *data;
+};
+
+grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *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 grub_video_vbe_map_rgba (grub_uint8_t red,
+                                            grub_uint8_t green,
+                                            grub_uint8_t blue,
+                                            grub_uint8_t alpha);
+
+void grub_video_vbe_unmap_color (struct grub_video_i386_vbeblit_info *source,
                                  grub_video_color_t color, grub_uint8_t *red,
                                  grub_uint8_t *green, grub_uint8_t *blue,
                                  grub_uint8_t *alpha);

Index: include/grub/i386/pc/vbeblit.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/i386/pc/vbeblit.h,v retrieving revision 1.1

grub/i386/pc/vbeblit.h +48 -14

95 lines not on this page · raw message

Index: include/grub/i386/pc/vbefill.h
===================================================================
RCS file: /sources/grub/grub2/include/grub/i386/pc/vbefill.h,v retrieving revision 1.1

grub/i386/pc/vbefill.h +12 -4
diff -u -r1.1 vbefill.h
@@ -20,21 +20,29 @@
 #ifndef GRUB_VBEFILL_MACHINE_HEADER
 #define GRUB_VBEFILL_MACHINE_HEADER	1
 
-#include <grub/video.h>
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_i386_vbeblit_info;
 
 void
-grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8A8 (struct grub_video_i386_vbeblit_info *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_i386_vbefill_R8G8B8 (struct grub_video_i386_vbeblit_info *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_i386_vbefill_index (struct grub_video_i386_vbeblit_info *dst,
                                grub_video_color_t color, int x, int y,
                                int width, int height);
 
+void
+grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst,
+                         grub_video_color_t color, int x, int y,
+                         int width, int height);
+
 #endif /* ! GRUB_VBEFILL_MACHINE_HEADER */

Index: include/grub/i386/pc/vbeutil.h
===================================================================
RCS file: include/grub/i386/pc/vbeutil.h

grub/i386/pc/vbeutil.h new file +44 -0

44 lines not on this page · raw message

Index: term/gfxterm.c
===================================================================
RCS file: /sources/grub/grub2/term/gfxterm.c,v
retrieving revision 1.2

gfxterm.c +86 -86

396 lines not on this page · raw message

Index: video/bitmap.c
===================================================================
RCS file: video/bitmap.c

bitmap.c new file +257 -0

257 lines not on this page · raw message

Index: video/video.c
===================================================================
RCS file: /sources/grub/grub2/video/video.c,v
retrieving revision 1.3

video.c +7 -5
diff -u -r1.3 video.c
@@ -82,7 +82,7 @@
   /* Loop thru all possible video adapter trying to find requested mode.  */
   for (p = grub_video_adapter_list; p; p = p->next)
     {
-      /* Try to initialize adapter, if can't skip to next.  */
+      /* Try to initialize adapter, if it fails, skip to next adapter.  */
       p->init ();
       if (grub_errno != GRUB_ERR_NONE)
         {
@@ -142,7 +142,7 @@
 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.  */
+  /* Check if we have any known 32 bit modes.  */
   if (mode_info->bpp == 32)
     {
       if ((mode_info->red_mask_size == 8)
@@ -286,13 +286,14 @@
 /* Blit bitmap to screen.  */
 grub_err_t
 grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                        enum grub_video_blit_operators oper,
                         int x, int y, int offset_x, int offset_y,
                         unsigned int width, unsigned int height)
 {
   if (! grub_video_adapter_active)
     return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
 
-  return grub_video_adapter_active->blit_bitmap (bitmap, x, y,
+  return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y,
                                                  offset_x, offset_y,
                                                  width, height);
 }
@@ -300,14 +301,15 @@
 /* Blit render target to active render target.  */
 grub_err_t
 grub_video_blit_render_target (struct grub_video_render_target *target,
+                               enum grub_video_blit_operators oper,
                                int x, int y, int offset_x, int offset_y,
                                unsigned int width, unsigned int height)
 {
   if (! grub_video_adapter_active)
     return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
 
-  return grub_video_adapter_active->blit_render_target (target, x, y,
-                                                        offset_x, offset_y, 
+  return grub_video_adapter_active->blit_render_target (target, oper, x, y,
+                                                        offset_x, offset_y,
                                                         width, height);
 }
 

Index: video/i386/pc/vbe.c
===================================================================
RCS file: /sources/grub/grub2/video/i386/pc/vbe.c,v retrieving revision 1.8

i386/pc/vbe.c +279 -287

826 lines not on this page · raw message

Index: video/i386/pc/vbeblit.c
===================================================================
RCS file: /sources/grub/grub2/video/i386/pc/vbeblit.c,v retrieving revision 1.2

i386/pc/vbeblit.c +243 -59

405 lines not on this page · raw message

Index: video/i386/pc/vbefill.c
===================================================================
RCS file: /sources/grub/grub2/video/i386/pc/vbefill.c,v retrieving revision 1.2

i386/pc/vbefill.c +31 -9
diff -u -r1.2 vbefill.c
@@ -17,19 +17,25 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <grub/err.h>
-#include <grub/machine/memory.h>
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
 #include <grub/machine/vbe.h>
 #include <grub/machine/vbefill.h>
+#include <grub/machine/vbeutil.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_i386_vbefill_R8G8B8A8 (struct grub_video_i386_vbeblit_info *dst,
                                   grub_video_color_t color, int x, int y,
                                   int width, int height)
 {
@@ -50,7 +56,7 @@
 }
 
 void
-grub_video_i386_vbefill_R8G8B8 (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_R8G8B8 (struct grub_video_i386_vbeblit_info *dst,
                                 grub_video_color_t color, int x, int y,
                                 int width, int height)
 {
@@ -78,7 +84,7 @@
 }
 
 void
-grub_video_i386_vbefill_index (struct grub_video_render_target *dst,
+grub_video_i386_vbefill_index (struct grub_video_i386_vbeblit_info *dst,
                                grub_video_color_t color, int x, int y,
                                int width, int height)
 {
@@ -98,3 +104,19 @@
         *dstptr++ = fill;
     }
 }
+
+void
+grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst,
+                         grub_video_color_t color, int x, int y,
+                         int width, int height)
+{
+  int i;
+  int j;
+
+  /* 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++)
+    for (i = 0; i < width; i++)
+      set_pixel (dst, x+i, y+j, color);
+}

Index: video/i386/pc/vbeutil.c
===================================================================
RCS file: video/i386/pc/vbeutil.c

i386/pc/vbeutil.c new file +150 -0

150 lines not on this page · raw message

Index: video/readers/tga.c
===================================================================
RCS file: video/readers/tga.c

readers/tga.c new file +496 -0

265 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#1 lore raw
Quoted 9 lines · Vesa Jääskeläinen

I have just made a patch to add bitmap support to Video API. It contains example bitmap loader for .tga files. At this point there is no real example how to use them, but I have tried to update wiki to reflect changes (except that bitmap handling is not there yet).

New functionality was introduced to Video API to specify blitting operator. Now there is only two operators specified, replace and blend. Replace just uses source pixel data and blits it destination and blend uses source pixel alpha value to blend source and destination pixels.

Fantastic. So have you implemented everything you planned? :)

Quoted 5 lines

Reason why I wanted to give patch before better example how to use is ready is that I want it to get to next grub release and I don't want to block other development. And I didn't include that background bitmap loading to gfxterm in this patch as I would rather like some development to improve menu system than to stall it :).

I don't think you have to care about releases... They are meant only to demonstrate that development is happening. In addition, I intend to delay the next by around one month, as we were quite inactive recently.

Quoted 1 line

Patch is attached to this message, any comments are welcome.

This looks very good to me. Please go ahead.

Thanks,
Okuji

#2 lore raw
Quoted 6 lines · Yoshinori K. Okuji
Quoted 5 lines · Vesa Jääskeläinen

I have just made a patch to add bitmap support to Video API. It contains example bitmap loader for .tga files. At this point there is no real example how to use them, but I have tried to update wiki to reflect changes (except that bitmap handling is not there yet).

Quoted 6 lines
Quoted 4 lines

New functionality was introduced to Video API to specify blitting operator. Now there is only two operators specified, replace and blend. Replace just uses source pixel data and blits it destination and blend uses source pixel alpha value to blend source and destination pixels.

Fantastic. So have you implemented everything you planned? :)

Almost. Couple of VBE2+ driver features are not implemented yet. But they should not limit much of going forward with implementing other features.

One issue that needs thinking is theming of GRUB, this includes colors and visual appearance and is also closely related to designing new menu system. What I would like to see is that that now as there is base work done on video side, someone could continue on menu side so I could do some other stuff :). I can of course help on menu stuff too.

There has been at lease couple of interested people on this in past and I would like them to step ahead :)

Thanks,
Vesa Jääskeläinen

#3 lore raw
Quoted 3 lines · Vesa Jääskeläinen

Almost. Couple of VBE2+ driver features are not implemented yet. But they should not limit much of going forward with implementing other features.

Great.

Quoted 5 lines

One issue that needs thinking is theming of GRUB, this includes colors and visual appearance and is also closely related to designing new menu system. What I would like to see is that that now as there is base work done on video side, someone could continue on menu side so I could do some other stuff :). I can of course help on menu stuff too.

I'm (always) planning to refactor the menu code, but I have little time at the moment, unfortunately... Once this is finished, I would be glad to make a try. ;)

Okuji