diff --git a/conf/common.rmk b/conf/common.rmk
index 3d74f90..41bfd30 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -521,13 +521,18 @@ lua_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Common Video Subsystem specific modules.
pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \
- png.mod font.mod gfxterm.mod
+ png.mod font.mod gfxterm.mod video_fb.mod
# For video.mod.
video_mod_SOURCES = video/video.c
video_mod_CFLAGS = $(COMMON_CFLAGS)
video_mod_LDFLAGS = $(COMMON_LDFLAGS)
+video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
+ video/fb/fbfill.c video/fb/fbutil.c
+video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For videotest.mod.
videotest_mod_SOURCES = commands/videotest.c
videotest_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index abb6fd5..66fdbd4 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -277,8 +277,7 @@ multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
- video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
+vbe_mod_SOURCES = video/i386/pc/vbe.c
vbe_mod_CFLAGS = $(COMMON_CFLAGS)
vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/include/grub/fbblit.h b/include/grub/fbblit.h
new file mode 100644
index 0000000..664f508
--- /dev/null
+++ b/include/grub/fbblit.h
@@ -0,0 +1,134 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+#ifndef GRUB_FBBLIT_HEADER
+#define GRUB_FBBLIT_HEADER 1
+
+/* NOTE: This header is private header for fb driver and should not be used
+ in other parts of the code. */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y);
+
+#endif /* ! GRUB_FBBLIT_HEADER */
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
new file mode 100644
index 0000000..11e22c6
--- /dev/null
+++ b/include/grub/fbfill.h
@@ -0,0 +1,52 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+#ifndef GRUB_FBFILL_HEADER
+#define GRUB_FBFILL_HEADER 1
+
+/* NOTE: This header is private header for fb driver and should not be used
+ in other parts of the code. */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height);
+
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height);
+
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height);
+
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height);
+
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height);
+
+#endif /* ! GRUB_FBFILL_HEADER */
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
new file mode 100644
index 0000000..76e1e57
--- /dev/null
+++ b/include/grub/fbutil.h
@@ -0,0 +1,43 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+/* NOTE: This header is private header for vbe driver and should not be used
+ in other parts of the code. */
+
+#ifndef GRUB_VBEUTIL_MACHINE_HEADER
+#define GRUB_VBEUTIL_MACHINE_HEADER 1
+
+#include
+#include
+
+struct grub_video_fbblit_info
+{
+ struct grub_video_mode_info *mode_info;
+ void *data;
+};
+
+grub_uint8_t *get_data_ptr (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y);
+
+grub_video_color_t get_pixel (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y);
+
+void set_pixel (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y, grub_video_color_t color);
+
+#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h
index bd6ecd7..fb11678 100644
--- a/include/grub/i386/pc/vbe.h
+++ b/include/grub/i386/pc/vbe.h
@@ -19,10 +19,7 @@
#ifndef GRUB_VBE_MACHINE_HEADER
#define GRUB_VBE_MACHINE_HEADER 1
-#include
-#include
-#include
-#include
+#include
/* Default video mode to be used. */
#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101
@@ -224,54 +221,5 @@ 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). */
-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 whether 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);
-
-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);
-
-grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
- grub_uint8_t *red,
- grub_uint8_t *green,
- grub_uint8_t *blue,
- grub_uint8_t *alpha);
-
-void grub_video_vbe_unmap_color_int (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);
#endif /* ! GRUB_VBE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vbeblit.h b/include/grub/i386/pc/vbeblit.h
deleted file mode 100644
index 5a2aa7a..0000000
--- a/include/grub/i386/pc/vbeblit.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-#ifndef GRUB_VBEBLIT_MACHINE_HEADER
-#define GRUB_VBEBLIT_MACHINE_HEADER 1
-
-/* 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_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_directN (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_BGR888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_index_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_replace_index_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y);
-
-void
-grub_video_i386_vbeblit_blend_index_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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
deleted file mode 100644
index efc6378..0000000
--- a/include/grub/i386/pc/vbefill.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-#ifndef GRUB_VBEFILL_MACHINE_HEADER
-#define GRUB_VBEFILL_MACHINE_HEADER 1
-
-/* 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 (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_direct32 (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_direct24 (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_direct16 (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_direct8 (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 */
diff --git a/include/grub/i386/pc/vbeutil.h b/include/grub/i386/pc/vbeutil.h
deleted file mode 100644
index 9b5be21..0000000
--- a/include/grub/i386/pc/vbeutil.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-/* NOTE: This header is private header for vbe driver and should not be used
- in other parts of the code. */
-
-#ifndef GRUB_VBEUTIL_MACHINE_HEADER
-#define GRUB_VBEUTIL_MACHINE_HEADER 1
-
-#include
-#include
-
-struct grub_video_i386_vbeblit_info
-{
- struct grub_video_mode_info *mode_info;
- void *data;
-};
-
-grub_uint8_t *get_data_ptr (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y);
-
-grub_video_color_t get_pixel (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y);
-
-void set_pixel (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y, grub_video_color_t color);
-
-#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
new file mode 100644
index 0000000..8c6987e
--- /dev/null
+++ b/include/grub/video_fb.h
@@ -0,0 +1,136 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER 1
+
+#include
+#include
+#include
+#include
+
+/* FB module internal prototype (should not be used from elsewhere). */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_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 whether 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;
+};
+
+struct grub_video_palette_data grub_video_fbstd_colors[16];
+
+grub_uint8_t * grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+ grub_uint32_t x, grub_uint32_t y);
+
+grub_err_t
+grub_video_fb_init (void);
+
+grub_err_t
+grub_video_fb_fini (void);
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info);
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+ struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+ struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height);
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+ unsigned int *width, unsigned int *height);
+
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name);
+
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+ grub_uint8_t blue);
+
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+ grub_uint8_t blue, grub_uint8_t alpha);
+
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha);
+
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+ grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha);
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+ unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_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);
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+ enum grub_video_blit_operators oper,
+ int x, int y, int offset_x, int offset_y,
+ unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+ unsigned int width, unsigned int height,
+ unsigned int mode_type __attribute__ ((unused)));
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target);
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target);
+
+#endif /* ! GRUB_VIDEO_FB_HEADER */
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
index 6510db6..1748836 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -31,9 +31,7 @@
#include
#include
#include
-/* FIXME: the definition of `struct grub_video_render_target' is
- VBE-specific. */
-#include
+#include
#include
#define GRUB_LINUX_CL_OFFSET 0x1000
@@ -403,14 +401,15 @@ static int
grub_linux_setup_video (struct linux_kernel_params *params)
{
struct grub_video_mode_info mode_info;
- struct grub_video_render_target *render_target;
+ struct grub_video_fbrender_target *render_target;
int ret;
ret = grub_video_get_info (&mode_info);
if (ret)
return 1;
- ret = grub_video_get_active_render_target (&render_target);
+ ret = grub_video_get_active_render_target
+ ((struct grub_video_render_target **) &render_target);
if (ret)
return 1;
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
index 037a713..2712a8a 100644
--- a/loader/i386/pc/xnu.c
+++ b/loader/i386/pc/xnu.c
@@ -21,8 +21,7 @@
#include
#include
#include
-#include
-#include
+#include
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -43,7 +42,7 @@ grub_err_t
grub_xnu_set_video (struct grub_xnu_boot_params *params)
{
struct grub_video_mode_info mode_info;
- struct grub_video_render_target *render_target;
+ struct grub_video_fbrender_target *render_target;
int ret;
int x,y;
char *tmp, *modevar;
@@ -71,7 +70,8 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
- ret = grub_video_get_active_render_target (&render_target);
+ ret = grub_video_get_active_render_target
+ ((struct grub_video_render_target **) &render_target);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c
new file mode 100644
index 0000000..138eba8
--- /dev/null
+++ b/video/fb/fbblit.c
@@ -0,0 +1,828 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+/* 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
+#include
+#include
+#include
+#include
+#include
+
+/* Generic replacing blitter (slow). Works for every supported format. */
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y)
+{
+ int i;
+ int j;
+ grub_uint8_t src_red;
+ grub_uint8_t src_green;
+ grub_uint8_t src_blue;
+ grub_uint8_t src_alpha;
+ grub_video_color_t src_color;
+ grub_video_color_t dst_color;
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ src_color = get_pixel (src, i + offset_x, j + offset_y);
+
+ grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+ &src_blue, &src_alpha);
+
+ dst_color = grub_video_fb_map_rgba (src_red, src_green,
+ src_blue, src_alpha);
+
+ set_pixel (dst, x + i, y + j, dst_color);
+ }
+ }
+}
+
+/* Block copy replacing blitter. Works with modes multiple of 8 bits. */
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y)
+{
+ int j;
+ grub_uint32_t *srcptr;
+ grub_uint32_t *dstptr;
+ int bpp;
+
+ bpp = src->mode_info->bytes_per_pixel;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
+
+ grub_memmove (dstptr, srcptr, width * bpp);
+ }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGRX8888. */
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ int i;
+ int j;
+ grub_uint8_t *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint8_t r = *srcptr++;
+ grub_uint8_t g = *srcptr++;
+ grub_uint8_t b = *srcptr++;
+ grub_uint8_t a = *srcptr++;
+
+ *dstptr++ = b;
+ *dstptr++ = g;
+ *dstptr++ = r;
+ *dstptr++ = a;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for RGB888 to BGRX8888. */
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ int i;
+ int j;
+ grub_uint8_t *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint8_t r = *srcptr++;
+ grub_uint8_t g = *srcptr++;
+ grub_uint8_t b = *srcptr++;
+
+ *dstptr++ = b;
+ *dstptr++ = g;
+ *dstptr++ = r;
+
+ /* Set alpha component as opaque. */
+ *dstptr++ = 255;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGR888. */
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ grub_uint32_t *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+ int i;
+ int j;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint32_t color;
+ grub_uint8_t sr;
+ grub_uint8_t sg;
+ grub_uint8_t sb;
+
+ color = *srcptr++;
+
+ sr = (color >> 0) & 0xFF;
+ sg = (color >> 8) & 0xFF;
+ sb = (color >> 16) & 0xFF;
+
+ *dstptr++ = sb;
+ *dstptr++ = sg;
+ *dstptr++ = sr;
+ }
+
+ srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for RGB888 to BGR888. */
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ int i;
+ int j;
+ grub_uint8_t *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint8_t r = *srcptr++;
+ grub_uint8_t g = *srcptr++;
+ grub_uint8_t b = *srcptr++;
+
+ *dstptr++ = b;
+ *dstptr++ = g;
+ *dstptr++ = r;
+ }
+
+ srcptr += srcrowskip;
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized replacing blitter for RGB888 to RGBX8888. */
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
+
+ for (i = 0; i < width; i++)
+ {
+ sr = *srcptr++;
+ sg = *srcptr++;
+ sb = *srcptr++;
+
+ /* Set alpha as opaque. */
+ color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
+
+ *dstptr++ = color;
+ }
+ }
+}
+
+/* Optimized replacing blitter for RGBX8888 to RGB888. */
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+ for (i = 0; i < width; i++)
+ {
+ color = *srcptr++;
+
+ sr = (color >> 0) & 0xFF;
+ sg = (color >> 8) & 0xFF;
+ sb = (color >> 16) & 0xFF;
+
+ *dstptr++ = sr;
+ *dstptr++ = sg;
+ *dstptr++ = sb;
+ }
+ }
+}
+
+/* Optimized replacing blitter for RGBX8888 to indexed color. */
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+ for (i = 0; i < width; i++)
+ {
+ color = *srcptr++;
+
+ sr = (color >> 0) & 0xFF;
+ sg = (color >> 8) & 0xFF;
+ sb = (color >> 16) & 0xFF;
+
+ color = grub_video_fb_map_rgb(sr, sg, sb);
+ *dstptr++ = color & 0xFF;
+ }
+ }
+}
+
+/* Optimized replacing blitter for RGB888 to indexed color. */
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
+
+ for (i = 0; i < width; i++)
+ {
+ sr = *srcptr++;
+ sg = *srcptr++;
+ sb = *srcptr++;
+
+ color = grub_video_fb_map_rgb(sr, sg, sb);
+
+ *dstptr++ = color & 0xFF;
+ }
+ }
+}
+
+/* Generic blending blitter. Works for every supported format. */
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y, int width, int height,
+ int offset_x, int offset_y)
+{
+ int i;
+ int j;
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint8_t src_red;
+ grub_uint8_t src_green;
+ grub_uint8_t src_blue;
+ grub_uint8_t src_alpha;
+ grub_uint8_t dst_red;
+ grub_uint8_t dst_green;
+ grub_uint8_t dst_blue;
+ grub_uint8_t dst_alpha;
+ grub_video_color_t src_color;
+ grub_video_color_t dst_color;
+
+ src_color = get_pixel (src, i + offset_x, j + offset_y);
+ grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+ &src_blue, &src_alpha);
+
+ if (src_alpha == 0)
+ continue;
+
+ if (src_alpha == 255)
+ {
+ dst_color = grub_video_fb_map_rgba (src_red, src_green,
+ src_blue, src_alpha);
+ set_pixel (dst, x + i, y + j, dst_color);
+ continue;
+ }
+
+ dst_color = get_pixel (dst, x + i, y + j);
+
+ grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
+ &dst_green, &dst_blue, &dst_alpha);
+
+ dst_red = (((src_red * src_alpha)
+ + (dst_red * (255 - src_alpha))) / 255);
+ dst_green = (((src_green * src_alpha)
+ + (dst_green * (255 - src_alpha))) / 255);
+ dst_blue = (((src_blue * src_alpha)
+ + (dst_blue * (255 - src_alpha))) / 255);
+
+ dst_alpha = src_alpha;
+ dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
+ dst_alpha);
+
+ set_pixel (dst, x + i, y + j, dst_color);
+ }
+ }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGRA8888. */
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ grub_uint32_t *srcptr;
+ grub_uint32_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+ int i;
+ int j;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint32_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint32_t color;
+ unsigned int sr;
+ unsigned int sg;
+ unsigned int sb;
+ unsigned int a;
+ unsigned int dr;
+ unsigned int dg;
+ unsigned int db;
+
+ color = *srcptr++;
+
+ a = color >> 24;
+
+ if (a == 0)
+ {
+ /* Skip transparent source pixels. */
+ dstptr++;
+ continue;
+ }
+
+ sr = (color >> 0) & 0xFF;
+ sg = (color >> 8) & 0xFF;
+ sb = (color >> 16) & 0xFF;
+
+ if (a == 255)
+ {
+ /* Opaque pixel shortcut. */
+ dr = sr;
+ dg = sg;
+ db = sb;
+ }
+ else
+ {
+ /* General pixel color blending. */
+ color = *dstptr;
+
+ dr = (color >> 16) & 0xFF;
+ dr = (dr * (255 - a) + sr * a) / 255;
+ dg = (color >> 8) & 0xFF;
+ dg = (dg * (255 - a) + sg * a) / 255;
+ db = (color >> 0) & 0xFF;
+ db = (db * (255 - a) + sb * a) / 255;
+ }
+
+ color = (a << 24) | (dr << 16) | (dg << 8) | db;
+
+ *dstptr++ = color;
+ }
+
+ srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+ dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
+ }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGR888. */
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ grub_uint32_t *srcptr;
+ grub_uint8_t *dstptr;
+ unsigned int srcrowskip;
+ unsigned int dstrowskip;
+ int i;
+ int j;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+ dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ grub_uint32_t color;
+ unsigned int sr;
+ unsigned int sg;
+ unsigned int sb;
+ unsigned int a;
+ unsigned int dr;
+ unsigned int dg;
+ unsigned int db;
+
+ color = *srcptr++;
+
+ a = color >> 24;
+
+ if (a == 0)
+ {
+ /* Skip transparent source pixels. */
+ dstptr += 3;
+ continue;
+ }
+
+ sr = (color >> 0) & 0xFF;
+ sg = (color >> 8) & 0xFF;
+ sb = (color >> 16) & 0xFF;
+
+ if (a == 255)
+ {
+ /* Opaque pixel shortcut. */
+ dr = sr;
+ dg = sg;
+ db = sb;
+ }
+ else
+ {
+ /* General pixel color blending. */
+ color = *dstptr;
+
+ db = dstptr[0];
+ db = (db * (255 - a) + sb * a) / 255;
+ dg = dstptr[1];
+ dg = (dg * (255 - a) + sg * a) / 255;
+ dr = dstptr[2];
+ dr = (dr * (255 - a) + sr * a) / 255;
+ }
+
+ *dstptr++ = db;
+ *dstptr++ = dg;
+ *dstptr++ = dr;
+ }
+
+ srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+ dstptr += dstrowskip;
+ }
+}
+
+/* Optimized blending blitter for RGBA888 to RGBA8888. */
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)get_data_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;
+ }
+ }
+}
+
+/* Optimized blending blitter for RGBA8888 to RGB888. */
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)get_data_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;
+ }
+ }
+}
+
+/* Optimized blending blitter for RGBA8888 to indexed color. */
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+ struct grub_video_fbblit_info *src,
+ int x, int y,
+ int width, int height,
+ int offset_x, int offset_y)
+{
+ 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;
+
+ for (j = 0; j < height; j++)
+ {
+ srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)get_data_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_fb_map_rgb(sr, sg, sb);
+ *dstptr++ = color & 0xFF;
+ continue;
+ }
+
+ grub_video_fb_unmap_color_int (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_fb_map_rgb(dr, dg, db);
+
+ *dstptr++ = color & 0xFF;
+ }
+ }
+}
diff --git a/video/fb/fbfill.c b/video/fb/fbfill.c
new file mode 100644
index 0000000..a4ca7c2
--- /dev/null
+++ b/video/fb/fbfill.c
@@ -0,0 +1,177 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+/* 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
+#include
+#include
+#include
+#include
+
+/* Generic filler that works for every supported mode. */
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height)
+{
+ int i;
+ int j;
+
+ for (j = 0; j < height; j++)
+ for (i = 0; i < width; i++)
+ set_pixel (dst, x + i, y + j, color);
+}
+
+/* Optimized filler for direct color 32 bit modes. It is assumed that color
+ is already mapped to destination format. */
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height)
+{
+ int i;
+ int j;
+ grub_uint32_t *dstptr;
+ grub_size_t rowskip;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ /* Get the start address. */
+ dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ *dstptr++ = color;
+
+ /* Advance the dest pointer to the right location on the next line. */
+ dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
+ }
+}
+
+/* Optimized filler for direct color 24 bit modes. It is assumed that color
+ is already mapped to destination format. */
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height)
+{
+ int i;
+ int j;
+ grub_size_t rowskip;
+ grub_uint8_t *dstptr;
+ grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+ grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+ grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ /* Get the start address. */
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ *dstptr++ = fill0;
+ *dstptr++ = fill1;
+ *dstptr++ = fill2;
+ }
+
+ /* Advance the dest pointer to the right location on the next line. */
+ dstptr += rowskip;
+ }
+}
+
+/* Optimized filler for direct color 16 bit modes. It is assumed that color
+ is already mapped to destination format. */
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height)
+{
+ int i;
+ int j;
+ grub_size_t rowskip;
+ grub_uint8_t *dstptr;
+ grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+ grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ /* Get the start address. */
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ *dstptr++ = fill0;
+ *dstptr++ = fill1;
+ }
+
+ /* Advance the dest pointer to the right location on the next line. */
+ dstptr += rowskip;
+ }
+}
+
+/* Optimized filler for index color. It is assumed that color
+ is already mapped to destination format. */
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+ grub_video_color_t color, int x, int y,
+ int width, int height)
+{
+ int i;
+ int j;
+ grub_size_t rowskip;
+ grub_uint8_t *dstptr;
+ grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
+
+ /* Calculate the number of bytes to advance from the end of one line
+ to the beginning of the next line. */
+ rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+ /* Get the start address. */
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ *dstptr++ = fill;
+
+ /* Advance the dest pointer to the right location on the next line. */
+ dstptr += rowskip;
+ }
+}
diff --git a/video/fb/fbutil.c b/video/fb/fbutil.c
new file mode 100644
index 0000000..09cbb12
--- /dev/null
+++ b/video/fb/fbutil.c
@@ -0,0 +1,177 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+
+grub_uint8_t *
+get_data_ptr (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y)
+{
+ grub_uint8_t *ptr = 0;
+
+ switch (source->mode_info->bpp)
+ {
+ case 32:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 4;
+ break;
+
+ case 24:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 3;
+ break;
+
+ case 16:
+ case 15:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 2;
+ break;
+
+ case 8:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x;
+ break;
+
+ case 1:
+ /* For 1-bit bitmaps, addressing needs to be done at the bit level
+ and it doesn't make sense, in general, to ask for a pointer
+ to a particular pixel's data. */
+ break;
+ }
+
+ return ptr;
+}
+
+grub_video_color_t
+get_pixel (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y)
+{
+ grub_video_color_t color = 0;
+
+ switch (source->mode_info->bpp)
+ {
+ case 32:
+ color = *(grub_uint32_t *)get_data_ptr (source, x, y);
+ break;
+
+ case 24:
+ {
+ grub_uint8_t *ptr;
+ ptr = get_data_ptr (source, x, y);
+ color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
+ }
+ break;
+
+ case 16:
+ case 15:
+ color = *(grub_uint16_t *)get_data_ptr (source, x, y);
+ break;
+
+ case 8:
+ color = *(grub_uint8_t *)get_data_ptr (source, x, y);
+ break;
+
+ case 1:
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+ {
+ int bit_index = y * source->mode_info->width + x;
+ grub_uint8_t *ptr = (grub_uint8_t *)source->data
+ + bit_index / 8;
+ int bit_pos = 7 - bit_index % 8;
+ color = (*ptr >> bit_pos) & 0x01;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return color;
+}
+
+void
+set_pixel (struct grub_video_fbblit_info *source,
+ unsigned int x, unsigned int y, grub_video_color_t color)
+{
+ switch (source->mode_info->bpp)
+ {
+ case 32:
+ {
+ grub_uint32_t *ptr;
+
+ ptr = (grub_uint32_t *)get_data_ptr (source, x, y);
+
+ *ptr = color;
+ }
+ break;
+
+ case 24:
+ {
+ grub_uint8_t *ptr;
+ grub_uint8_t *colorptr = (grub_uint8_t *)&color;
+
+ ptr = get_data_ptr (source, x, y);
+
+ ptr[0] = colorptr[0];
+ ptr[1] = colorptr[1];
+ ptr[2] = colorptr[2];
+ }
+ break;
+
+ case 16:
+ case 15:
+ {
+ grub_uint16_t *ptr;
+
+ ptr = (grub_uint16_t *)get_data_ptr (source, x, y);
+
+ *ptr = (grub_uint16_t) (color & 0xFFFF);
+ }
+ break;
+
+ case 8:
+ {
+ grub_uint8_t *ptr;
+
+ ptr = (grub_uint8_t *)get_data_ptr (source, x, y);
+
+ *ptr = (grub_uint8_t) (color & 0xFF);
+ }
+ break;
+
+ case 1:
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+ {
+ int bit_index = y * source->mode_info->width + x;
+ grub_uint8_t *ptr = (grub_uint8_t *)source->data
+ + bit_index / 8;
+ int bit_pos = 7 - bit_index % 8;
+ *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
new file mode 100644
index 0000000..98f80c3
--- /dev/null
+++ b/video/fb/video_fb.c
@@ -0,0 +1,1100 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static struct grub_video_fbrender_target *render_target;
+struct grub_video_palette_data *palette;
+static unsigned int palette_size;
+
+/* Specify "standard" VGA palette, some video cards may
+ need this and this will also be used when using RGB modes. */
+struct grub_video_palette_data grub_video_fbstd_colors[16] =
+ {
+ // {R, G, B, A}
+ {0x00, 0x00, 0x00, 0xFF}, // 0 = black
+ {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
+ {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
+ {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
+ {0xA8, 0x00, 0x00, 0xFF}, // 4 = red
+ {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
+ {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
+ {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
+
+ {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
+ {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
+ {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
+ {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
+ {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
+ {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
+ {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
+ {0xFE, 0xFE, 0xFE, 0xFF} // 15 = white
+ };
+
+grub_err_t
+grub_video_fb_init (void)
+{
+ grub_free (palette);
+ render_target = 0;
+ palette = 0;
+ palette_size = 0;
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_fini (void)
+{
+ grub_free (palette);
+ render_target = 0;
+ palette = 0;
+ palette_size = 0;
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info)
+{
+ /* Copy mode info from active render target. */
+ grub_memcpy (mode_info, &render_target->mode_info,
+ sizeof (struct grub_video_mode_info));
+
+ return GRUB_ERR_NONE;
+}
+
+
+grub_uint8_t *
+grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+ grub_uint32_t x, grub_uint32_t y)
+{
+ grub_uint8_t *ptr = 0;
+
+ switch (source->mode_info->bpp)
+ {
+ case 32:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 4;
+ break;
+
+ case 24:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 3;
+ break;
+
+ case 16:
+ case 15:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x * 2;
+ break;
+
+ case 8:
+ ptr = (grub_uint8_t *)source->data
+ + y * source->mode_info->pitch
+ + x;
+ break;
+ }
+
+ return ptr;
+}
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+ struct grub_video_palette_data *palette_data)
+{
+ unsigned int i;
+
+ /* Assume that we know everything from index color palette. */
+ for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+ palette_data[i] = palette[start + i];
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+ struct grub_video_palette_data *palette_data)
+{
+ unsigned i;
+ if (start + count > palette_size)
+ {
+ palette_size = start + count;
+ palette = grub_realloc (palette, sizeof (palette[0]) * palette_size);
+ if (!palette)
+ {
+ grub_video_fb_fini ();
+ return grub_errno;
+ }
+ }
+ for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+ palette[start + i] = palette_data[i];
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height)
+{
+ render_target->viewport.x = x;
+ render_target->viewport.y = y;
+ render_target->viewport.width = width;
+ render_target->viewport.height = height;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+ unsigned int *width, unsigned int *height)
+{
+ if (x) *x = render_target->viewport.x;
+ if (y) *y = render_target->viewport.y;
+ if (width) *width = render_target->viewport.width;
+ if (height) *height = render_target->viewport.height;
+
+ return GRUB_ERR_NONE;
+}
+
+/* Maps color name to target optimized color format. */
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name)
+{
+ /* TODO: implement color theme mapping code. */
+
+ if (color_name < palette_size)
+ {
+ if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+ return color_name;
+ else
+ {
+ grub_video_color_t color;
+
+ color = grub_video_fb_map_rgb (palette[color_name].r,
+ palette[color_name].g,
+ palette[color_name].b);
+
+ return color;
+ }
+ }
+
+ return 0;
+}
+
+/* Maps RGB to target optimized color format. */
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+ grub_uint8_t blue)
+{
+ if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+ {
+ int minindex = 0;
+ int delta = 0;
+ int tmp;
+ int val;
+ unsigned i;
+
+ /* Find best matching color. */
+ for (i = 0; i < palette_size; i++)
+ {
+ val = palette[i].r - red;
+ tmp = val * val;
+ val = palette[i].g - green;
+ tmp += val * val;
+ val = palette[i].b - blue;
+ tmp += val * val;
+
+ if (i == 0)
+ delta = tmp;
+
+ if (tmp < delta)
+ {
+ delta = tmp;
+ minindex = i;
+ if (tmp == 0)
+ break;
+ }
+ }
+
+ return minindex;
+ }
+ else if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (red == render_target->mode_info.fg_red
+ && green == render_target->mode_info.fg_green
+ && blue == render_target->mode_info.fg_blue)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ {
+ grub_uint32_t value;
+ grub_uint8_t alpha = 255; /* Opaque color. */
+
+ red >>= 8 - render_target->mode_info.red_mask_size;
+ green >>= 8 - render_target->mode_info.green_mask_size;
+ blue >>= 8 - render_target->mode_info.blue_mask_size;
+ alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+ value = red << render_target->mode_info.red_field_pos;
+ value |= green << render_target->mode_info.green_field_pos;
+ value |= blue << render_target->mode_info.blue_field_pos;
+ value |= alpha << render_target->mode_info.reserved_field_pos;
+
+ return value;
+ }
+
+}
+
+/* Maps RGBA to target optimized color format. */
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+ grub_uint8_t blue, grub_uint8_t alpha)
+{
+ if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+ /* No alpha available in index color modes, just use
+ same value as in only RGB modes. */
+ return grub_video_fb_map_rgb (red, green, blue);
+ else if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (red == render_target->mode_info.fg_red
+ && green == render_target->mode_info.fg_green
+ && blue == render_target->mode_info.fg_blue
+ && alpha == render_target->mode_info.fg_alpha)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ {
+ grub_uint32_t value;
+
+ red >>= 8 - render_target->mode_info.red_mask_size;
+ green >>= 8 - render_target->mode_info.green_mask_size;
+ blue >>= 8 - render_target->mode_info.blue_mask_size;
+ alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+ value = red << render_target->mode_info.red_field_pos;
+ value |= green << render_target->mode_info.green_field_pos;
+ value |= blue << render_target->mode_info.blue_field_pos;
+ value |= alpha << render_target->mode_info.reserved_field_pos;
+
+ return value;
+ }
+}
+
+/* Splits target optimized format to components. */
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+ struct grub_video_fbblit_info target_info;
+
+ target_info.mode_info = &render_target->mode_info;
+ target_info.data = render_target->data;
+
+ grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha);
+
+ return GRUB_ERR_NONE;
+}
+
+/* Splits color in source format to components. */
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+ grub_video_color_t color,
+ grub_uint8_t *red, grub_uint8_t *green,
+ grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+ struct grub_video_mode_info *mode_info;
+ mode_info = source->mode_info;
+
+ if ((mode_info->mode_type
+ & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+ {
+ /* If we have an out-of-bounds color, return transparent black. */
+ if (color > 255)
+ {
+ *red = 0;
+ *green = 0;
+ *blue = 0;
+ *alpha = 0;
+ return;
+ }
+
+ *red = palette[color].r;
+ *green = palette[color].g;
+ *blue = palette[color].b;
+ *alpha = palette[color].a;
+ return;
+ }
+ else if ((mode_info->mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (color & 1)
+ {
+ *red = mode_info->fg_red;
+ *green = mode_info->fg_green;
+ *blue = mode_info->fg_blue;
+ *alpha = mode_info->fg_alpha;
+ }
+ else
+ {
+ *red = mode_info->bg_red;
+ *green = mode_info->bg_green;
+ *blue = mode_info->bg_blue;
+ *alpha = mode_info->bg_alpha;
+ }
+ }
+ else
+ {
+ grub_uint32_t tmp;
+
+ /* Get red component. */
+ tmp = color >> mode_info->red_field_pos;
+ tmp &= (1 << mode_info->red_mask_size) - 1;
+ tmp <<= 8 - mode_info->red_mask_size;
+ tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
+ *red = tmp & 0xFF;
+
+ /* Get green component. */
+ tmp = color >> mode_info->green_field_pos;
+ tmp &= (1 << mode_info->green_mask_size) - 1;
+ tmp <<= 8 - mode_info->green_mask_size;
+ tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
+ *green = tmp & 0xFF;
+
+ /* Get blue component. */
+ tmp = color >> mode_info->blue_field_pos;
+ tmp &= (1 << mode_info->blue_mask_size) - 1;
+ tmp <<= 8 - mode_info->blue_mask_size;
+ tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
+ *blue = tmp & 0xFF;
+
+ /* Get alpha component. */
+ if (source->mode_info->reserved_mask_size > 0)
+ {
+ tmp = color >> mode_info->reserved_field_pos;
+ tmp &= (1 << mode_info->reserved_mask_size) - 1;
+ tmp <<= 8 - mode_info->reserved_mask_size;
+ tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
+ }
+ else
+ /* If there is no alpha component, assume it opaque. */
+ tmp = 255;
+
+ *alpha = tmp & 0xFF;
+ }
+}
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+ unsigned int width, unsigned int height)
+{
+ struct grub_video_fbblit_info target;
+
+ /* Make sure there is something to do. */
+ if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+ return GRUB_ERR_NONE;
+ if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+ return GRUB_ERR_NONE;
+
+ /* Do not allow drawing out of viewport. */
+ if (x < 0)
+ {
+ width += x;
+ x = 0;
+ }
+ if (y < 0)
+ {
+ height += y;
+ y = 0;
+ }
+
+ if ((x + width) > render_target->viewport.width)
+ width = render_target->viewport.width - x;
+ if ((y + height) > render_target->viewport.height)
+ height = render_target->viewport.height - y;
+
+ /* Add viewport offset. */
+ x += render_target->viewport.x;
+ y += render_target->viewport.y;
+
+ /* Use fbblit_info to encapsulate rendering. */
+ target.mode_info = &render_target->mode_info;
+ target.data = render_target->data;
+
+ /* Try to figure out more optimized version. Note that color is already
+ mapped to target format so we can make assumptions based on that. */
+ if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbfill_direct32 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+ else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ grub_video_fbfill_direct32 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+ else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ grub_video_fbfill_direct24 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+ else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+ {
+ grub_video_fbfill_direct16 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+ else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
+ {
+ grub_video_fbfill_direct16 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+ else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbfill_direct8 (&target, color, x, y,
+ width, height);
+ return GRUB_ERR_NONE;
+ }
+
+ /* No optimized version found, use default (slow) filler. */
+ grub_video_fbfill (&target, color, x, y, width, height);
+
+ return GRUB_ERR_NONE;
+}
+
+/* NOTE: This function assumes that given coordinates are within bounds of
+ handled data. */
+static void
+common_blitter (struct grub_video_fbblit_info *target,
+ struct grub_video_fbblit_info *source,
+ enum grub_video_blit_operators oper, int x, int y,
+ unsigned int width, unsigned int height,
+ int offset_x, int offset_y)
+{
+ if (oper == GRUB_VIDEO_BLIT_REPLACE)
+ {
+ /* Try to figure out more optimized version for replace operator. */
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ grub_video_fbblit_replace_directN (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+ {
+ grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbblit_replace_index_RGBX8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+ else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+ {
+ grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ grub_video_fbblit_replace_directN (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbblit_replace_index_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+ else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbblit_replace_directN (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+ else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbblit_replace_directN (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+
+ /* No optimized replace operator found, use default (slow) blitter. */
+ grub_video_fbblit_replace (target, source, x, y, width, height,
+ offset_x, offset_y);
+ }
+ else
+ {
+ /* Try to figure out more optimized blend operator. */
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+ {
+ grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbblit_blend_index_RGBA8888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+ else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ /* Note: There is really no alpha information here, so blend is
+ changed to replace. */
+
+ if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+ {
+ grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+ {
+ grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+ {
+ grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+ {
+ grub_video_fbblit_replace_directN (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+ {
+ grub_video_fbblit_replace_index_RGB888 (target, source,
+ x, y, width, height,
+ offset_x, offset_y);
+ return;
+ }
+ }
+
+ /* No optimized blend operation found, use default (slow) blitter. */
+ grub_video_fbblit_blend (target, source, x, y, width, height,
+ offset_x, offset_y);
+ }
+}
+
+grub_err_t
+grub_video_fb_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)
+{
+ struct grub_video_fbblit_info source;
+ struct grub_video_fbblit_info target;
+
+ /* Make sure there is something to do. */
+ if ((width == 0) || (height == 0))
+ return GRUB_ERR_NONE;
+ if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+ return GRUB_ERR_NONE;
+ if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+ return GRUB_ERR_NONE;
+ if ((x + (int)bitmap->mode_info.width) < 0)
+ return GRUB_ERR_NONE;
+ if ((y + (int)bitmap->mode_info.height) < 0)
+ return GRUB_ERR_NONE;
+ if ((offset_x >= (int)bitmap->mode_info.width)
+ || (offset_x + (int)width < 0))
+ return GRUB_ERR_NONE;
+ if ((offset_y >= (int)bitmap->mode_info.height)
+ || (offset_y + (int)height < 0))
+ return GRUB_ERR_NONE;
+
+ /* If we have negative coordinates, optimize drawing to minimum. */
+ if (offset_x < 0)
+ {
+ width += offset_x;
+ x -= offset_x;
+ offset_x = 0;
+ }
+
+ if (offset_y < 0)
+ {
+ height += offset_y;
+ y -= offset_y;
+ offset_y = 0;
+ }
+
+ if (x < 0)
+ {
+ width += x;
+ offset_x -= x;
+ x = 0;
+ }
+
+ if (y < 0)
+ {
+ height += y;
+ offset_y -= y;
+ y = 0;
+ }
+
+ /* Do not allow drawing out of viewport. */
+ if ((x + width) > render_target->viewport.width)
+ width = render_target->viewport.width - x;
+ if ((y + height) > render_target->viewport.height)
+ height = render_target->viewport.height - y;
+
+ if ((offset_x + width) > bitmap->mode_info.width)
+ width = bitmap->mode_info.width - offset_x;
+ if ((offset_y + height) > bitmap->mode_info.height)
+ height = bitmap->mode_info.height - offset_y;
+
+ /* Limit drawing to source render target dimensions. */
+ if (width > bitmap->mode_info.width)
+ width = bitmap->mode_info.width;
+
+ if (height > bitmap->mode_info.height)
+ height = bitmap->mode_info.height;
+
+ /* Add viewport offset. */
+ x += render_target->viewport.x;
+ y += render_target->viewport.y;
+
+ /* Use fbblit_info to encapsulate rendering. */
+ source.mode_info = &bitmap->mode_info;
+ source.data = bitmap->data;
+ target.mode_info = &render_target->mode_info;
+ target.data = render_target->data;
+
+ /* Do actual blitting. */
+ common_blitter (&target, &source, oper, x, y, width, height,
+ offset_x, offset_y);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+ enum grub_video_blit_operators oper,
+ int x, int y, int offset_x, int offset_y,
+ unsigned int width, unsigned int height)
+{
+ struct grub_video_fbblit_info source_info;
+ struct grub_video_fbblit_info target_info;
+
+ /* Make sure there is something to do. */
+ if ((width == 0) || (height == 0))
+ return GRUB_ERR_NONE;
+ if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+ return GRUB_ERR_NONE;
+ if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+ return GRUB_ERR_NONE;
+ if ((x + (int)source->mode_info.width) < 0)
+ return GRUB_ERR_NONE;
+ if ((y + (int)source->mode_info.height) < 0)
+ return GRUB_ERR_NONE;
+ if ((offset_x >= (int)source->mode_info.width)
+ || (offset_x + (int)width < 0))
+ return GRUB_ERR_NONE;
+ if ((offset_y >= (int)source->mode_info.height)
+ || (offset_y + (int)height < 0))
+ return GRUB_ERR_NONE;
+
+ /* If we have negative coordinates, optimize drawing to minimum. */
+ if (offset_x < 0)
+ {
+ width += offset_x;
+ x -= offset_x;
+ offset_x = 0;
+ }
+
+ if (offset_y < 0)
+ {
+ height += offset_y;
+ y -= offset_y;
+ offset_y = 0;
+ }
+
+ if (x < 0)
+ {
+ width += x;
+ offset_x -= x;
+ x = 0;
+ }
+
+ if (y < 0)
+ {
+ height += y;
+ offset_y -= y;
+ y = 0;
+ }
+
+ /* Do not allow drawing out of viewport. */
+ if ((x + width) > render_target->viewport.width)
+ width = render_target->viewport.width - x;
+ if ((y + height) > render_target->viewport.height)
+ height = render_target->viewport.height - y;
+
+ if ((offset_x + width) > source->mode_info.width)
+ width = source->mode_info.width - offset_x;
+ if ((offset_y + height) > source->mode_info.height)
+ height = source->mode_info.height - offset_y;
+
+ /* Limit drawing to source render target dimensions. */
+ if (width > source->mode_info.width)
+ width = source->mode_info.width;
+
+ if (height > source->mode_info.height)
+ height = source->mode_info.height;
+
+ /* Add viewport offset. */
+ x += render_target->viewport.x;
+ y += render_target->viewport.y;
+
+ /* Use fbblit_info to encapsulate rendering. */
+ source_info.mode_info = &source->mode_info;
+ source_info.data = source->data;
+ target_info.mode_info = &render_target->mode_info;
+ target_info.data = render_target->data;
+
+ /* Do actual blitting. */
+ common_blitter (&target_info, &source_info, oper, x, y, width, height,
+ offset_x, offset_y);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
+{
+ int width;
+ int height;
+ int src_x;
+ int src_y;
+ int dst_x;
+ int dst_y;
+
+ /* 1. Check if we have something to do. */
+ if ((dx == 0) && (dy == 0))
+ return GRUB_ERR_NONE;
+
+ width = render_target->viewport.width - grub_abs (dx);
+ height = render_target->viewport.height - grub_abs (dy);
+
+ if (dx < 0)
+ {
+ src_x = render_target->viewport.x - dx;
+ dst_x = render_target->viewport.x;
+ }
+ else
+ {
+ src_x = render_target->viewport.x;
+ dst_x = render_target->viewport.x + dx;
+ }
+
+ if (dy < 0)
+ {
+ src_y = render_target->viewport.y - dy;
+ dst_y = render_target->viewport.y;
+ }
+ else
+ {
+ src_y = render_target->viewport.y;
+ dst_y = render_target->viewport.y + dy;
+ }
+
+ /* 2. Check if there is need to copy data. */
+ if ((grub_abs (dx) < render_target->viewport.width)
+ && (grub_abs (dy) < render_target->viewport.height))
+ {
+ /* 3. Move data in render target. */
+ struct grub_video_fbblit_info target;
+ grub_uint8_t *src;
+ grub_uint8_t *dst;
+ int j;
+
+ target.mode_info = &render_target->mode_info;
+ target.data = render_target->data;
+
+ /* Check vertical direction of the move. */
+ if (dy <= 0)
+ /* 3a. Move data upwards. */
+ for (j = 0; j < height; j++)
+ {
+ dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+ src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+ grub_memmove (dst, src,
+ width * target.mode_info->bytes_per_pixel);
+ }
+ else
+ /* 3b. Move data downwards. */
+ for (j = (height - 1); j >= 0; j--)
+ {
+ dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+ src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+ grub_memmove (dst, src,
+ width * target.mode_info->bytes_per_pixel);
+ }
+ }
+
+ /* 4. Fill empty space with specified color. In this implementation
+ there might be colliding areas but at the moment there is no need
+ to optimize this. */
+
+ /* 4a. Fill top & bottom parts. */
+ if (dy > 0)
+ grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
+ else if (dy < 0)
+ {
+ if (render_target->viewport.height < grub_abs (dy))
+ dy = -render_target->viewport.height;
+
+ grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
+ render_target->viewport.width, -dy);
+ }
+
+ /* 4b. Fill left & right parts. */
+ if (dx > 0)
+ grub_video_fb_fill_rect (color, 0, 0,
+ dx, render_target->viewport.height);
+ else if (dx < 0)
+ {
+ if (render_target->viewport.width < grub_abs (dx))
+ dx = -render_target->viewport.width;
+
+ grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
+ -dx, render_target->viewport.height);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+ unsigned int width, unsigned int height,
+ unsigned int mode_type __attribute__ ((unused)))
+{
+ struct grub_video_fbrender_target *target;
+ unsigned int size;
+
+ /* Validate arguments. */
+ if ((! result)
+ || (width == 0)
+ || (height == 0))
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "invalid argument given.");
+
+ /* Allocate memory for render target. */
+ target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+ if (! target)
+ return grub_errno;
+
+ /* TODO: Implement other types too.
+ Currently only 32bit render targets are supported. */
+
+ /* Mark render target as allocated. */
+ target->is_allocated = 1;
+
+ /* Maximize viewport. */
+ target->viewport.x = 0;
+ target->viewport.y = 0;
+ target->viewport.width = width;
+ target->viewport.height = height;
+
+ /* Setup render target format. */
+ target->mode_info.width = width;
+ target->mode_info.height = height;
+ target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+ | GRUB_VIDEO_MODE_TYPE_ALPHA;
+ target->mode_info.bpp = 32;
+ target->mode_info.bytes_per_pixel = 4;
+ target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
+ target->mode_info.number_of_colors = palette_size; /* Emulated palette. */
+ target->mode_info.red_mask_size = 8;
+ target->mode_info.red_field_pos = 0;
+ target->mode_info.green_mask_size = 8;
+ target->mode_info.green_field_pos = 8;
+ target->mode_info.blue_mask_size = 8;
+ target->mode_info.blue_field_pos = 16;
+ target->mode_info.reserved_mask_size = 8;
+ target->mode_info.reserved_field_pos = 24;
+
+ target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
+
+ /* Calculate size needed for the data. */
+ size = (width * target->mode_info.bytes_per_pixel) * height;
+
+ target->data = grub_malloc (size);
+ if (! target->data)
+ {
+ grub_free (target);
+ return grub_errno;
+ }
+
+ /* Clear render target with black and maximum transparency. */
+ grub_memset (target->data, 0, size);
+
+ /* TODO: Add render target to render target list. */
+
+ /* Save result to caller. */
+ *result = target;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target)
+{
+ /* If there is no target, then just return without error. */
+ if (! target)
+ return GRUB_ERR_NONE;
+
+ /* TODO: Delist render target from render target list. */
+
+ /* If this is software render target, free it's memory. */
+ if (target->is_allocated)
+ grub_free (target->data);
+
+ /* Free render target. */
+ grub_free (target);
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target)
+{
+ if (! target->data)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "invalid render target given.");
+
+ render_target = target;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target)
+{
+ *target = render_target;
+
+ return GRUB_ERR_NONE;
+}
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
index ae08402..19cfaf5 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -16,43 +16,17 @@
* along with GRUB. If not, see .
*/
+#define grub_video_render_target grub_video_fbrender_target
+
#include
#include
#include
#include
-#include
-#include
-#include
#include
#include
#include
#include
#include
-#include
-
-/* Specify "standard" VGA palette, some video cards may
- need this and this will also be used when using RGB modes. */
-static struct grub_vbe_palette_data vga_colors[16] =
- {
- // {B, G, R, A}
- {0x00, 0x00, 0x00, 0x00}, // 0 = black
- {0xA8, 0x00, 0x00, 0x00}, // 1 = blue
- {0x00, 0xA8, 0x00, 0x00}, // 2 = green
- {0xA8, 0xA8, 0x00, 0x00}, // 3 = cyan
- {0x00, 0x00, 0xA8, 0x00}, // 4 = red
- {0xA8, 0x00, 0xA8, 0x00}, // 5 = magenta
- {0x00, 0x54, 0xA8, 0x00}, // 6 = brown
- {0xA8, 0xA8, 0xA8, 0x00}, // 7 = light gray
-
- {0x54, 0x54, 0x54, 0x00}, // 8 = dark gray
- {0xFE, 0x54, 0x54, 0x00}, // 9 = bright blue
- {0x54, 0xFE, 0x54, 0x00}, // 10 = bright green
- {0xFE, 0xFE, 0x54, 0x00}, // 11 = bright cyan
- {0x54, 0x54, 0xFE, 0x00}, // 12 = bright red
- {0xFE, 0x54, 0xFE, 0x00}, // 13 = bright magenta
- {0x54, 0xFE, 0xFE, 0x00}, // 14 = yellow
- {0xFE, 0xFE, 0xFE, 0x00} // 15 = white
- };
static int vbe_detected = -1;
@@ -68,10 +42,8 @@ static struct
grub_uint32_t active_mode;
grub_uint8_t *ptr;
int index_color_mode;
- struct grub_video_palette_data palette[256];
} framebuffer;
-static struct grub_video_render_target *render_target;
static grub_uint32_t initial_mode;
static grub_uint32_t mode_in_use = 0x55aa;
static grub_uint16_t *mode_list;
@@ -239,11 +211,20 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
{
struct grub_vbe_palette_data *palette
= (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+ unsigned i;
- /* Make sure that the BIOS can reach the palette. */
- grub_memcpy (palette, vga_colors, sizeof (vga_colors));
- status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
- / sizeof (struct grub_vbe_palette_data),
+ /* Make sure that the BIOS can reach the palette. */
+ for (i = 0; i < sizeof (grub_video_fbstd_colors)
+ / sizeof (grub_video_fbstd_colors[0]); i++)
+ {
+ palette[i].red = grub_video_fbstd_colors[i].r;
+ palette[i].green = grub_video_fbstd_colors[i].g;
+ palette[i].blue = grub_video_fbstd_colors[i].b;
+ palette[i].alignment = 0;
+ }
+
+ status = grub_vbe_bios_set_palette_data (sizeof (grub_video_fbstd_colors)
+ / sizeof (grub_video_fbstd_colors[0]),
0,
palette);
@@ -308,43 +289,6 @@ grub_vbe_get_video_mode_info (grub_uint32_t mode,
return GRUB_ERR_NONE;
}
-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_uint8_t *ptr = 0;
-
- switch (source->mode_info->bpp)
- {
- case 32:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 4;
- break;
-
- case 24:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 3;
- break;
-
- case 16:
- case 15:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 2;
- break;
-
- case 8:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x;
- break;
- }
-
- return ptr;
-}
-
static grub_err_t
grub_video_vbe_init (void)
{
@@ -387,9 +331,7 @@ grub_video_vbe_init (void)
/* Reset frame buffer and render target variables. */
grub_memset (&framebuffer, 0, sizeof(framebuffer));
- render_target = &framebuffer.render_target;
-
- return GRUB_ERR_NONE;
+ return grub_video_fb_init ();
}
static grub_err_t
@@ -409,8 +351,7 @@ grub_video_vbe_fini (void)
/* TODO: destroy render targets. */
- /* Return success to caller. */
- return GRUB_ERR_NONE;
+ return grub_video_fb_fini ();
}
static grub_err_t
@@ -422,7 +363,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
struct grub_vbe_mode_info_block best_mode_info;
grub_uint32_t best_mode = 0;
int depth;
- unsigned int i;
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
@@ -512,54 +452,63 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
in order to fasten later operations. */
mode_in_use = best_mode;
- /* Reset render target to framebuffer one. */
- render_target = &framebuffer.render_target;
-
/* Fill mode info details in framebuffer's render target. */
- render_target->mode_info.width = active_mode_info.x_resolution;
- render_target->mode_info.height = active_mode_info.y_resolution;
+ framebuffer.render_target.mode_info.width
+ = active_mode_info.x_resolution;
+ framebuffer.render_target.mode_info.height
+ = active_mode_info.y_resolution;
if (framebuffer.index_color_mode)
- render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+ framebuffer.render_target.mode_info.mode_type
+ = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
else
- render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-
- render_target->mode_info.bpp = active_mode_info.bits_per_pixel;
- render_target->mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
- render_target->mode_info.pitch = framebuffer.bytes_per_scan_line;
- render_target->mode_info.number_of_colors = 256; /* TODO: fix me. */
- render_target->mode_info.red_mask_size = active_mode_info.red_mask_size;
- render_target->mode_info.red_field_pos = active_mode_info.red_field_position;
- render_target->mode_info.green_mask_size = active_mode_info.green_mask_size;
- render_target->mode_info.green_field_pos = active_mode_info.green_field_position;
- render_target->mode_info.blue_mask_size = active_mode_info.blue_mask_size;
- 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);
+ framebuffer.render_target.mode_info.mode_type
+ = GRUB_VIDEO_MODE_TYPE_RGB;
+
+ framebuffer.render_target.mode_info.bpp = active_mode_info.bits_per_pixel;
+ framebuffer.render_target.mode_info.bytes_per_pixel
+ = framebuffer.bytes_per_pixel;
+ framebuffer.render_target.mode_info.pitch
+ = framebuffer.bytes_per_scan_line;
+ framebuffer.render_target.mode_info.number_of_colors
+ = 256; /* TODO: fix me. */
+ framebuffer.render_target.mode_info.red_mask_size
+ = active_mode_info.red_mask_size;
+ framebuffer.render_target.mode_info.red_field_pos
+ = active_mode_info.red_field_position;
+ framebuffer.render_target.mode_info.green_mask_size
+ = active_mode_info.green_mask_size;
+ framebuffer.render_target.mode_info.green_field_pos
+ = active_mode_info.green_field_position;
+ framebuffer.render_target.mode_info.blue_mask_size
+ = active_mode_info.blue_mask_size;
+ framebuffer.render_target.mode_info.blue_field_pos
+ = active_mode_info.blue_field_position;
+ framebuffer.render_target.mode_info.reserved_mask_size
+ = active_mode_info.rsvd_mask_size;
+ framebuffer.render_target.mode_info.reserved_field_pos
+ = active_mode_info.rsvd_field_position;
+
+ framebuffer.render_target.mode_info.blit_format
+ = grub_video_get_blit_format (&framebuffer.render_target.mode_info);
/* Reset viewport to match new mode. */
- render_target->viewport.x = 0;
- render_target->viewport.y = 0;
- render_target->viewport.width = active_mode_info.x_resolution;
- render_target->viewport.height = active_mode_info.y_resolution;
+ framebuffer.render_target.viewport.x = 0;
+ framebuffer.render_target.viewport.y = 0;
+ framebuffer.render_target.viewport.width = active_mode_info.x_resolution;
+ framebuffer.render_target.viewport.height = active_mode_info.y_resolution;
/* Set framebuffer pointer and mark it as non allocated. */
- render_target->is_allocated = 0;
- render_target->data = framebuffer.ptr;
+ framebuffer.render_target.is_allocated = 0;
+ framebuffer.render_target.data = framebuffer.ptr;
/* Copy default palette to initialize emulated palette. */
- for (i = 0;
- i < (sizeof (vga_colors)
- / sizeof (struct grub_vbe_palette_data));
- i++)
- {
- framebuffer.palette[i].r = vga_colors[i].red;
- framebuffer.palette[i].g = vga_colors[i].green;
- framebuffer.palette[i].b = vga_colors[i].blue;
- framebuffer.palette[i].a = 0xFF;
- }
+ grub_video_fb_set_palette (0, (sizeof (grub_video_fbstd_colors)
+ / sizeof (grub_video_fbstd_colors[0])),
+ grub_video_fbstd_colors);
+
+ /* Reset render target to framebuffer one. */
+ grub_video_fb_set_active_render_target (&framebuffer.render_target);
return GRUB_ERR_NONE;
}
@@ -569,21 +518,9 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
}
static grub_err_t
-grub_video_vbe_get_info (struct grub_video_mode_info *mode_info)
-{
- /* Copy mode info from active render target. */
- grub_memcpy (mode_info, &render_target->mode_info,
- sizeof (struct grub_video_mode_info));
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
grub_video_vbe_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data)
{
- unsigned int i;
-
if (framebuffer.index_color_mode)
{
/* TODO: Implement setting indexed color mode palette to hardware. */
@@ -595,28 +532,13 @@ grub_video_vbe_set_palette (unsigned int start, unsigned int count,
}
/* Then set color to emulated palette. */
- for (i = 0; (i < count) && ((i + start) < 256); i++)
- framebuffer.palette[start + i] = palette_data[i];
-
- return GRUB_ERR_NONE;
-}
-static grub_err_t
-grub_video_vbe_get_palette (unsigned int start, unsigned int count,
- struct grub_video_palette_data *palette_data)
-{
- unsigned int i;
-
- /* Assume that we know everything from index color palette. */
- for (i = 0; (i < count) && ((i + start) < 256); i++)
- palette_data[i] = framebuffer.palette[start + i];
-
- return GRUB_ERR_NONE;
+ return grub_video_fb_set_palette (start, count, palette_data);
}
-static grub_err_t
+grub_err_t
grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
- unsigned int width, unsigned int height)
+ unsigned int width, unsigned int height)
{
/* Make sure viewport is withing screen dimensions. If viewport was set
to be out of the region, mark its size as zero. */
@@ -637,832 +559,7 @@ grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
if (y + height > active_mode_info.y_resolution)
height = active_mode_info.y_resolution - y;
-
- render_target->viewport.x = x;
- render_target->viewport.y = y;
- render_target->viewport.width = width;
- render_target->viewport.height = height;
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_get_viewport (unsigned int *x, unsigned int *y,
- unsigned int *width, unsigned int *height)
-{
- if (x) *x = render_target->viewport.x;
- if (y) *y = render_target->viewport.y;
- if (width) *width = render_target->viewport.width;
- if (height) *height = render_target->viewport.height;
-
- return GRUB_ERR_NONE;
-}
-
-/* Maps color name to target optimized color format. */
-static grub_video_color_t
-grub_video_vbe_map_color (grub_uint32_t color_name)
-{
- /* TODO: implement color theme mapping code. */
-
- if (color_name < 256)
- {
- if ((render_target->mode_info.mode_type
- & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- return color_name;
- else
- {
- grub_video_color_t color;
-
- color = grub_video_vbe_map_rgb (framebuffer.palette[color_name].r,
- framebuffer.palette[color_name].g,
- framebuffer.palette[color_name].b);
-
- return color;
- }
- }
-
- return 0;
-}
-
-/* Maps RGB to target optimized color format. */
-grub_video_color_t
-grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green,
- grub_uint8_t blue)
-{
- if ((render_target->mode_info.mode_type
- & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- {
- int minindex = 0;
- int delta = 0;
- int tmp;
- int val;
- int i;
-
- /* Find best matching color. */
- for (i = 0; i < 256; i++)
- {
- val = framebuffer.palette[i].r - red;
- tmp = val * val;
- val = framebuffer.palette[i].g - green;
- tmp += val * val;
- val = framebuffer.palette[i].b - blue;
- tmp += val * val;
-
- if (i == 0)
- delta = tmp;
-
- if (tmp < delta)
- {
- delta = tmp;
- minindex = i;
- if (tmp == 0)
- break;
- }
- }
-
- return minindex;
- }
- else if ((render_target->mode_info.mode_type
- & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
- {
- if (red == render_target->mode_info.fg_red
- && green == render_target->mode_info.fg_green
- && blue == render_target->mode_info.fg_blue)
- return 1;
- else
- return 0;
- }
- else
- {
- grub_uint32_t value;
- grub_uint8_t alpha = 255; /* Opaque color. */
-
- red >>= 8 - render_target->mode_info.red_mask_size;
- green >>= 8 - render_target->mode_info.green_mask_size;
- blue >>= 8 - render_target->mode_info.blue_mask_size;
- alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
- value = red << render_target->mode_info.red_field_pos;
- value |= green << render_target->mode_info.green_field_pos;
- value |= blue << render_target->mode_info.blue_field_pos;
- value |= alpha << render_target->mode_info.reserved_field_pos;
-
- return value;
- }
-
-}
-
-/* Maps RGBA to target optimized color format. */
-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)
-{
- if ((render_target->mode_info.mode_type
- & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- /* No alpha available in index color modes, just use
- same value as in only RGB modes. */
- return grub_video_vbe_map_rgb (red, green, blue);
- else if ((render_target->mode_info.mode_type
- & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
- {
- if (red == render_target->mode_info.fg_red
- && green == render_target->mode_info.fg_green
- && blue == render_target->mode_info.fg_blue
- && alpha == render_target->mode_info.fg_alpha)
- return 1;
- else
- return 0;
- }
- else
- {
- grub_uint32_t value;
-
- red >>= 8 - render_target->mode_info.red_mask_size;
- green >>= 8 - render_target->mode_info.green_mask_size;
- blue >>= 8 - render_target->mode_info.blue_mask_size;
- alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
- value = red << render_target->mode_info.red_field_pos;
- value |= green << render_target->mode_info.green_field_pos;
- value |= blue << render_target->mode_info.blue_field_pos;
- value |= alpha << render_target->mode_info.reserved_field_pos;
-
- return value;
- }
-}
-
-/* Splits target optimized format to components. */
-grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color,
- grub_uint8_t *red, grub_uint8_t *green,
- grub_uint8_t *blue, grub_uint8_t *alpha)
-{
- struct grub_video_i386_vbeblit_info target_info;
-
- target_info.mode_info = &render_target->mode_info;
- target_info.data = render_target->data;
-
- grub_video_vbe_unmap_color_int (&target_info, color, red, green, blue, alpha);
-
- return GRUB_ERR_NONE;
-}
-
-/* Splits color in source format to components. */
-void
-grub_video_vbe_unmap_color_int (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)
-{
- struct grub_video_mode_info *mode_info;
- mode_info = source->mode_info;
-
- if ((mode_info->mode_type
- & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- {
- /* If we have an out-of-bounds color, return transparent black. */
- if (color > 255)
- {
- *red = 0;
- *green = 0;
- *blue = 0;
- *alpha = 0;
- return;
- }
-
- *red = framebuffer.palette[color].r;
- *green = framebuffer.palette[color].g;
- *blue = framebuffer.palette[color].b;
- *alpha = framebuffer.palette[color].a;
- return;
- }
- else if ((mode_info->mode_type
- & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
- {
- if (color & 1)
- {
- *red = mode_info->fg_red;
- *green = mode_info->fg_green;
- *blue = mode_info->fg_blue;
- *alpha = mode_info->fg_alpha;
- }
- else
- {
- *red = mode_info->bg_red;
- *green = mode_info->bg_green;
- *blue = mode_info->bg_blue;
- *alpha = mode_info->bg_alpha;
- }
- }
- else
- {
- grub_uint32_t tmp;
-
- /* Get red component. */
- tmp = color >> mode_info->red_field_pos;
- tmp &= (1 << mode_info->red_mask_size) - 1;
- tmp <<= 8 - mode_info->red_mask_size;
- tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
- *red = tmp & 0xFF;
-
- /* Get green component. */
- tmp = color >> mode_info->green_field_pos;
- tmp &= (1 << mode_info->green_mask_size) - 1;
- tmp <<= 8 - mode_info->green_mask_size;
- tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
- *green = tmp & 0xFF;
-
- /* Get blue component. */
- tmp = color >> mode_info->blue_field_pos;
- tmp &= (1 << mode_info->blue_mask_size) - 1;
- tmp <<= 8 - mode_info->blue_mask_size;
- tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
- *blue = tmp & 0xFF;
-
- /* Get alpha component. */
- if (source->mode_info->reserved_mask_size > 0)
- {
- tmp = color >> mode_info->reserved_field_pos;
- tmp &= (1 << mode_info->reserved_mask_size) - 1;
- tmp <<= 8 - mode_info->reserved_mask_size;
- tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
- }
- else
- /* If there is no alpha component, assume it opaque. */
- tmp = 255;
-
- *alpha = tmp & 0xFF;
- }
-}
-
-static grub_err_t
-grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
- unsigned int width, unsigned int height)
-{
- struct grub_video_i386_vbeblit_info target;
-
- /* Make sure there is something to do. */
- if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
- return GRUB_ERR_NONE;
- if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
- return GRUB_ERR_NONE;
-
- /* Do not allow drawing out of viewport. */
- if (x < 0)
- {
- width += x;
- x = 0;
- }
- if (y < 0)
- {
- height += y;
- y = 0;
- }
-
- if ((x + width) > render_target->viewport.width)
- width = render_target->viewport.width - x;
- if ((y + height) > render_target->viewport.height)
- height = render_target->viewport.height - y;
-
- /* Add viewport offset. */
- x += render_target->viewport.x;
- y += render_target->viewport.y;
-
- /* Use vbeblit_info to encapsulate rendering. */
- target.mode_info = &render_target->mode_info;
- target.data = render_target->data;
-
- /* Try to figure out more optimized version. Note that color is already
- mapped to target format so we can make assumptions based on that. */
- if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbefill_direct32 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
- else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- grub_video_i386_vbefill_direct32 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
- else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- grub_video_i386_vbefill_direct24 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
- else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
- {
- grub_video_i386_vbefill_direct16 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
- else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
- {
- grub_video_i386_vbefill_direct16 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
- else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbefill_direct8 (&target, color, x, y,
- width, height);
- return GRUB_ERR_NONE;
- }
-
- /* No optimized version found, use default (slow) filler. */
- grub_video_i386_vbefill (&target, color, x, y, width, height);
-
- return GRUB_ERR_NONE;
-}
-
-/* NOTE: This function assumes that given coordinates are within bounds of
- handled data. */
-static void
-common_blitter (struct grub_video_i386_vbeblit_info *target,
- struct grub_video_i386_vbeblit_info *source,
- enum grub_video_blit_operators oper, int x, int y,
- unsigned int width, unsigned int height,
- int offset_x, int offset_y)
-{
- if (oper == GRUB_VIDEO_BLIT_REPLACE)
- {
- /* Try to figure out more optimized version for replace operator. */
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- grub_video_i386_vbeblit_replace_directN (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
- grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbeblit_replace_index_RGBX8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
- grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- grub_video_i386_vbeblit_replace_directN (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbeblit_replace_index_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbeblit_replace_directN (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbeblit_replace_directN (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
-
- /* No optimized replace operator found, use default (slow) blitter. */
- grub_video_i386_vbeblit_replace (target, source, x, y, width, height,
- offset_x, offset_y);
- }
- else
- {
- /* Try to figure out more optimized blend operator. */
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
- grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbeblit_blend_index_RGBA8888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
- else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- /* Note: There is really no alpha information here, so blend is
- changed to replace. */
-
- if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
- {
- grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
- {
- grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
- {
- grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
- {
- grub_video_i386_vbeblit_replace_directN (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
- {
- grub_video_i386_vbeblit_replace_index_RGB888 (target, source,
- x, y, width, height,
- offset_x, offset_y);
- return;
- }
- }
-
- /* No optimized blend operation found, use default (slow) blitter. */
- grub_video_i386_vbeblit_blend (target, source, x, y, width, height,
- offset_x, offset_y);
- }
-}
-
-static grub_err_t
-grub_video_vbe_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)
-{
- struct grub_video_i386_vbeblit_info source;
- struct grub_video_i386_vbeblit_info target;
-
- /* Make sure there is something to do. */
- if ((width == 0) || (height == 0))
- return GRUB_ERR_NONE;
- if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
- return GRUB_ERR_NONE;
- if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
- return GRUB_ERR_NONE;
- if ((x + (int)bitmap->mode_info.width) < 0)
- return GRUB_ERR_NONE;
- if ((y + (int)bitmap->mode_info.height) < 0)
- return GRUB_ERR_NONE;
- if ((offset_x >= (int)bitmap->mode_info.width)
- || (offset_x + (int)width < 0))
- return GRUB_ERR_NONE;
- if ((offset_y >= (int)bitmap->mode_info.height)
- || (offset_y + (int)height < 0))
- return GRUB_ERR_NONE;
-
- /* If we have negative coordinates, optimize drawing to minimum. */
- if (offset_x < 0)
- {
- width += offset_x;
- x -= offset_x;
- offset_x = 0;
- }
-
- if (offset_y < 0)
- {
- height += offset_y;
- y -= offset_y;
- offset_y = 0;
- }
-
- if (x < 0)
- {
- width += x;
- offset_x -= x;
- x = 0;
- }
-
- if (y < 0)
- {
- height += y;
- offset_y -= y;
- y = 0;
- }
-
- /* Do not allow drawing out of viewport. */
- if ((x + width) > render_target->viewport.width)
- width = render_target->viewport.width - x;
- if ((y + height) > render_target->viewport.height)
- height = render_target->viewport.height - y;
-
- if ((offset_x + width) > bitmap->mode_info.width)
- width = bitmap->mode_info.width - offset_x;
- if ((offset_y + height) > bitmap->mode_info.height)
- height = bitmap->mode_info.height - offset_y;
-
- /* Limit drawing to source render target dimensions. */
- if (width > bitmap->mode_info.width)
- width = bitmap->mode_info.width;
-
- if (height > bitmap->mode_info.height)
- height = bitmap->mode_info.height;
-
- /* Add viewport offset. */
- x += render_target->viewport.x;
- y += render_target->viewport.y;
-
- /* Use vbeblit_info to encapsulate rendering. */
- source.mode_info = &bitmap->mode_info;
- source.data = bitmap->data;
- target.mode_info = &render_target->mode_info;
- target.data = render_target->data;
-
- /* Do actual blitting. */
- common_blitter (&target, &source, oper, x, y, width, height,
- offset_x, offset_y);
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_blit_render_target (struct grub_video_render_target *source,
- enum grub_video_blit_operators oper,
- int x, int y, int offset_x, int offset_y,
- unsigned int width, unsigned int height)
-{
- struct grub_video_i386_vbeblit_info source_info;
- struct grub_video_i386_vbeblit_info target_info;
-
- /* Make sure there is something to do. */
- if ((width == 0) || (height == 0))
- return GRUB_ERR_NONE;
- if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
- return GRUB_ERR_NONE;
- if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
- return GRUB_ERR_NONE;
- if ((x + (int)source->mode_info.width) < 0)
- return GRUB_ERR_NONE;
- if ((y + (int)source->mode_info.height) < 0)
- return GRUB_ERR_NONE;
- if ((offset_x >= (int)source->mode_info.width)
- || (offset_x + (int)width < 0))
- return GRUB_ERR_NONE;
- if ((offset_y >= (int)source->mode_info.height)
- || (offset_y + (int)height < 0))
- return GRUB_ERR_NONE;
-
- /* If we have negative coordinates, optimize drawing to minimum. */
- if (offset_x < 0)
- {
- width += offset_x;
- x -= offset_x;
- offset_x = 0;
- }
-
- if (offset_y < 0)
- {
- height += offset_y;
- y -= offset_y;
- offset_y = 0;
- }
-
- if (x < 0)
- {
- width += x;
- offset_x -= x;
- x = 0;
- }
-
- if (y < 0)
- {
- height += y;
- offset_y -= y;
- y = 0;
- }
-
- /* Do not allow drawing out of viewport. */
- if ((x + width) > render_target->viewport.width)
- width = render_target->viewport.width - x;
- if ((y + height) > render_target->viewport.height)
- height = render_target->viewport.height - y;
-
- if ((offset_x + width) > source->mode_info.width)
- width = source->mode_info.width - offset_x;
- if ((offset_y + height) > source->mode_info.height)
- height = source->mode_info.height - offset_y;
-
- /* Limit drawing to source render target dimensions. */
- if (width > source->mode_info.width)
- width = source->mode_info.width;
-
- if (height > source->mode_info.height)
- height = source->mode_info.height;
-
- /* Add viewport offset. */
- x += render_target->viewport.x;
- y += render_target->viewport.y;
-
- /* Use vbeblit_info to encapsulate rendering. */
- source_info.mode_info = &source->mode_info;
- source_info.data = source->data;
- target_info.mode_info = &render_target->mode_info;
- target_info.data = render_target->data;
-
- /* Do actual blitting. */
- common_blitter (&target_info, &source_info, oper, x, y, width, height,
- offset_x, offset_y);
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_scroll (grub_video_color_t color, int dx, int dy)
-{
- int width;
- int height;
- int src_x;
- int src_y;
- int dst_x;
- int dst_y;
-
- /* 1. Check if we have something to do. */
- if ((dx == 0) && (dy == 0))
- return GRUB_ERR_NONE;
-
- width = render_target->viewport.width - grub_abs (dx);
- height = render_target->viewport.height - grub_abs (dy);
-
- if (dx < 0)
- {
- src_x = render_target->viewport.x - dx;
- dst_x = render_target->viewport.x;
- }
- else
- {
- src_x = render_target->viewport.x;
- dst_x = render_target->viewport.x + dx;
- }
-
- if (dy < 0)
- {
- src_y = render_target->viewport.y - dy;
- dst_y = render_target->viewport.y;
- }
- else
- {
- src_y = render_target->viewport.y;
- dst_y = render_target->viewport.y + dy;
- }
-
- /* 2. Check if there is need to copy data. */
- if ((grub_abs (dx) < render_target->viewport.width)
- && (grub_abs (dy) < render_target->viewport.height))
- {
- /* 3. Move data in render target. */
- struct grub_video_i386_vbeblit_info target;
- grub_uint8_t *src;
- grub_uint8_t *dst;
- int j;
-
- target.mode_info = &render_target->mode_info;
- target.data = render_target->data;
-
- /* Check vertical direction of the move. */
- if (dy <= 0)
- /* 3a. Move data upwards. */
- for (j = 0; j < height; j++)
- {
- dst = grub_video_vbe_get_video_ptr (&target, dst_x, dst_y + j);
- src = grub_video_vbe_get_video_ptr (&target, src_x, src_y + j);
- grub_memmove (dst, src,
- width * target.mode_info->bytes_per_pixel);
- }
- else
- /* 3b. Move data downwards. */
- for (j = (height - 1); j >= 0; j--)
- {
- dst = grub_video_vbe_get_video_ptr (&target, dst_x, dst_y + j);
- src = grub_video_vbe_get_video_ptr (&target, src_x, src_y + j);
- grub_memmove (dst, src,
- width * target.mode_info->bytes_per_pixel);
- }
- }
-
- /* 4. Fill empty space with specified color. In this implementation
- there might be colliding areas but at the moment there is no need
- to optimize this. */
-
- /* 4a. Fill top & bottom parts. */
- if (dy > 0)
- grub_video_vbe_fill_rect (color, 0, 0, render_target->viewport.width, dy);
- else if (dy < 0)
- {
- if (render_target->viewport.height < grub_abs (dy))
- dy = -render_target->viewport.height;
-
- grub_video_vbe_fill_rect (color, 0, render_target->viewport.height + dy,
- render_target->viewport.width, -dy);
- }
-
- /* 4b. Fill left & right parts. */
- if (dx > 0)
- grub_video_vbe_fill_rect (color, 0, 0,
- dx, render_target->viewport.height);
- else if (dx < 0)
- {
- if (render_target->viewport.width < grub_abs (dx))
- dx = -render_target->viewport.width;
-
- grub_video_vbe_fill_rect (color, render_target->viewport.width + dx, 0,
- -dx, render_target->viewport.height);
- }
-
- return GRUB_ERR_NONE;
+ return grub_video_fb_set_viewport (x, y, width, height);
}
static grub_err_t
@@ -1473,126 +570,16 @@ grub_video_vbe_swap_buffers (void)
}
static grub_err_t
-grub_video_vbe_create_render_target (struct grub_video_render_target **result,
- unsigned int width, unsigned int height,
- unsigned int mode_type __attribute__ ((unused)))
-{
- struct grub_video_render_target *target;
- unsigned int size;
-
- /* Validate arguments. */
- if ((! result)
- || (width == 0)
- || (height == 0))
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "invalid argument given.");
-
- /* Allocate memory for render target. */
- target = grub_malloc (sizeof (struct grub_video_render_target));
- if (! target)
- return grub_errno;
-
- /* TODO: Implement other types too.
- Currently only 32bit render targets are supported. */
-
- /* Mark render target as allocated. */
- target->is_allocated = 1;
-
- /* Maximize viewport. */
- target->viewport.x = 0;
- target->viewport.y = 0;
- target->viewport.width = width;
- target->viewport.height = height;
-
- /* Setup render target format. */
- target->mode_info.width = width;
- target->mode_info.height = height;
- target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
- | GRUB_VIDEO_MODE_TYPE_ALPHA;
- target->mode_info.bpp = 32;
- target->mode_info.bytes_per_pixel = 4;
- target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
- target->mode_info.number_of_colors = 256; /* Emulated palette. */
- target->mode_info.red_mask_size = 8;
- target->mode_info.red_field_pos = 0;
- target->mode_info.green_mask_size = 8;
- target->mode_info.green_field_pos = 8;
- target->mode_info.blue_mask_size = 8;
- target->mode_info.blue_field_pos = 16;
- target->mode_info.reserved_mask_size = 8;
- target->mode_info.reserved_field_pos = 24;
-
- target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
-
- /* Calculate size needed for the data. */
- size = (width * target->mode_info.bytes_per_pixel) * height;
-
- target->data = grub_malloc (size);
- if (! target->data)
- {
- grub_free (target);
- return grub_errno;
- }
-
- /* Clear render target with black and maximum transparency. */
- grub_memset (target->data, 0, size);
-
- /* TODO: Add render target to render target list. */
-
- /* Save result to caller. */
- *result = target;
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_delete_render_target (struct grub_video_render_target *target)
-{
- /* If there is no target, then just return without error. */
- if (! target)
- return GRUB_ERR_NONE;
-
- /* TODO: Delist render target from render target list. */
-
- /* If this is software render target, free it's memory. */
- if (target->is_allocated)
- grub_free (target->data);
-
- /* Free render target. */
- grub_free (target);
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
{
if (target == GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER)
- {
- render_target = &framebuffer.render_target;
-
- return GRUB_ERR_NONE;
- }
+ return grub_video_fb_set_active_render_target (&framebuffer.render_target);
if (target == GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"double buffering not implemented yet.");
- if (! target->data)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "invalid render target given.");
-
- render_target = target;
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
-{
- *target = render_target;
-
- return GRUB_ERR_NONE;
+ return grub_video_fb_set_active_render_target (target);
}
static struct grub_video_adapter grub_video_vbe_adapter =
@@ -1602,24 +589,24 @@ static struct grub_video_adapter grub_video_vbe_adapter =
.init = grub_video_vbe_init,
.fini = grub_video_vbe_fini,
.setup = grub_video_vbe_setup,
- .get_info = grub_video_vbe_get_info,
+ .get_info = grub_video_fb_get_info,
.set_palette = grub_video_vbe_set_palette,
- .get_palette = grub_video_vbe_get_palette,
- .set_viewport = grub_video_vbe_set_viewport,
- .get_viewport = grub_video_vbe_get_viewport,
- .map_color = grub_video_vbe_map_color,
- .map_rgb = grub_video_vbe_map_rgb,
- .map_rgba = grub_video_vbe_map_rgba,
- .unmap_color = grub_video_vbe_unmap_color,
- .fill_rect = grub_video_vbe_fill_rect,
- .blit_bitmap = grub_video_vbe_blit_bitmap,
- .blit_render_target = grub_video_vbe_blit_render_target,
- .scroll = grub_video_vbe_scroll,
+ .get_palette = grub_video_fb_get_palette,
+ .set_viewport = grub_video_fb_set_viewport,
+ .get_viewport = grub_video_fb_get_viewport,
+ .map_color = grub_video_fb_map_color,
+ .map_rgb = grub_video_fb_map_rgb,
+ .map_rgba = grub_video_fb_map_rgba,
+ .unmap_color = grub_video_fb_unmap_color,
+ .fill_rect = grub_video_fb_fill_rect,
+ .blit_bitmap = grub_video_fb_blit_bitmap,
+ .blit_render_target = grub_video_fb_blit_render_target,
+ .scroll = grub_video_fb_scroll,
.swap_buffers = grub_video_vbe_swap_buffers,
- .create_render_target = grub_video_vbe_create_render_target,
- .delete_render_target = grub_video_vbe_delete_render_target,
+ .create_render_target = grub_video_fb_create_render_target,
+ .delete_render_target = grub_video_fb_delete_render_target,
.set_active_render_target = grub_video_vbe_set_active_render_target,
- .get_active_render_target = grub_video_vbe_get_active_render_target,
+ .get_active_render_target = grub_video_fb_get_active_render_target,
.next = 0
};
diff --git a/video/i386/pc/vbeblit.c b/video/i386/pc/vbeblit.c
deleted file mode 100644
index 4121bfe..0000000
--- a/video/i386/pc/vbeblit.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-/* 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
-#include
-#include
-#include
-#include
-#include
-
-/* Generic replacing blitter (slow). Works for every supported format. */
-void
-grub_video_i386_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y)
-{
- int i;
- int j;
- grub_uint8_t src_red;
- grub_uint8_t src_green;
- grub_uint8_t src_blue;
- grub_uint8_t src_alpha;
- grub_video_color_t src_color;
- grub_video_color_t dst_color;
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- src_color = get_pixel (src, i + offset_x, j + offset_y);
-
- grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green,
- &src_blue, &src_alpha);
-
- dst_color = grub_video_vbe_map_rgba (src_red, src_green,
- src_blue, src_alpha);
-
- set_pixel (dst, x + i, y + j, dst_color);
- }
- }
-}
-
-/* Block copy replacing blitter. Works with modes multiple of 8 bits. */
-void
-grub_video_i386_vbeblit_replace_directN (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y)
-{
- int j;
- grub_uint32_t *srcptr;
- grub_uint32_t *dstptr;
- int bpp;
-
- bpp = src->mode_info->bytes_per_pixel;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
-
- grub_memmove (dstptr, srcptr, width * bpp);
- }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGRX8888. */
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- int i;
- int j;
- grub_uint8_t *srcptr;
- grub_uint8_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint8_t r = *srcptr++;
- grub_uint8_t g = *srcptr++;
- grub_uint8_t b = *srcptr++;
- grub_uint8_t a = *srcptr++;
-
- *dstptr++ = b;
- *dstptr++ = g;
- *dstptr++ = r;
- *dstptr++ = a;
- }
-
- srcptr += srcrowskip;
- dstptr += dstrowskip;
- }
-}
-
-/* Optimized replacing blitter for RGB888 to BGRX8888. */
-void
-grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- int i;
- int j;
- grub_uint8_t *srcptr;
- grub_uint8_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint8_t r = *srcptr++;
- grub_uint8_t g = *srcptr++;
- grub_uint8_t b = *srcptr++;
-
- *dstptr++ = b;
- *dstptr++ = g;
- *dstptr++ = r;
-
- /* Set alpha component as opaque. */
- *dstptr++ = 255;
- }
-
- srcptr += srcrowskip;
- dstptr += dstrowskip;
- }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGR888. */
-void
-grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- grub_uint32_t *srcptr;
- grub_uint8_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
- int i;
- int j;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint32_t color;
- grub_uint8_t sr;
- grub_uint8_t sg;
- grub_uint8_t sb;
-
- color = *srcptr++;
-
- sr = (color >> 0) & 0xFF;
- sg = (color >> 8) & 0xFF;
- sb = (color >> 16) & 0xFF;
-
- *dstptr++ = sb;
- *dstptr++ = sg;
- *dstptr++ = sr;
- }
-
- srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
- dstptr += dstrowskip;
- }
-}
-
-/* Optimized replacing blitter for RGB888 to BGR888. */
-void
-grub_video_i386_vbeblit_replace_BGR888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- int i;
- int j;
- grub_uint8_t *srcptr;
- grub_uint8_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint8_t r = *srcptr++;
- grub_uint8_t g = *srcptr++;
- grub_uint8_t b = *srcptr++;
-
- *dstptr++ = b;
- *dstptr++ = g;
- *dstptr++ = r;
- }
-
- srcptr += srcrowskip;
- dstptr += dstrowskip;
- }
-}
-
-/* Optimized replacing blitter for RGB888 to RGBX8888. */
-void
-grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j);
-
- for (i = 0; i < width; i++)
- {
- sr = *srcptr++;
- sg = *srcptr++;
- sb = *srcptr++;
-
- /* Set alpha as opaque. */
- color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
-
- *dstptr++ = color;
- }
- }
-}
-
-/* Optimized replacing blitter for RGBX8888 to RGB888. */
-void
-grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
-
- for (i = 0; i < width; i++)
- {
- color = *srcptr++;
-
- sr = (color >> 0) & 0xFF;
- sg = (color >> 8) & 0xFF;
- sb = (color >> 16) & 0xFF;
-
- *dstptr++ = sr;
- *dstptr++ = sg;
- *dstptr++ = sb;
- }
- }
-}
-
-/* Optimized replacing blitter for RGBX8888 to indexed color. */
-void
-grub_video_i386_vbeblit_replace_index_RGBX8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j);
-
- for (i = 0; i < width; i++)
- {
- color = *srcptr++;
-
- sr = (color >> 0) & 0xFF;
- sg = (color >> 8) & 0xFF;
- sb = (color >> 16) & 0xFF;
-
- color = grub_video_vbe_map_rgb(sr, sg, sb);
- *dstptr++ = color & 0xFF;
- }
- }
-}
-
-/* Optimized replacing blitter for RGB888 to indexed color. */
-void
-grub_video_i386_vbeblit_replace_index_RGB888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint8_t *)get_data_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;
- }
- }
-}
-
-/* Generic blending blitter. Works for every supported format. */
-void
-grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y, int width, int height,
- int offset_x, int offset_y)
-{
- int i;
- int j;
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint8_t src_red;
- grub_uint8_t src_green;
- grub_uint8_t src_blue;
- grub_uint8_t src_alpha;
- grub_uint8_t dst_red;
- grub_uint8_t dst_green;
- grub_uint8_t dst_blue;
- grub_uint8_t dst_alpha;
- grub_video_color_t src_color;
- grub_video_color_t dst_color;
-
- src_color = get_pixel (src, i + offset_x, j + offset_y);
- grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green,
- &src_blue, &src_alpha);
-
- if (src_alpha == 0)
- continue;
-
- if (src_alpha == 255)
- {
- dst_color = grub_video_vbe_map_rgba (src_red, src_green,
- src_blue, src_alpha);
- set_pixel (dst, x + i, y + j, dst_color);
- continue;
- }
-
- dst_color = get_pixel (dst, x + i, y + j);
-
- grub_video_vbe_unmap_color_int (dst, dst_color, &dst_red,
- &dst_green, &dst_blue, &dst_alpha);
-
- dst_red = (((src_red * src_alpha)
- + (dst_red * (255 - src_alpha))) / 255);
- dst_green = (((src_green * src_alpha)
- + (dst_green * (255 - src_alpha))) / 255);
- dst_blue = (((src_blue * src_alpha)
- + (dst_blue * (255 - src_alpha))) / 255);
-
- dst_alpha = src_alpha;
- dst_color = grub_video_vbe_map_rgba (dst_red, dst_green, dst_blue,
- dst_alpha);
-
- set_pixel (dst, x + i, y + j, dst_color);
- }
- }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGRA8888. */
-void
-grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- grub_uint32_t *srcptr;
- grub_uint32_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
- int i;
- int j;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint32_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint32_t color;
- unsigned int sr;
- unsigned int sg;
- unsigned int sb;
- unsigned int a;
- unsigned int dr;
- unsigned int dg;
- unsigned int db;
-
- color = *srcptr++;
-
- a = color >> 24;
-
- if (a == 0)
- {
- /* Skip transparent source pixels. */
- dstptr++;
- continue;
- }
-
- sr = (color >> 0) & 0xFF;
- sg = (color >> 8) & 0xFF;
- sb = (color >> 16) & 0xFF;
-
- if (a == 255)
- {
- /* Opaque pixel shortcut. */
- dr = sr;
- dg = sg;
- db = sb;
- }
- else
- {
- /* General pixel color blending. */
- color = *dstptr;
-
- dr = (color >> 16) & 0xFF;
- dr = (dr * (255 - a) + sr * a) / 255;
- dg = (color >> 8) & 0xFF;
- dg = (dg * (255 - a) + sg * a) / 255;
- db = (color >> 0) & 0xFF;
- db = (db * (255 - a) + sb * a) / 255;
- }
-
- color = (a << 24) | (dr << 16) | (dg << 8) | db;
-
- *dstptr++ = color;
- }
-
- srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
- dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
- }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGR888. */
-void
-grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *src,
- int x, int y,
- int width, int height,
- int offset_x, int offset_y)
-{
- grub_uint32_t *srcptr;
- grub_uint8_t *dstptr;
- unsigned int srcrowskip;
- unsigned int dstrowskip;
- int i;
- int j;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
- dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y);
- dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- grub_uint32_t color;
- unsigned int sr;
- unsigned int sg;
- unsigned int sb;
- unsigned int a;
- unsigned int dr;
- unsigned int dg;
- unsigned int db;
-
- color = *srcptr++;
-
- a = color >> 24;
-
- if (a == 0)
- {
- /* Skip transparent source pixels. */
- dstptr += 3;
- continue;
- }
-
- sr = (color >> 0) & 0xFF;
- sg = (color >> 8) & 0xFF;
- sb = (color >> 16) & 0xFF;
-
- if (a == 255)
- {
- /* Opaque pixel shortcut. */
- dr = sr;
- dg = sg;
- db = sb;
- }
- else
- {
- /* General pixel color blending. */
- color = *dstptr;
-
- db = dstptr[0];
- db = (db * (255 - a) + sb * a) / 255;
- dg = dstptr[1];
- dg = (dg * (255 - a) + sg * a) / 255;
- dr = dstptr[2];
- dr = (dr * (255 - a) + sr * a) / 255;
- }
-
- *dstptr++ = db;
- *dstptr++ = dg;
- *dstptr++ = dr;
- }
-
- srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
- dstptr += dstrowskip;
- }
-}
-
-/* Optimized blending blitter for RGBA888 to RGBA8888. */
-void
-grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint32_t *)get_data_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;
- }
- }
-}
-
-/* Optimized blending blitter for RGBA8888 to RGB888. */
-void
-grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint8_t *)get_data_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;
- }
- }
-}
-
-/* Optimized blending blitter for RGBA8888 to indexed color. */
-void
-grub_video_i386_vbeblit_blend_index_RGBA8888 (struct grub_video_i386_vbeblit_info *dst,
- struct grub_video_i386_vbeblit_info *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;
-
- for (j = 0; j < height; j++)
- {
- srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y);
- dstptr = (grub_uint8_t *)get_data_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_int (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;
- }
- }
-}
diff --git a/video/i386/pc/vbefill.c b/video/i386/pc/vbefill.c
deleted file mode 100644
index 3a98a71..0000000
--- a/video/i386/pc/vbefill.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-/* 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
-#include
-#include
-#include
-#include
-
-/* Generic filler that works for every supported mode. */
-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;
-
- for (j = 0; j < height; j++)
- for (i = 0; i < width; i++)
- set_pixel (dst, x+i, y+j, color);
-}
-
-/* Optimized filler for direct color 32 bit modes. It is assumed that color
- is already mapped to destination format. */
-void
-grub_video_i386_vbefill_direct32 (struct grub_video_i386_vbeblit_info *dst,
- grub_video_color_t color, int x, int y,
- int width, int height)
-{
- int i;
- int j;
- grub_uint32_t *dstptr;
- grub_size_t rowskip;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- /* Get the start address. */
- dstptr = (grub_uint32_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- *dstptr++ = color;
-
- /* Advance the dest pointer to the right location on the next line. */
- dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
- }
-}
-
-/* Optimized filler for direct color 24 bit modes. It is assumed that color
- is already mapped to destination format. */
-void
-grub_video_i386_vbefill_direct24 (struct grub_video_i386_vbeblit_info *dst,
- grub_video_color_t color, int x, int y,
- int width, int height)
-{
- int i;
- int j;
- grub_size_t rowskip;
- grub_uint8_t *dstptr;
- grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
- grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
- grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- /* Get the start address. */
- dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- *dstptr++ = fill0;
- *dstptr++ = fill1;
- *dstptr++ = fill2;
- }
-
- /* Advance the dest pointer to the right location on the next line. */
- dstptr += rowskip;
- }
-}
-
-/* Optimized filler for direct color 16 bit modes. It is assumed that color
- is already mapped to destination format. */
-void
-grub_video_i386_vbefill_direct16 (struct grub_video_i386_vbeblit_info *dst,
- grub_video_color_t color, int x, int y,
- int width, int height)
-{
- int i;
- int j;
- grub_size_t rowskip;
- grub_uint8_t *dstptr;
- grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
- grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- /* Get the start address. */
- dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- {
- *dstptr++ = fill0;
- *dstptr++ = fill1;
- }
-
- /* Advance the dest pointer to the right location on the next line. */
- dstptr += rowskip;
- }
-}
-
-/* Optimized filler for index color. It is assumed that color
- is already mapped to destination format. */
-void
-grub_video_i386_vbefill_direct8 (struct grub_video_i386_vbeblit_info *dst,
- grub_video_color_t color, int x, int y,
- int width, int height)
-{
- int i;
- int j;
- grub_size_t rowskip;
- grub_uint8_t *dstptr;
- grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
-
- /* Calculate the number of bytes to advance from the end of one line
- to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
- /* Get the start address. */
- dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y);
-
- for (j = 0; j < height; j++)
- {
- for (i = 0; i < width; i++)
- *dstptr++ = fill;
-
- /* Advance the dest pointer to the right location on the next line. */
- dstptr += rowskip;
- }
-}
diff --git a/video/i386/pc/vbeutil.c b/video/i386/pc/vbeutil.c
deleted file mode 100644
index 1040dc9..0000000
--- a/video/i386/pc/vbeutil.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see .
- */
-
-#include
-#include
-#include
-
-grub_uint8_t *
-get_data_ptr (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y)
-{
- grub_uint8_t *ptr = 0;
-
- switch (source->mode_info->bpp)
- {
- case 32:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 4;
- break;
-
- case 24:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 3;
- break;
-
- case 16:
- case 15:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x * 2;
- break;
-
- case 8:
- ptr = (grub_uint8_t *)source->data
- + y * source->mode_info->pitch
- + x;
- break;
-
- case 1:
- /* For 1-bit bitmaps, addressing needs to be done at the bit level
- and it doesn't make sense, in general, to ask for a pointer
- to a particular pixel's data. */
- break;
- }
-
- return ptr;
-}
-
-grub_video_color_t
-get_pixel (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y)
-{
- grub_video_color_t color = 0;
-
- switch (source->mode_info->bpp)
- {
- case 32:
- color = *(grub_uint32_t *)get_data_ptr (source, x, y);
- break;
-
- case 24:
- {
- grub_uint8_t *ptr;
- ptr = get_data_ptr (source, x, y);
- color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
- }
- break;
-
- case 16:
- case 15:
- color = *(grub_uint16_t *)get_data_ptr (source, x, y);
- break;
-
- case 8:
- color = *(grub_uint8_t *)get_data_ptr (source, x, y);
- break;
-
- case 1:
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
- {
- int bit_index = y * source->mode_info->width + x;
- grub_uint8_t *ptr = (grub_uint8_t *)source->data
- + bit_index / 8;
- int bit_pos = 7 - bit_index % 8;
- color = (*ptr >> bit_pos) & 0x01;
- }
- break;
-
- default:
- break;
- }
-
- return color;
-}
-
-void
-set_pixel (struct grub_video_i386_vbeblit_info *source,
- unsigned int x, unsigned int y, grub_video_color_t color)
-{
- switch (source->mode_info->bpp)
- {
- case 32:
- {
- grub_uint32_t *ptr;
-
- ptr = (grub_uint32_t *)get_data_ptr (source, x, y);
-
- *ptr = color;
- }
- break;
-
- case 24:
- {
- grub_uint8_t *ptr;
- grub_uint8_t *colorptr = (grub_uint8_t *)&color;
-
- ptr = get_data_ptr (source, x, y);
-
- ptr[0] = colorptr[0];
- ptr[1] = colorptr[1];
- ptr[2] = colorptr[2];
- }
- break;
-
- case 16:
- case 15:
- {
- grub_uint16_t *ptr;
-
- ptr = (grub_uint16_t *)get_data_ptr (source, x, y);
-
- *ptr = (grub_uint16_t) (color & 0xFFFF);
- }
- break;
-
- case 8:
- {
- grub_uint8_t *ptr;
-
- ptr = (grub_uint8_t *)get_data_ptr (source, x, y);
-
- *ptr = (grub_uint8_t) (color & 0xFF);
- }
- break;
-
- case 1:
- if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
- {
- int bit_index = y * source->mode_info->width + x;
- grub_uint8_t *ptr = (grub_uint8_t *)source->data
- + bit_index / 8;
- int bit_pos = 7 - bit_index % 8;
- *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
- }
- break;
-
- default:
- break;
- }
-}
diff --git a/video/video.c b/video/video.c
index c22947b..8271d79 100644
--- a/video/video.c
+++ b/video/video.c
@@ -654,6 +654,8 @@ grub_video_set_mode (char *modestring,
if (err != GRUB_ERR_NONE)
{
p->fini ();
+ grub_dprintf ("video", "Failed to setup mode %dx%d (%x) on %s\n",
+ width, height, flags, p->name);
grub_errno = GRUB_ERR_NONE;
continue;
}
@@ -662,6 +664,8 @@ grub_video_set_mode (char *modestring,
if (err != GRUB_ERR_NONE)
{
p->fini ();
+ grub_dprintf ("video", "Failed to get info: %dx%d (%x) on %s\n",
+ width, height, flags, p->name);
grub_errno = GRUB_ERR_NONE;
continue;
}