* Fwd: [PATCH 1/2] Framebuffer split
[not found] ` <d7ead6de0907230250h13df5d6du29ce32ef0e187123@mail.gmail.com>
@ 2009-07-23 9:52 ` Vladimir 'phcoder' Serbinenko
2009-07-23 23:41 ` Pavel Roskin
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-07-23 9:52 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 319 bytes --]
Hello. Here is a framebuffer split which has already been discussed.
This patch contains some code by Collin D Bennett in addition to my
code. Sorry for compression but maillist server doesn't accept it otherwise
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: fb.diff.gz --]
[-- Type: application/x-gzip, Size: 27336 bytes --]
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-23 9:52 ` Fwd: [PATCH 1/2] Framebuffer split Vladimir 'phcoder' Serbinenko
@ 2009-07-23 23:41 ` Pavel Roskin
2009-07-25 9:57 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Pavel Roskin @ 2009-07-23 23:41 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, 2009-07-23 at 11:52 +0200, Vladimir 'phcoder' Serbinenko wrote:
> Hello. Here is a framebuffer split which has already been discussed.
> This patch contains some code by Collin D Bennett in addition to my
> code. Sorry for compression but maillist server doesn't accept it otherwise
Please include an uncompressed ChangeLog entry. Even though the issue
was discussed, it would help if you include a description of the changes
to simplify reviewing. You can copy a previously posted description.
grub_video_vbe_set_viewport and grub_video_vbe_get_info_and_fini need to
be declared static to avoid compiler warnings.
Apart from that, no warnings are introduced.
Please don't add trailing whitespace. Since you are using git, you can
easily check it with STGit by running "stg edit -d".
grub_video_vbe_get_info_and_fini strikes as a weird name. The comment
says:
/* Get information about active video mode. */
Likewise, all occurrences of "get_info_and_fini" should probably be
replaced with something more descriptive.
--
Regards,
Pavel Roskin
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-23 23:41 ` Pavel Roskin
@ 2009-07-25 9:57 ` Vladimir 'phcoder' Serbinenko
2009-07-26 22:06 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-07-25 9:57 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 1528 bytes --]
On Fri, Jul 24, 2009 at 1:41 AM, Pavel Roskin<proski@gnu.org> wrote:
> On Thu, 2009-07-23 at 11:52 +0200, Vladimir 'phcoder' Serbinenko wrote:
>> Hello. Here is a framebuffer split which has already been discussed.
>> This patch contains some code by Collin D Bennett in addition to my
>> code. Sorry for compression but maillist server doesn't accept it otherwise
>
> Please include an uncompressed ChangeLog entry.
Coming when I have a bit more time
> grub_video_vbe_set_viewport and grub_video_vbe_get_info_and_fini need to
> be declared static to avoid compiler warnings.
>
Done
> Apart from that, no warnings are introduced.
>
> Please don't add trailing whitespace. Since you are using git, you can
> easily check it with STGit by running "stg edit -d".
>
I used git diff --color but few whitespace slipped in
> grub_video_vbe_get_info_and_fini strikes as a weird name. The comment
> says:
>
> /* Get information about active video mode. */
>
> Likewise, all occurrences of "get_info_and_fini" should probably be
> replaced with something more descriptive.
>
I don't see which comment you refer to but I added a comment to
grub_video_get_info_and_fini explaining why it's needed
> --
> Regards,
> Pavel Roskin
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: framebuf.diff.gz --]
[-- Type: application/x-gzip, Size: 27453 bytes --]
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-25 9:57 ` Vladimir 'phcoder' Serbinenko
@ 2009-07-26 22:06 ` Vladimir 'phcoder' Serbinenko
2009-07-28 17:50 ` Robert Millan
2009-08-01 15:01 ` Robert Millan
0 siblings, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-07-26 22:06 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 4132 bytes --]
Removed parts which are purely moving code around (of course it will
be restored on commit).
2009-07-26 Vladimir Serbinenko <phcoder@gmail.com>
2009-07-26 Colin D Bennett <colin@gibibit.com>
Framebuffer split and double buffering support.
* commands/i386/pc/vbetest.c (grub_cmd_vbetest): Restore video
subsystem at the end.
* commands/i386/pc/videotest.c (grub_cmd_videotest): Swap doublebuffers.
* conf/common.rmk (pkglib_MODULES): Add video_fb.mod.
(video_fb_mod_SOURCES): New variable.
(video_fb_mod_CFLAGS): Likewise.
(video_fb_mod_LDFLAGS): Likewise.
* conf/i386-pc.rmk (vbe_mod_SOURCES): Remove video/i386/pc/vbeblit.c,
video/i386/pc/vbefill.c and video/i386/pc/vbeutil.c.
* video/i386/pc/vbeblit.c: Moved from here ...
* video/fb/fbblit.c: ..here. Replaced 'vbe' with 'fb'.
* video/i386/pc/vbefill.c: Moved from here ...
* video/fb/fbfill.c: ..here. Replaced 'vbe' with 'fb'.
* video/i386/pc/vbeutil.c: Moved from here ...
* video/fb/fbutil.c: ..here. Replaced 'vbe' with 'fb'.
* include/grub/i386/pc/vbeblit.h: Moved from here ...
* include/grub/fbblit.h: ... here. Replaced 'vbe' with 'fb'.
* include/grub/i386/pc/vbefill.h: Moved from here ...
* include/grub/fbfill.h: ... here. Replaced 'vbe' with 'fb'.
* include/grub/i386/pc/vbeutil.h: Moved from here ...
* include/grub/fbutil.h: ... here. Replaced 'vbe' with 'fb'.
* include/grub/i386/pc/vbe.h: Moved framebuffer part ...
* include/grub/video_fb.h: ... here. Replaced 'vbe' with 'fb'.
* include/grub/video.h (GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER): Removed.
(GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER): Likewise.
(grub_video_rect): New type.
(grub_video_adapter): Added get_info_and_fini and
enable_double_buffering.
(grub_video_get_info_and_fini): New prototype.
(grub_video_enable_double_buffering): Likewise.
(grub_video_set_mode): make modestring const char *.
* loader/i386/linux.c (grub_linux_setup_video): Use
grub_video_get_info_and_fini.
(grub_linux_boot): Move modesetting just before booting.
* loader/i386/pc/xnu.c (grub_xnu_set_video): Use
grub_video_get_info_and_fini.
* term/gfxterm.c (redraw_screen_rect): Support double buffering.
(dirty_region_redraw): Likewise.
(scroll_up): Likewise.
(grub_gfxterm_putchar): Likewise.
* video/i386/pc/vbe.c: Moved framebuffer part ...
* video/fb/video_fb.c: ... here. Replaced 'vbe' with 'fb'.
* video/i386/pc/vbe.c (doublebuf_state): New variable.
(double_buffering_init): New prototype.
(grub_vbe_set_video_mode): Use grub_video_fbstd_colors and
grub_video_fb_set_palette.
(grub_video_vbe_init): Initialise double buffering and use
grub_video_fb_init.
(grub_video_vbe_fini): Finalise double buffering and use
grub_video_fb_fini.
(grub_video_vbe_setup): Use framebuffer.render_target instead of
render_target and use grub_video_fb_set_active_render_target and
grub_video_fb_set_palette.
(doublebuf_pageflipping_commit): New function.
(doublebuf_pageflipping_update_screen): Likewise.
(doublebuf_blit_update_screen): Likewise.
(doublebuf_blit_init): Likewise.
(doublebuf_null_update_screen): Likewise.
(doublebuf_null_destroy): Likewise.
(doublebuf_null_init): Likewise.
(double_buffering_init): Likewise.
(grub_video_vbe_enable_double_buffering): Likewise.
(grub_video_vbe_set_palette): Use grub_video_fb_set_palette.
(grub_video_vbe_set_viewport): Use grub_video_fb_set_viewport.
(grub_video_vbe_swap_buffers): Use update_screen.
(grub_video_vbe_adapter): Use framebuffer.
* video/video.c (grub_video_get_info_and_fini): New function.
(grub_video_set_mode): Make modestring const char * and use
double buffering.
(GRUB_MOD_INIT(video_video)): Don't set variables to 0 since these
values are already initialised.
>> --
>> Regards,
>> Pavel Roskin
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: framebuf.diff --]
[-- Type: text/plain, Size: 108056 bytes --]
diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c
index 3cbc301..314320d 100644
--- a/commands/i386/pc/vbetest.c
+++ b/commands/i386/pc/vbetest.c
@@ -155,6 +155,8 @@ grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
grub_getkey ();
+ grub_video_restore ();
+
/* Restore old video mode. */
grub_vbe_set_video_mode (old_mode, 0);
diff --git a/commands/videotest.c b/commands/videotest.c
index 6fe4b9b..c4b315a 100644
--- a/commands/videotest.c
+++ b/commands/videotest.c
@@ -160,6 +160,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
0, 0, width, height);
}
+ grub_video_swap_buffers ();
+
grub_getkey ();
grub_video_delete_render_target (text_layer);
diff --git a/conf/common.rmk b/conf/common.rmk
index 032517f..5e93302 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -535,13 +535,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 798aee2..5b7b8c0 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -273,8 +273,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/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 <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/video.h>
+#include <grub/video_fb.h>
/* 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/video.h b/include/grub/video.h
index c98731d..ad6dc6d 100644
--- a/include/grub/video.h
+++ b/include/grub/video.h
@@ -48,10 +48,10 @@ struct grub_video_bitmap;
#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK 0x0000ff00
#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS 8
-/* Defined predefined render targets. */
-#define GRUB_VIDEO_RENDER_TARGET_DISPLAY ((struct grub_video_render_target *) 0)
-#define GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER ((struct grub_video_render_target *) 0)
-#define GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER ((struct grub_video_render_target *) 1)
+/* The basic render target representing the whole display. This always
+ renders to the back buffer when double-buffering is in use. */
+#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
+ ((struct grub_video_render_target *) 0)
/* Defined blitting formats. */
enum grub_video_blit_format
@@ -161,6 +161,16 @@ struct grub_video_palette_data
grub_uint8_t a; /* Reserved bits value (0-255). */
};
+/* A 2D rectangle type. */
+struct grub_video_rect
+{
+ int x;
+ int y;
+ int width;
+ int height;
+};
+typedef struct grub_video_rect grub_video_rect_t;
+
struct grub_video_adapter
{
/* The video adapter name. */
@@ -177,6 +187,9 @@ struct grub_video_adapter
grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
+ grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
+ void **framebuffer);
+
grub_err_t (*set_palette) (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data);
@@ -218,6 +231,8 @@ struct grub_video_adapter
grub_err_t (*swap_buffers) (void);
+ grub_err_t (*enable_double_buffering) (int enable);
+
grub_err_t (*create_render_target) (struct grub_video_render_target **result,
unsigned int width, unsigned int height,
unsigned int mode_type);
@@ -241,6 +256,14 @@ grub_err_t grub_video_restore (void);
grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info);
+/* Framebuffer address may change as a part of normal operation
+ (e.g. double buffering). That's why you need to stop video subsystem to be
+ sure that framebuffer address doesn't change. To ensure this abstraction
+ grub_video_get_info_and_fini is the only function supplying framebuffer
+ address. */
+grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuffer);
+
enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
@@ -286,6 +309,8 @@ grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy);
grub_err_t grub_video_swap_buffers (void);
+grub_err_t grub_video_enable_double_buffering (int enable);
+
grub_err_t grub_video_create_render_target (struct grub_video_render_target **result,
unsigned int width,
unsigned int height,
@@ -297,7 +322,7 @@ grub_err_t grub_video_set_active_render_target (struct grub_video_render_target
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
-grub_err_t grub_video_set_mode (char *modestring,
+grub_err_t grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info));
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
new file mode 100644
index 0000000..9ae4101
--- /dev/null
+++ b/include/grub/video_fb.h
@@ -0,0 +1,137 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+
+/* 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;
+};
+
+#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
+extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
+
+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 78fa848..9a7a8f7 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -31,9 +31,7 @@
#include <grub/term.h>
#include <grub/cpu/linux.h>
#include <grub/video.h>
-/* FIXME: the definition of `struct grub_video_render_target' is
- VBE-specific. */
-#include <grub/i386/pc/vbe.h>
+#include <grub/video_fb.h>
#include <grub/command.h>
#define GRUB_LINUX_CL_OFFSET 0x1000
@@ -403,14 +401,11 @@ 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;
+ void *framebuffer;
int ret;
- ret = grub_video_get_info (&mode_info);
- if (ret)
- return 1;
+ ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
- ret = grub_video_get_active_render_target (&render_target);
if (ret)
return 1;
@@ -419,7 +414,7 @@ grub_linux_setup_video (struct linux_kernel_params *params)
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
- params->lfb_base = (grub_size_t) render_target->data;
+ params->lfb_base = (grub_size_t) framebuffer;
params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16;
params->red_mask_size = mode_info.red_mask_size;
@@ -449,41 +444,6 @@ grub_linux_boot (void)
params = real_mode_mem;
- modevar = grub_env_get ("gfxpayload");
-
- /* Now all graphical modes are acceptable.
- May change in future if we have modes without framebuffer. */
- if (modevar && *modevar != 0)
- {
- tmp = grub_malloc (grub_strlen (modevar)
- + sizeof (DEFAULT_VIDEO_MODE) + 1);
- if (! tmp)
- return grub_errno;
- grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
- err = grub_video_set_mode (tmp, 0);
- grub_free (tmp);
- }
-#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
- else
- err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
-#endif
-
- if (err)
- {
- grub_print_error ();
- grub_printf ("Booting however\n");
- grub_errno = GRUB_ERR_NONE;
- }
-
- if (! grub_linux_setup_video (params))
- params->have_vga = GRUB_VIDEO_TYPE_VLFB;
- else
- {
- params->have_vga = GRUB_VIDEO_TYPE_TEXT;
- params->video_width = 80;
- params->video_height = 25;
- }
-
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
(unsigned) params->code32_start,
(unsigned long) &(idt_desc.limit),
@@ -534,6 +494,41 @@ grub_linux_boot (void)
grub_mmap_iterate (hook);
params->mmap_size = e820_num;
+ modevar = grub_env_get ("gfxpayload");
+
+ /* Now all graphical modes are acceptable.
+ May change in future if we have modes without framebuffer. */
+ if (modevar && *modevar != 0)
+ {
+ tmp = grub_malloc (grub_strlen (modevar)
+ + sizeof (DEFAULT_VIDEO_MODE) + 1);
+ if (! tmp)
+ return grub_errno;
+ grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+ err = grub_video_set_mode (tmp, 0);
+ grub_free (tmp);
+ }
+#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
+ else
+ err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
+#endif
+
+ if (err)
+ {
+ grub_print_error ();
+ grub_printf ("Booting however\n");
+ grub_errno = GRUB_ERR_NONE;
+ }
+
+ if (! grub_linux_setup_video (params))
+ params->have_vga = GRUB_VIDEO_TYPE_VLFB;
+ else
+ {
+ params->have_vga = GRUB_VIDEO_TYPE_TEXT;
+ params->video_width = 80;
+ params->video_height = 25;
+ }
+
/* Initialize these last, because terminal position could be affected by printfs above. */
if (params->have_vga == GRUB_VIDEO_TYPE_TEXT)
{
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
index 037a713..69a9405 100644
--- a/loader/i386/pc/xnu.c
+++ b/loader/i386/pc/xnu.c
@@ -21,8 +21,7 @@
#include <grub/xnu.h>
#include <grub/mm.h>
#include <grub/cpu/xnu.h>
-#include <grub/machine/vbe.h>
-#include <grub/machine/vga.h>
+#include <grub/video_fb.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -43,10 +42,10 @@ 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;
int ret;
int x,y;
char *tmp, *modevar;
+ void *framebuffer;
grub_err_t err;
modevar = grub_env_get ("gfxpayload");
@@ -67,11 +66,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
if (err)
return err;
- ret = grub_video_get_info (&mode_info);
- 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_info_and_fini (&mode_info, &framebuffer);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
@@ -102,7 +97,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
- params->lfb_base = PTR_TO_UINT32 (render_target->data);
+ params->lfb_base = PTR_TO_UINT32 (framebuffer);
params->lfb_mode = grub_xnu_bitmap
? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
diff --git a/term/gfxterm.c b/term/gfxterm.c
index 61cf0e7..775bc60 100644
--- a/term/gfxterm.c
+++ b/term/gfxterm.c
@@ -397,6 +397,8 @@ redraw_screen_rect (unsigned int x, unsigned int y,
y - virtual_screen.offset_y,
width, height);
}
+
+ grub_video_swap_buffers ();
}
static void
@@ -474,6 +476,7 @@ dirty_region_redraw (void)
redraw_screen_rect (x, y, width, height);
dirty_region_reset ();
+ grub_video_swap_buffers ();
}
static void
@@ -614,6 +617,8 @@ scroll_up (void)
if (virtual_screen.cursor_state)
draw_cursor (1);
}
+
+ grub_video_swap_buffers ();
}
static void
@@ -709,5 +714,7 @@ grub_gfxterm_putchar (grub_uint32_t c)
above call to write_char is redundant when the cursor is showing. */
if (virtual_screen.cursor_state)
draw_cursor (1);
+
+ grub_video_swap_buffers ();
}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
new file mode 100644
index 0000000..c80f6ea
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fbblit.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/bitmap.h>
+
+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[GRUB_VIDEO_FBSTD_NUMCOLORS] =
+ {
+ // {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..5b6e2b8 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -16,43 +16,17 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#define grub_video_render_target grub_video_fbrender_target
+
#include <grub/err.h>
#include <grub/machine/memory.h>
#include <grub/machine/vga.h>
#include <grub/machine/vbe.h>
-#include <grub/machine/vbeblit.h>
-#include <grub/machine/vbefill.h>
-#include <grub/machine/vbeutil.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/video.h>
-#include <grub/bitmap.h>
-
-/* 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,14 +42,30 @@ 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;
+static struct
+{
+ grub_size_t page_size; /* The size of a page in bytes. */
+
+ /* For page flipping strategy. */
+ int displayed_page; /* The page # that is the front buffer. */
+ int render_page; /* The page # that is the back buffer. */
+
+ /* For blit strategy. */
+ grub_uint8_t *offscreen_buffer;
+
+ /* Virtual functions. */
+ int (*update_screen) (void);
+ int (*destroy) (void);
+} doublebuf_state;
+
+static void double_buffering_init (int enable);
+
static void *
real2pm (grub_vbe_farptr_t ptr)
{
@@ -142,6 +132,7 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
{
grub_vbe_status_t status;
grub_uint32_t old_mode;
+ grub_err_t err;
/* Make sure that VBE is supported. */
grub_vbe_probe (0);
@@ -239,15 +230,29 @@ 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),
+ 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);
/* Just ignore the status. */
+ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+ grub_video_fbstd_colors);
+ if (err)
+ return err;
+
}
}
@@ -308,43 +313,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 +355,9 @@ grub_video_vbe_init (void)
/* Reset frame buffer and render target variables. */
grub_memset (&framebuffer, 0, sizeof(framebuffer));
- render_target = &framebuffer.render_target;
+ grub_memset (&doublebuf_state, 0, sizeof(doublebuf_state));
- return GRUB_ERR_NONE;
+ return grub_video_fb_init ();
}
static grub_err_t
@@ -403,14 +371,16 @@ grub_video_vbe_fini (void)
/* TODO: Decide, is this something we want to do. */
return grub_errno;
+ if (doublebuf_state.destroy)
+ doublebuf_state.destroy();
+
/* TODO: Free any resources allocated by driver. */
grub_free (mode_list);
mode_list = 0;
/* TODO: destroy render targets. */
- /* Return success to caller. */
- return GRUB_ERR_NONE;
+ return grub_video_fb_fini ();
}
static grub_err_t
@@ -422,7 +392,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)
@@ -502,6 +471,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
/* Try to initialize best mode found. */
if (best_mode != 0)
{
+ grub_err_t err;
/* If this fails, then we have mode selection heuristics problem,
or adapter failure. */
grub_vbe_set_video_mode (best_mode, &active_mode_info);
@@ -512,1089 +482,302 @@ 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;
+
+ /* Mark framebuffer memory as non allocated. */
+ framebuffer.render_target.is_allocated = 0;
- /* Set framebuffer pointer and mark it as non allocated. */
- render_target->is_allocated = 0;
- render_target->data = framebuffer.ptr;
+ /* Set up double buffering, initially disabled. */
+ double_buffering_init (0);
/* 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;
- }
+ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+ grub_video_fbstd_colors);
+ if (err)
+ return err;
- return GRUB_ERR_NONE;
+ /* Reset render target to framebuffer one. */
+ return grub_video_fb_set_active_render_target (&framebuffer.render_target);
}
/* Couldn't found matching mode. */
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found.");
}
-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;
-}
+/*
+ Set framebuffer render target page and display the proper page, based on
+ `doublebuf_state.render_page' and `doublebuf_state.displayed_page',
+ respectively.
-static grub_err_t
-grub_video_vbe_set_palette (unsigned int start, unsigned int count,
- struct grub_video_palette_data *palette_data)
+ Returns 0 upon success, nonzero upon failure.
+ */
+static int
+doublebuf_pageflipping_commit (void)
{
- unsigned int i;
+ /* Set the render target's data pointer to the start of the render_page. */
+ framebuffer.render_target.data =
+ ((char *) framebuffer.ptr) +
+ doublebuf_state.page_size * doublebuf_state.render_page;
- if (framebuffer.index_color_mode)
- {
- /* TODO: Implement setting indexed color mode palette to hardware. */
- //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
- // / sizeof (struct grub_vbe_palette_data),
- // 0,
- // palette);
+ /* Tell the video adapter to display the new front page. */
+ int display_start_line =
+ framebuffer.render_target.mode_info.height
+ * doublebuf_state.displayed_page;
- }
+ grub_vbe_status_t vbe_err =
+ grub_vbe_bios_set_display_start (0, display_start_line);
+ if (vbe_err != GRUB_VBE_STATUS_OK)
+ return 1;
- /* 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;
+ return 0;
}
-static grub_err_t
-grub_video_vbe_get_palette (unsigned int start, unsigned int count,
- struct grub_video_palette_data *palette_data)
+static int
+doublebuf_pageflipping_update_screen (void)
{
- 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];
+ /* Swap the page numbers in the framebuffer struct. */
+ int new_displayed_page = doublebuf_state.render_page;
+ doublebuf_state.render_page = doublebuf_state.displayed_page;
+ doublebuf_state.displayed_page = new_displayed_page;
- return GRUB_ERR_NONE;
+ return doublebuf_pageflipping_commit ();
}
-static grub_err_t
-grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
- unsigned int width, unsigned int height)
+static int
+doublebuf_pageflipping_destroy (void)
{
- /* Make sure viewport is withing screen dimensions. If viewport was set
- to be out of the region, mark its size as zero. */
- if (x > active_mode_info.x_resolution)
- {
- x = 0;
- width = 0;
- }
-
- if (y > active_mode_info.y_resolution)
- {
- y = 0;
- height = 0;
- }
-
- if (x + width > active_mode_info.x_resolution)
- width = active_mode_info.x_resolution - x;
-
- 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;
+ doublebuf_state.update_screen = 0;
+ doublebuf_state.destroy = 0;
+ return 0;
}
-static grub_err_t
-grub_video_vbe_get_viewport (unsigned int *x, unsigned int *y,
- unsigned int *width, unsigned int *height)
+static int
+doublebuf_pageflipping_init (void)
{
- 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;
+ doublebuf_state.page_size =
+ framebuffer.bytes_per_scan_line * framebuffer.render_target.mode_info.height;
- return GRUB_ERR_NONE;
-}
+ /* Get video RAM size in bytes. */
+ grub_size_t vram_size = controller_info.total_memory << 16;
-/* 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 (2 * doublebuf_state.page_size > vram_size)
+ return 1; /* Not enough video memory for 2 pages. */
- 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;
+ doublebuf_state.displayed_page = 0;
+ doublebuf_state.render_page = 1;
- color = grub_video_vbe_map_rgb (framebuffer.palette[color_name].r,
- framebuffer.palette[color_name].g,
- framebuffer.palette[color_name].b);
+ doublebuf_state.update_screen = doublebuf_pageflipping_update_screen;
+ doublebuf_state.destroy = doublebuf_pageflipping_destroy;
- return color;
- }
- }
+ /* Set the framebuffer memory data pointer and display the right page. */
+ if (doublebuf_pageflipping_commit () != GRUB_ERR_NONE)
+ return 1; /* Unable to set the display start. */
+ framebuffer.render_target.mode_info.mode_type
+ |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
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)
+static int
+doublebuf_blit_update_screen (void)
{
- 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;
- }
-
+ grub_memcpy (framebuffer.ptr,
+ doublebuf_state.offscreen_buffer,
+ doublebuf_state.page_size);
+ return 0;
}
-/* 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)
+static int
+doublebuf_blit_destroy (void)
{
- 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;
+ grub_free (doublebuf_state.offscreen_buffer);
+ doublebuf_state.offscreen_buffer = 0;
- 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;
- }
+ doublebuf_state.update_screen = 0;
+ doublebuf_state.destroy = 0;
+ return 0;
}
-/* 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)
+static int
+doublebuf_blit_init (void)
{
- struct grub_video_i386_vbeblit_info target_info;
+ doublebuf_state.page_size =
+ framebuffer.bytes_per_scan_line * framebuffer.render_target.mode_info.height;
- target_info.mode_info = &render_target->mode_info;
- target_info.data = render_target->data;
+ doublebuf_state.offscreen_buffer = (grub_uint8_t *)
+ grub_malloc (doublebuf_state.page_size);
+ if (doublebuf_state.offscreen_buffer == 0)
+ return 1; /* Error. */
- grub_video_vbe_unmap_color_int (&target_info, color, red, green, blue, alpha);
+ framebuffer.render_target.data = doublebuf_state.offscreen_buffer;
+ doublebuf_state.update_screen = doublebuf_blit_update_screen;
+ doublebuf_state.destroy = doublebuf_blit_destroy;
- return GRUB_ERR_NONE;
+ framebuffer.render_target.mode_info.mode_type
+ |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+ return 0;
}
-/* 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)
+static int
+doublebuf_null_update_screen (void)
{
- 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;
- }
+ return 0;
}
-static grub_err_t
-grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y,
- unsigned int width, unsigned int height)
+static int
+doublebuf_null_destroy (void)
{
- 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;
+ doublebuf_state.update_screen = 0;
+ doublebuf_state.destroy = 0;
+ return 0;
}
-/* 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)
+static int
+doublebuf_null_init (void)
{
- 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. */
+ framebuffer.render_target.data = framebuffer.ptr;
+ doublebuf_state.update_screen = doublebuf_null_update_screen;
+ doublebuf_state.destroy = doublebuf_null_destroy;
- 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);
- }
+ framebuffer.render_target.mode_info.mode_type
+ &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+ return 0;
}
-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)
+/* Select the best double buffering mode available. */
+static void
+double_buffering_init (int enable)
{
- 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 (doublebuf_state.destroy)
+ doublebuf_state.destroy ();
- if (offset_y < 0)
+ if (enable)
{
- height += offset_y;
- y -= offset_y;
- offset_y = 0;
- }
+ if (doublebuf_pageflipping_init () == 0)
+ return;
- if (x < 0)
- {
- width += x;
- offset_x -= x;
- x = 0;
- }
-
- if (y < 0)
- {
- height += y;
- offset_y -= y;
- y = 0;
+ if (doublebuf_blit_init () == 0)
+ return;
}
- /* 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;
+ /* Fall back to no double buffering. */
+ doublebuf_null_init ();
}
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)
+grub_video_vbe_set_palette (unsigned int start, unsigned int count,
+ struct grub_video_palette_data *palette_data)
{
- 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)
+ if (framebuffer.index_color_mode)
{
- width += x;
- offset_x -= x;
- x = 0;
- }
+ /* TODO: Implement setting indexed color mode palette to hardware. */
+ //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
+ // / sizeof (struct grub_vbe_palette_data),
+ // 0,
+ // palette);
- 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);
+ /* Then set color to emulated palette. */
- return GRUB_ERR_NONE;
+ return grub_video_fb_set_palette (start, count, palette_data);
}
static grub_err_t
-grub_video_vbe_scroll (grub_video_color_t color, int dx, int dy)
+grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
+ unsigned int width, unsigned int height)
{
- 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))
+ /* Make sure viewport is withing screen dimensions. If viewport was set
+ to be out of the region, mark its size as zero. */
+ if (x > active_mode_info.x_resolution)
{
- /* 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);
- }
+ x = 0;
+ width = 0;
}
- /* 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 (y > active_mode_info.y_resolution)
{
- 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);
+ y = 0;
+ height = 0;
}
- /* 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);
- }
+ if (x + width > active_mode_info.x_resolution)
+ width = active_mode_info.x_resolution - x;
- return GRUB_ERR_NONE;
+ if (y + height > active_mode_info.y_resolution)
+ height = active_mode_info.y_resolution - y;
+ return grub_video_fb_set_viewport (x, y, width, height);
}
static grub_err_t
grub_video_vbe_swap_buffers (void)
{
- /* TODO: Implement buffer swapping. */
- return GRUB_ERR_NONE;
-}
-
-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;
+ if (doublebuf_state.update_screen () != 0)
+ return grub_error (GRUB_ERR_INVALID_COMMAND,
+ "Double buffer update failed");
return GRUB_ERR_NONE;
}
static grub_err_t
-grub_video_vbe_delete_render_target (struct grub_video_render_target *target)
+grub_video_vbe_enable_double_buffering (int enable)
{
- /* 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);
-
+ double_buffering_init (enable);
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;
- }
+ if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+ 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;
+ return grub_video_fb_set_active_render_target (target);
}
static grub_err_t
-grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
+grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuf)
{
- *target = render_target;
+ grub_err_t err;
+ err = grub_video_fb_get_info (mode_info);
+ if (err)
+ return err;
+ *framebuf = ((char *) framebuffer.ptr) +
+ doublebuf_state.page_size * doublebuf_state.displayed_page;
return GRUB_ERR_NONE;
}
+
static struct grub_video_adapter grub_video_vbe_adapter =
{
.name = "VESA BIOS Extension Video Driver",
@@ -1602,24 +785,26 @@ 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,
+ .get_info_and_fini = grub_video_vbe_get_info_and_fini,
.set_palette = grub_video_vbe_set_palette,
- .get_palette = grub_video_vbe_get_palette,
+ .get_palette = grub_video_fb_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_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,
+ .enable_double_buffering = grub_video_vbe_enable_double_buffering,
+ .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/video.c b/video/video.c
index c22947b..b7df580 100644
--- a/video/video.c
+++ b/video/video.c
@@ -93,6 +93,24 @@ grub_video_get_info (struct grub_video_mode_info *mode_info)
return grub_video_adapter_active->get_info (mode_info);
}
+/* Get information about active video mode. */
+grub_err_t
+grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuffer)
+{
+ grub_err_t err;
+
+ if (! grub_video_adapter_active)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+ err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer);
+ if (err)
+ return err;
+
+ grub_video_adapter_active = 0;
+ return GRUB_ERR_NONE;
+}
+
/* Determine optimized blitting formation for specified video mode info. */
enum grub_video_blit_format
grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
@@ -335,6 +353,16 @@ grub_video_swap_buffers (void)
return grub_video_adapter_active->swap_buffers ();
}
+/* Enable or disable double buffering. */
+grub_err_t
+grub_video_enable_double_buffering (int enable)
+{
+ if (! grub_video_adapter_active)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+ return grub_video_adapter_active->enable_double_buffering (enable);
+}
+
/* Create new render target. */
grub_err_t
grub_video_create_render_target (struct grub_video_render_target **result,
@@ -380,7 +408,7 @@ grub_video_get_active_render_target (struct grub_video_render_target **target)
}
grub_err_t
-grub_video_set_mode (char *modestring,
+grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info))
{
@@ -630,6 +658,8 @@ grub_video_set_mode (char *modestring,
flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+ flags |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+
/* Try to initialize requested mode. Ignore any errors. */
grub_video_adapter_t p;
@@ -654,6 +684,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 +694,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;
}
@@ -695,8 +729,6 @@ grub_video_set_mode (char *modestring,
/* Initialize Video API module. */
GRUB_MOD_INIT(video_video)
{
- grub_video_adapter_active = 0;
- grub_video_adapter_list = 0;
}
/* Finalize Video API module. */
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-26 22:06 ` Vladimir 'phcoder' Serbinenko
@ 2009-07-28 17:50 ` Robert Millan
2009-07-28 21:21 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:01 ` Robert Millan
1 sibling, 1 reply; 47+ messages in thread
From: Robert Millan @ 2009-07-28 17:50 UTC (permalink / raw)
To: The development of GRUB 2
On Mon, Jul 27, 2009 at 12:06:17AM +0200, Vladimir 'phcoder' Serbinenko wrote:
> Removed parts which are purely moving code around (of course it will
> be restored on commit).
This is not a full review of the patch, just a quick overview. But I have
a few comments:
- The "fb" naming is confusing. "framebuffer" refers to a Linux API
exported to userland on GNU/Linux, but it seems to be used for
referring to the backend. I think it's better if we call it just
that ("backend"). Or maybe "driver" but that doesn't apply well to
vbe.
- Some copyright years need updating (I noticed video_fb.h, but please
review the other files as well).
- It'd help if the patch could actually be split in standalone parts
that can be committed separately. Maybe this is not possible, but
at least for some parts of it, it probably is.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-28 17:50 ` Robert Millan
@ 2009-07-28 21:21 ` Vladimir 'phcoder' Serbinenko
2009-07-31 16:00 ` Robert Millan
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-07-28 21:21 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jul 28, 2009 at 7:50 PM, Robert Millan<rmh@aybabtu.com> wrote:
> On Mon, Jul 27, 2009 at 12:06:17AM +0200, Vladimir 'phcoder' Serbinenko wrote:
>> Removed parts which are purely moving code around (of course it will
>> be restored on commit).
>
> This is not a full review of the patch, just a quick overview. But I have
> a few comments:
>
> - The "fb" naming is confusing. "framebuffer" refers to a Linux API
> exported to userland on GNU/Linux, but it seems to be used for
> referring to the backend. I think it's better if we call it just
> that ("backend"). Or maybe "driver" but that doesn't apply well to
> vbe.
backend and driver aren't good names because it's neither a complete
backend nor a driver. It's more like a functions library which can be
used by drivers. Prefix video_fb was chosen deliberately to avoid
names to become too long. I don't think that video_fb is of any more
problem than video_vbe since FB is a widely used abbreviation when
speaking about graphics.
>
> - Some copyright years need updating (I noticed video_fb.h, but please
> review the other files as well).
>
Thanks
> - It'd help if the patch could actually be split in standalone parts
> that can be committed separately. Maybe this is not possible, but
> at least for some parts of it, it probably is.
>
Some parts yes but the main part of patch is dispatching functions
from vbe.c and splitting it may cause intermediary states to be easily
broken.
> --
> Robert Millan
>
> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
> how) you may access your data; but nobody's threatening your freedom: we
> still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-28 21:21 ` Vladimir 'phcoder' Serbinenko
@ 2009-07-31 16:00 ` Robert Millan
2009-07-31 20:31 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Robert Millan @ 2009-07-31 16:00 UTC (permalink / raw)
To: The development of GRUB 2
On Tue, Jul 28, 2009 at 11:21:56PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> On Tue, Jul 28, 2009 at 7:50 PM, Robert Millan<rmh@aybabtu.com> wrote:
> > On Mon, Jul 27, 2009 at 12:06:17AM +0200, Vladimir 'phcoder' Serbinenko wrote:
> >> Removed parts which are purely moving code around (of course it will
> >> be restored on commit).
> >
> > This is not a full review of the patch, just a quick overview. But I have
> > a few comments:
> >
> > - The "fb" naming is confusing. "framebuffer" refers to a Linux API
> > exported to userland on GNU/Linux, but it seems to be used for
> > referring to the backend. I think it's better if we call it just
> > that ("backend"). Or maybe "driver" but that doesn't apply well to
> > vbe.
> backend and driver aren't good names because it's neither a complete
> backend nor a driver. It's more like a functions library which can be
> used by drivers.
Well, that fits the definition of backend.
> Prefix video_fb was chosen deliberately to avoid
> names to become too long. I don't think that video_fb is of any more
> problem than video_vbe since FB is a widely used abbreviation when
> speaking about graphics.
Yes, but in this case we're speaking about the category where VBE belongs
to. If people read "backend", that inmediately conveys an idea on what
it does.
If they read "fb", they just know it has something to do with video, but
they already knew that, so in practice it doesn't provide any information.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-31 16:00 ` Robert Millan
@ 2009-07-31 20:31 ` Vladimir 'phcoder' Serbinenko
2009-08-01 14:41 ` Robert Millan
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-07-31 20:31 UTC (permalink / raw)
To: The development of GRUB 2
> Well, that fits the definition of backend.
>
But there are other backends too - network backend, opengl backend, ...
Framebuffer is a term often used to designated memory ranged which is
mapped to the screen.
May we stop discussing about names and rather either commit or discuss
technical details?
>
> --
> Robert Millan
>
> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
> how) you may access your data; but nobody's threatening your freedom: we
> still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-31 20:31 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-01 14:41 ` Robert Millan
2009-08-01 14:50 ` Michal Suchanek
0 siblings, 1 reply; 47+ messages in thread
From: Robert Millan @ 2009-08-01 14:41 UTC (permalink / raw)
To: The development of GRUB 2
On Fri, Jul 31, 2009 at 10:31:07PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> > Well, that fits the definition of backend.
> >
> But there are other backends too - network backend, opengl backend, ...
> Framebuffer is a term often used to designated memory ranged which is
> mapped to the screen.
Ok then. I think I got confused by the common usage of this term, which
often refers to the whole thing. I'm fine with it, as long as it's used
consistently.
> May we stop discussing about names and rather either commit or discuss
> technical details?
Names are very important. When someone who's not familiar with the code
is trying to figure it out, if the name of a function or an interface
inmediately evokes an idea of what it does, that person won't have to
check. It makes working with GRUB much more efficient.
I'll look at the technical part of the patch now.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 14:41 ` Robert Millan
@ 2009-08-01 14:50 ` Michal Suchanek
2009-08-01 15:02 ` Robert Millan
0 siblings, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-01 14:50 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/1 Robert Millan <rmh@aybabtu.com>:
> On Fri, Jul 31, 2009 at 10:31:07PM +0200, Vladimir 'phcoder' Serbinenko wrote:
>> > Well, that fits the definition of backend.
>> >
>> But there are other backends too - network backend, opengl backend, ...
>> Framebuffer is a term often used to designated memory ranged which is
>> mapped to the screen.
>
> Ok then. I think I got confused by the common usage of this term, which
> often refers to the whole thing. I'm fine with it, as long as it's used
> consistently.
Yes, I can agree with "framebuffer" being used for the memory storing
the display data, X has fb library, many other graphics libraries have
bf handling routines but the most well known one is the Linux
"framebuffer console" - the console using the Linux framebuffer
library.
>
>> May we stop discussing about names and rather either commit or discuss
>> technical details?
>
> Names are very important. When someone who's not familiar with the code
> is trying to figure it out, if the name of a function or an interface
> inmediately evokes an idea of what it does, that person won't have to
> check. It makes working with GRUB much more efficient.
>
For me backend is just something generic that can do just about
anything (even compilers have a backend) but framebuffer evokes the
thought of rectangular memory area storing the picture shown on the
screen.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-07-26 22:06 ` Vladimir 'phcoder' Serbinenko
2009-07-28 17:50 ` Robert Millan
@ 2009-08-01 15:01 ` Robert Millan
2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:14 ` Michal Suchanek
1 sibling, 2 replies; 47+ messages in thread
From: Robert Millan @ 2009-08-01 15:01 UTC (permalink / raw)
To: The development of GRUB 2
On Mon, Jul 27, 2009 at 12:06:17AM +0200, Vladimir 'phcoder' Serbinenko wrote:
> grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
>
> + grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
> + void **framebuffer);
> +
> [...]
> +/* Framebuffer address may change as a part of normal operation
> + (e.g. double buffering). That's why you need to stop video subsystem to be
> + sure that framebuffer address doesn't change. To ensure this abstraction
> + grub_video_get_info_and_fini is the only function supplying framebuffer
> + address. */
> +grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
> + void **framebuffer);
> +
I see that returning framebuffer address and finishing the video subsystem
must be together, but is there a reason to couple this with getting mode_info ?
If mode_info is also affected by this problem, or if getting mode info only
makes sense in a situation in which we'd also want to obtain framebuffer
address or finishing the subsystem, then the existing get_info() function
is no longer necessary.
Otherwise, users who want both things can just invoke get_info() first and then
the new function to obtain FB address.
Btw, if I understand correctly, we have a race condition right now. As a
bugfix it'd be better to merge this separately from the interface redesign if
possible.
Also, does finishing the video subsystem only affect GRUB internally, or
result in any effect at the display level? I want to avoid having visual
glitches when the payload is loaded without switching video mode.
> - modevar = grub_env_get ("gfxpayload");
> -
> - /* Now all graphical modes are acceptable.
> - May change in future if we have modes without framebuffer. */
> [...]
> - {
> - params->have_vga = GRUB_VIDEO_TYPE_TEXT;
> - params->video_width = 80;
> - params->video_height = 25;
> - }
> -
Why is this chunk of code moved down? AFAICS, this change only involves
adding an additional layer between it and the video backend. Does this
make it conflict with something else?
> +#define grub_video_render_target grub_video_fbrender_target
If we want to rename this function, I'd rather do it all the way than
keeping a compatibility macro. But then, I'd also prefer if this is
done separately from the rest (either before or after).
> +/* Select the best double buffering mode available. */
> +static void
> +double_buffering_init (int enable)
This patch also seems to add double buffering support, which is a feature
that wasn't yet implemented. I suppose it's good to have (I'm not very
clued about graphics), but I'd prefer if we can merge this separately
from the redesign changes.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 14:50 ` Michal Suchanek
@ 2009-08-01 15:02 ` Robert Millan
0 siblings, 0 replies; 47+ messages in thread
From: Robert Millan @ 2009-08-01 15:02 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 01, 2009 at 04:50:59PM +0200, Michal Suchanek wrote:
> 2009/8/1 Robert Millan <rmh@aybabtu.com>:
> > On Fri, Jul 31, 2009 at 10:31:07PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> >> > Well, that fits the definition of backend.
> >> >
> >> But there are other backends too - network backend, opengl backend, ...
> >> Framebuffer is a term often used to designated memory ranged which is
> >> mapped to the screen.
> >
> > Ok then. I think I got confused by the common usage of this term, which
> > often refers to the whole thing. I'm fine with it, as long as it's used
> > consistently.
>
> Yes, I can agree with "framebuffer" being used for the memory storing
> the display data, X has fb library, many other graphics libraries have
> bf handling routines but the most well known one is the Linux
> "framebuffer console" - the console using the Linux framebuffer
> library.
>
> >
> >> May we stop discussing about names and rather either commit or discuss
> >> technical details?
> >
> > Names are very important. When someone who's not familiar with the code
> > is trying to figure it out, if the name of a function or an interface
> > inmediately evokes an idea of what it does, that person won't have to
> > check. It makes working with GRUB much more efficient.
> >
>
> For me backend is just something generic that can do just about
> anything (even compilers have a backend) but framebuffer evokes the
> thought of rectangular memory area storing the picture shown on the
> screen.
I stand corrected.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:01 ` Robert Millan
@ 2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-01 16:03 ` Vladimir 'phcoder' Serbinenko
2009-08-02 21:43 ` Robert Millan
2009-08-01 15:14 ` Michal Suchanek
1 sibling, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-01 15:10 UTC (permalink / raw)
To: The development of GRUB 2
>
> I see that returning framebuffer address and finishing the video subsystem
> must be together, but is there a reason to couple this with getting mode_info ?
When designing this part I thought of accelerated graphics. Before
loading the OS they would switch to standard framebuffer mode this may
also affect the formats used so the info may be different from
get_info
>
> Btw, if I understand correctly, we have a race condition right now. As a
> bugfix it'd be better to merge this separately from the interface redesign if
> possible.
race condition? We don't even have threads
>
> Also, does finishing the video subsystem only affect GRUB internally, or
> result in any effect at the display level? I want to avoid having visual
> glitches when the payload is loaded without switching video mode.
>
Other than addition of double buffering changes will not result in any
visible effect.
>> - modevar = grub_env_get ("gfxpayload");
>> -
>> - /* Now all graphical modes are acceptable.
>> - May change in future if we have modes without framebuffer. */
>> [...]
>> - {
>> - params->have_vga = GRUB_VIDEO_TYPE_TEXT;
>> - params->video_width = 80;
>> - params->video_height = 25;
>> - }
>> -
>
> Why is this chunk of code moved down? AFAICS, this change only involves
> adding an additional layer between it and the video backend. Does this
> make it conflict with something else?
>
I wanted to keep normal grub_printf as long as possible and after
get_mode_and_fini grub_printf may be unfunctional.
>> +#define grub_video_render_target grub_video_fbrender_target
>
> If we want to rename this function, I'd rather do it all the way than
> keeping a compatibility macro. But then, I'd also prefer if this is
> done separately from the rest (either before or after).
>
It's not about renaming but to inform includes that
grub_video_render_target is in fact grub_video_fbrender_target and so
avoid warnings and casts.
>> +/* Select the best double buffering mode available. */
>> +static void
>> +double_buffering_init (int enable)
>
> This patch also seems to add double buffering support, which is a feature
> that wasn't yet implemented. I suppose it's good to have (I'm not very
> clued about graphics), but I'd prefer if we can merge this separately
> from the redesign changes.
>
Ok, I will try to split while keeping patch functional.
> --
> Robert Millan
>
> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
> how) you may access your data; but nobody's threatening your freedom: we
> still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:01 ` Robert Millan
2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-01 15:14 ` Michal Suchanek
2009-08-01 15:17 ` Vladimir 'phcoder' Serbinenko
1 sibling, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-01 15:14 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/1 Robert Millan <rmh@aybabtu.com>:
> On Mon, Jul 27, 2009 at 12:06:17AM +0200, Vladimir 'phcoder' Serbinenko wrote:
>> grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
>>
>> + grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
>> + void **framebuffer);
>> +
>> [...]
>> +/* Framebuffer address may change as a part of normal operation
>> + (e.g. double buffering). That's why you need to stop video subsystem to be
>> + sure that framebuffer address doesn't change. To ensure this abstraction
>> + grub_video_get_info_and_fini is the only function supplying framebuffer
>> + address. */
>> +grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
>> + void **framebuffer);
>> +
>
> I see that returning framebuffer address and finishing the video subsystem
> must be together, but is there a reason to couple this with getting mode_info ?
>
> If mode_info is also affected by this problem, or if getting mode info only
> makes sense in a situation in which we'd also want to obtain framebuffer
> address or finishing the subsystem, then the existing get_info() function
> is no longer necessary.
>
> Otherwise, users who want both things can just invoke get_info() first and then
> the new function to obtain FB address.
>
> Btw, if I understand correctly, we have a race condition right now. As a
> bugfix it'd be better to merge this separately from the interface redesign if
> possible.
>
> Also, does finishing the video subsystem only affect GRUB internally, or
> result in any effect at the display level? I want to avoid having visual
> glitches when the payload is loaded without switching video mode.
>
I guess the current initialization is somewhat fishy. I haven't looked
at the code so far but the way it works is odd. When I change output
to gfxterm it apparently tries to initialize the vbe graphics but it
fails to find any videomode unless I run vbetest before starting
gfxterm.
The situation is the same both pre- and post- split.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:14 ` Michal Suchanek
@ 2009-08-01 15:17 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:32 ` Michal Suchanek
2009-08-02 21:29 ` Robert Millan
0 siblings, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-01 15:17 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 1, 2009 at 5:14 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> 2009/8/1 Robert Millan <rmh@aybabtu.com>:
> I guess the current initialization is somewhat fishy. I haven't looked
> at the code so far but the way it works is odd. When I change output
> to gfxterm it apparently tries to initialize the vbe graphics but it
> fails to find any videomode unless I run vbetest before starting
> gfxterm.
>
> The situation is the same both pre- and post- split.
insmod vbe
Autoload right driver would be nice. Perhaps having a list of pairs
(PCI vendor; driver) ?
>
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:17 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-01 15:32 ` Michal Suchanek
2009-08-02 21:29 ` Robert Millan
1 sibling, 0 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-01 15:32 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/1 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Sat, Aug 1, 2009 at 5:14 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> 2009/8/1 Robert Millan <rmh@aybabtu.com>:
>> I guess the current initialization is somewhat fishy. I haven't looked
>> at the code so far but the way it works is odd. When I change output
>> to gfxterm it apparently tries to initialize the vbe graphics but it
>> fails to find any videomode unless I run vbetest before starting
>> gfxterm.
>>
>> The situation is the same both pre- and post- split.
>
> insmod vbe
>
> Autoload right driver would be nice. Perhaps having a list of pairs
> (PCI vendor; driver) ?
The PCI id list for vbe would be quite long ;-)
However, vbe and vga (if/when implemented) could be used as fallback.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-01 16:03 ` Vladimir 'phcoder' Serbinenko
2009-08-02 22:01 ` Vladimir 'phcoder' Serbinenko
2009-08-02 21:43 ` Robert Millan
1 sibling, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-01 16:03 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 826 bytes --]
On Sat, Aug 1, 2009 at 5:10 PM, Vladimir 'phcoder'
Serbinenko<phcoder@gmail.com> wrote:
> Ok, I will try to split while keeping patch functional.
Done
>> --
>> Robert Millan
>>
>> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
>> how) you may access your data; but nobody's threatening your freedom: we
>> still allow you to remove your data and not access it at all."
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: framebuf.diff.gz --]
[-- Type: application/x-gzip, Size: 25564 bytes --]
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:17 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:32 ` Michal Suchanek
@ 2009-08-02 21:29 ` Robert Millan
1 sibling, 0 replies; 47+ messages in thread
From: Robert Millan @ 2009-08-02 21:29 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 01, 2009 at 05:17:32PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> On Sat, Aug 1, 2009 at 5:14 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> > 2009/8/1 Robert Millan <rmh@aybabtu.com>:
> > I guess the current initialization is somewhat fishy. I haven't looked
> > at the code so far but the way it works is odd. When I change output
> > to gfxterm it apparently tries to initialize the vbe graphics but it
> > fails to find any videomode unless I run vbetest before starting
> > gfxterm.
> >
> > The situation is the same both pre- and post- split.
>
> insmod vbe
>
> Autoload right driver would be nice. Perhaps having a list of pairs
> (PCI vendor; driver) ?
I suppose this will make sense when we have hardware drivers for video.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-01 16:03 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-02 21:43 ` Robert Millan
2009-08-02 21:52 ` Vladimir 'phcoder' Serbinenko
1 sibling, 1 reply; 47+ messages in thread
From: Robert Millan @ 2009-08-02 21:43 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Aug 01, 2009 at 05:10:30PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> > Btw, if I understand correctly, we have a race condition right now. As a
> > bugfix it'd be better to merge this separately from the interface redesign if
> > possible.
> race condition? We don't even have threads
Well, we have the possibility that video drivers are doing stuff in background,
but that's something entirely different I had in mind. Please bear with me, I
missunderstood what you wrote :-)
> > Why is this chunk of code moved down? AFAICS, this change only involves
> > adding an additional layer between it and the video backend. Does this
> > make it conflict with something else?
> >
> I wanted to keep normal grub_printf as long as possible and after
> get_mode_and_fini grub_printf may be unfunctional.
Ok
> >> +#define grub_video_render_target grub_video_fbrender_target
> >
> > If we want to rename this function, I'd rather do it all the way than
> > keeping a compatibility macro. But then, I'd also prefer if this is
> > done separately from the rest (either before or after).
> >
> It's not about renaming but to inform includes that
> grub_video_render_target is in fact grub_video_fbrender_target and so
> avoid warnings and casts.
I don't understand this. If we want to settle with grub_video_render_target
why don't we just provide that function directly? Or is this making room
for an additional layer later on?
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-02 21:43 ` Robert Millan
@ 2009-08-02 21:52 ` Vladimir 'phcoder' Serbinenko
0 siblings, 0 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-02 21:52 UTC (permalink / raw)
To: The development of GRUB 2
>> >> +#define grub_video_render_target grub_video_fbrender_target
>> >
>> > If we want to rename this function, I'd rather do it all the way than
>> > keeping a compatibility macro. But then, I'd also prefer if this is
>> > done separately from the rest (either before or after).
>> >
>> It's not about renaming but to inform includes that
>> grub_video_render_target is in fact grub_video_fbrender_target and so
>> avoid warnings and casts.
>
> I don't understand this. If we want to settle with grub_video_render_target
> why don't we just provide that function directly? Or is this making room
> for an additional layer later on?
It's for abstraction we already have. Most of video subsystem doesn't
care whether render_target is framebuffer, OpenGL or network commands.
In this particular case we know that we're rendering to a framebuffer
and so function
do_something (grub_video_render_target *my_render_target);
like it's used by upper layers is inded the same as
do_something (grub_video_fbrender_target *my_render_target);
and not e.g.
do_something (grub_video_glrender_target *my_render_target);
>
> --
> Robert Millan
>
> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
> how) you may access your data; but nobody's threatening your freedom: we
> still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-01 16:03 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-02 22:01 ` Vladimir 'phcoder' Serbinenko
2009-08-08 19:06 ` Michal Suchanek
2009-08-09 11:55 ` Michal Suchanek
0 siblings, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-02 22:01 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 1128 bytes --]
As requested a patch with moving of code omitted
On Sat, Aug 1, 2009 at 6:03 PM, Vladimir 'phcoder'
Serbinenko<phcoder@gmail.com> wrote:
> On Sat, Aug 1, 2009 at 5:10 PM, Vladimir 'phcoder'
> Serbinenko<phcoder@gmail.com> wrote:
>> Ok, I will try to split while keeping patch functional.
> Done
>>> --
>>> Robert Millan
>>>
>>> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
>>> how) you may access your data; but nobody's threatening your freedom: we
>>> still allow you to remove your data and not access it at all."
>>>
>>>
>>> _______________________________________________
>>> Grub-devel mailing list
>>> Grub-devel@gnu.org
>>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>>
>>
>>
>>
>> --
>> Regards
>> Vladimir 'phcoder' Serbinenko
>>
>> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: framebuf.diff --]
[-- Type: text/plain, Size: 100053 bytes --]
diff --git a/ChangeLog b/ChangeLog
index d7f219b..7713e29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2009-07-26 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Framebuffer split.
+
+ * commands/i386/pc/vbetest.c (grub_cmd_vbetest): Restore video
+ subsystem at the end.
+ * conf/common.rmk (pkglib_MODULES): Add video_fb.mod.
+ (video_fb_mod_SOURCES): New variable.
+ (video_fb_mod_CFLAGS): Likewise.
+ (video_fb_mod_LDFLAGS): Likewise.
+ * conf/i386-pc.rmk (vbe_mod_SOURCES): Remove video/i386/pc/vbeblit.c,
+ video/i386/pc/vbefill.c and video/i386/pc/vbeutil.c.
+ * video/i386/pc/vbeblit.c: Moved from here ...
+ * video/fb/fbblit.c: ..here. Replaced 'vbe' with 'fb'.
+ * video/i386/pc/vbefill.c: Moved from here ...
+ * video/fb/fbfill.c: ..here. Replaced 'vbe' with 'fb'.
+ * video/i386/pc/vbeutil.c: Moved from here ...
+ * video/fb/fbutil.c: ..here. Replaced 'vbe' with 'fb'.
+ * include/grub/i386/pc/vbeblit.h: Moved from here ...
+ * include/grub/fbblit.h: ... here. Replaced 'vbe' with 'fb'.
+ * include/grub/i386/pc/vbefill.h: Moved from here ...
+ * include/grub/fbfill.h: ... here. Replaced 'vbe' with 'fb'.
+ * include/grub/i386/pc/vbeutil.h: Moved from here ...
+ * include/grub/fbutil.h: ... here. Replaced 'vbe' with 'fb'.
+ * include/grub/i386/pc/vbe.h: Moved framebuffer part ...
+ * include/grub/video_fb.h: ... here. Replaced 'vbe' with 'fb'.
+ * include/grub/video.h (GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER): Removed.
+ (GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER): Likewise.
+ (grub_video_adapter): Added 'get_info_and_fini'.
+ (grub_video_get_info_and_fini): New prototype.
+ (grub_video_set_mode): make modestring const char *.
+ * loader/i386/linux.c (grub_linux_setup_video): Use
+ grub_video_get_info_and_fini.
+ (grub_linux_boot): Move modesetting just before booting.
+ * loader/i386/pc/xnu.c (grub_xnu_set_video): Use
+ grub_video_get_info_and_fini.
+ * video/i386/pc/vbe.c: Moved framebuffer part ...
+ * video/fb/video_fb.c: ... here. Replaced 'vbe' with 'fb'.
+ * video/i386/pc/vbe.c (grub_vbe_set_video_mode): Use
+ grub_video_fbstd_colors and grub_video_fb_set_palette.
+ (grub_video_vbe_init): Clear 'framebuffer' variable and use
+ grub_video_fb_init.
+ (grub_video_vbe_fini): Use grub_video_fb_fini.
+ (grub_video_vbe_setup): Use framebuffer.render_target instead of
+ render_target and use grub_video_fb_set_active_render_target and
+ grub_video_fb_set_palette.
+ (grub_video_vbe_set_palette): Use grub_video_fb_set_palette.
+ (grub_video_vbe_set_viewport): Use grub_video_fb_set_viewport.
+ (grub_video_vbe_adapter): Use framebuffer.
+ * video/video.c (grub_video_get_info_and_fini): New function.
+ (grub_video_set_mode): Make modestring const char *.
+ (GRUB_MOD_INIT(video_video)): Don't set variables to 0 since these
+ values are already initialised.
+
2009-08-01 Vladimir Serbinenko <phcoder@gmail.com>
* util/hostfs.c (grub_hostfs_dir): Don't use DT_DIR: It doesn't work
diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c
index 3cbc301..314320d 100644
--- a/commands/i386/pc/vbetest.c
+++ b/commands/i386/pc/vbetest.c
@@ -155,6 +155,8 @@ grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
grub_getkey ();
+ grub_video_restore ();
+
/* Restore old video mode. */
grub_vbe_set_video_mode (old_mode, 0);
diff --git a/conf/common.rmk b/conf/common.rmk
index 032517f..5e93302 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -535,13 +535,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 798aee2..5b7b8c0 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -273,8 +273,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/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 <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/video.h>
+#include <grub/video_fb.h>
/* 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/video.h b/include/grub/video.h
index c98731d..4145db4 100644
--- a/include/grub/video.h
+++ b/include/grub/video.h
@@ -48,10 +48,8 @@ struct grub_video_bitmap;
#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK 0x0000ff00
#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS 8
-/* Defined predefined render targets. */
-#define GRUB_VIDEO_RENDER_TARGET_DISPLAY ((struct grub_video_render_target *) 0)
-#define GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER ((struct grub_video_render_target *) 0)
-#define GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER ((struct grub_video_render_target *) 1)
+#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
+ ((struct grub_video_render_target *) 0)
/* Defined blitting formats. */
enum grub_video_blit_format
@@ -177,6 +175,9 @@ struct grub_video_adapter
grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
+ grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
+ void **framebuffer);
+
grub_err_t (*set_palette) (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data);
@@ -241,6 +242,14 @@ grub_err_t grub_video_restore (void);
grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info);
+/* Framebuffer address may change as a part of normal operation
+ (e.g. double buffering). That's why you need to stop video subsystem to be
+ sure that framebuffer address doesn't change. To ensure this abstraction
+ grub_video_get_info_and_fini is the only function supplying framebuffer
+ address. */
+grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuffer);
+
enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
@@ -297,7 +306,7 @@ grub_err_t grub_video_set_active_render_target (struct grub_video_render_target
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
-grub_err_t grub_video_set_mode (char *modestring,
+grub_err_t grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info));
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
new file mode 100644
index 0000000..9ae4101
--- /dev/null
+++ b/include/grub/video_fb.h
@@ -0,0 +1,137 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+
+/* 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;
+};
+
+#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
+extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
+
+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 d76e7fb..238e4cd 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -31,9 +31,7 @@
#include <grub/term.h>
#include <grub/cpu/linux.h>
#include <grub/video.h>
-/* FIXME: the definition of `struct grub_video_render_target' is
- VBE-specific. */
-#include <grub/i386/pc/vbe.h>
+#include <grub/video_fb.h>
#include <grub/command.h>
#define GRUB_LINUX_CL_OFFSET 0x1000
@@ -403,14 +401,11 @@ 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;
+ void *framebuffer;
int ret;
- ret = grub_video_get_info (&mode_info);
- if (ret)
- return 1;
+ ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
- ret = grub_video_get_active_render_target (&render_target);
if (ret)
return 1;
@@ -419,7 +414,7 @@ grub_linux_setup_video (struct linux_kernel_params *params)
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
- params->lfb_base = (grub_size_t) render_target->data;
+ params->lfb_base = (grub_size_t) framebuffer;
params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16;
params->red_mask_size = mode_info.red_mask_size;
@@ -449,41 +444,6 @@ grub_linux_boot (void)
params = real_mode_mem;
- modevar = grub_env_get ("gfxpayload");
-
- /* Now all graphical modes are acceptable.
- May change in future if we have modes without framebuffer. */
- if (modevar && *modevar != 0)
- {
- tmp = grub_malloc (grub_strlen (modevar)
- + sizeof (DEFAULT_VIDEO_MODE) + 1);
- if (! tmp)
- return grub_errno;
- grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
- err = grub_video_set_mode (tmp, 0);
- grub_free (tmp);
- }
-#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
- else
- err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
-#endif
-
- if (err)
- {
- grub_print_error ();
- grub_printf ("Booting however\n");
- grub_errno = GRUB_ERR_NONE;
- }
-
- if (! grub_linux_setup_video (params))
- params->have_vga = GRUB_VIDEO_TYPE_VLFB;
- else
- {
- params->have_vga = GRUB_VIDEO_TYPE_TEXT;
- params->video_width = 80;
- params->video_height = 25;
- }
-
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
(unsigned) params->code32_start,
(unsigned long) &(idt_desc.limit),
@@ -534,6 +494,41 @@ grub_linux_boot (void)
grub_mmap_iterate (hook);
params->mmap_size = e820_num;
+ modevar = grub_env_get ("gfxpayload");
+
+ /* Now all graphical modes are acceptable.
+ May change in future if we have modes without framebuffer. */
+ if (modevar && *modevar != 0)
+ {
+ tmp = grub_malloc (grub_strlen (modevar)
+ + sizeof (DEFAULT_VIDEO_MODE) + 1);
+ if (! tmp)
+ return grub_errno;
+ grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+ err = grub_video_set_mode (tmp, 0);
+ grub_free (tmp);
+ }
+#ifndef GRUB_ASSUME_LINUX_HAS_FB_SUPPORT
+ else
+ err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0);
+#endif
+
+ if (err)
+ {
+ grub_print_error ();
+ grub_printf ("Booting however\n");
+ grub_errno = GRUB_ERR_NONE;
+ }
+
+ if (! grub_linux_setup_video (params))
+ params->have_vga = GRUB_VIDEO_TYPE_VLFB;
+ else
+ {
+ params->have_vga = GRUB_VIDEO_TYPE_TEXT;
+ params->video_width = 80;
+ params->video_height = 25;
+ }
+
/* Initialize these last, because terminal position could be affected by printfs above. */
if (params->have_vga == GRUB_VIDEO_TYPE_TEXT)
{
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
index 037a713..69a9405 100644
--- a/loader/i386/pc/xnu.c
+++ b/loader/i386/pc/xnu.c
@@ -21,8 +21,7 @@
#include <grub/xnu.h>
#include <grub/mm.h>
#include <grub/cpu/xnu.h>
-#include <grub/machine/vbe.h>
-#include <grub/machine/vga.h>
+#include <grub/video_fb.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -43,10 +42,10 @@ 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;
int ret;
int x,y;
char *tmp, *modevar;
+ void *framebuffer;
grub_err_t err;
modevar = grub_env_get ("gfxpayload");
@@ -67,11 +66,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
if (err)
return err;
- ret = grub_video_get_info (&mode_info);
- 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_info_and_fini (&mode_info, &framebuffer);
if (ret)
return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
@@ -102,7 +97,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
params->lfb_depth = mode_info.bpp;
params->lfb_line_len = mode_info.pitch;
- params->lfb_base = PTR_TO_UINT32 (render_target->data);
+ params->lfb_base = PTR_TO_UINT32 (framebuffer);
params->lfb_mode = grub_xnu_bitmap
? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
new file mode 100644
index 0000000..c80f6ea
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fbblit.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/bitmap.h>
+
+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[GRUB_VIDEO_FBSTD_NUMCOLORS] =
+ {
+ // {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..67b724c 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -16,43 +16,17 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#define grub_video_render_target grub_video_fbrender_target
+
#include <grub/err.h>
#include <grub/machine/memory.h>
#include <grub/machine/vga.h>
#include <grub/machine/vbe.h>
-#include <grub/machine/vbeblit.h>
-#include <grub/machine/vbefill.h>
-#include <grub/machine/vbeutil.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/video.h>
-#include <grub/bitmap.h>
-
-/* 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;
@@ -142,6 +114,7 @@ grub_vbe_set_video_mode (grub_uint32_t mode,
{
grub_vbe_status_t status;
grub_uint32_t old_mode;
+ grub_err_t err;
/* Make sure that VBE is supported. */
grub_vbe_probe (0);
@@ -239,15 +212,26 @@ 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),
- 0,
- palette);
+ for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; 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 (GRUB_VIDEO_FBSTD_NUMCOLORS,
+ 0, palette);
/* Just ignore the status. */
+ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+ grub_video_fbstd_colors);
+ if (err)
+ return err;
+
}
}
@@ -308,43 +292,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)
{
@@ -385,11 +332,10 @@ grub_video_vbe_init (void)
return grub_errno;
}
- /* Reset frame buffer and render target variables. */
+ /* Reset frame buffer. */
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 +355,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 +367,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)
@@ -502,6 +446,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
/* Try to initialize best mode found. */
if (best_mode != 0)
{
+ grub_err_t err;
/* If this fails, then we have mode selection heuristics problem,
or adapter failure. */
grub_vbe_set_video_mode (best_mode, &active_mode_info);
@@ -512,56 +457,48 @@ 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.data = framebuffer.ptr;
+ 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;
+ /* Mark framebuffer memory as non allocated. */
+ framebuffer.render_target.is_allocated = 0;
/* 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;
- }
+ err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+ grub_video_fbstd_colors);
+ if (err)
+ return err;
- return GRUB_ERR_NONE;
+ /* Reset render target to framebuffer one. */
+ return grub_video_fb_set_active_render_target (&framebuffer.render_target);
}
/* Couldn't found matching mode. */
@@ -569,21 +506,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 +520,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_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 +547,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,128 +558,28 @@ 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;
- }
+ if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+ 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;
+ return grub_video_fb_set_active_render_target (target);
}
static grub_err_t
-grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
+grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuf)
{
- *target = render_target;
+ grub_err_t err;
+ err = grub_video_fb_get_info (mode_info);
+ if (err)
+ return err;
+ *framebuf = (char *) framebuffer.ptr;
return GRUB_ERR_NONE;
}
+
static struct grub_video_adapter grub_video_vbe_adapter =
{
.name = "VESA BIOS Extension Video Driver",
@@ -1602,24 +587,25 @@ 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,
+ .get_info_and_fini = grub_video_vbe_get_info_and_fini,
.set_palette = grub_video_vbe_set_palette,
- .get_palette = grub_video_vbe_get_palette,
+ .get_palette = grub_video_fb_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_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/video.c b/video/video.c
index c22947b..36ebfd1 100644
--- a/video/video.c
+++ b/video/video.c
@@ -93,6 +93,24 @@ grub_video_get_info (struct grub_video_mode_info *mode_info)
return grub_video_adapter_active->get_info (mode_info);
}
+/* Get information about active video mode. */
+grub_err_t
+grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+ void **framebuffer)
+{
+ grub_err_t err;
+
+ if (! grub_video_adapter_active)
+ return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+ err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer);
+ if (err)
+ return err;
+
+ grub_video_adapter_active = 0;
+ return GRUB_ERR_NONE;
+}
+
/* Determine optimized blitting formation for specified video mode info. */
enum grub_video_blit_format
grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
@@ -380,7 +398,7 @@ grub_video_get_active_render_target (struct grub_video_render_target **target)
}
grub_err_t
-grub_video_set_mode (char *modestring,
+grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info))
{
@@ -695,8 +713,6 @@ grub_video_set_mode (char *modestring,
/* Initialize Video API module. */
GRUB_MOD_INIT(video_video)
{
- grub_video_adapter_active = 0;
- grub_video_adapter_list = 0;
}
/* Finalize Video API module. */
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-02 22:01 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-08 19:06 ` Michal Suchanek
2009-08-08 22:03 ` Michal Suchanek
2009-08-10 12:30 ` Vladimir 'phcoder' Serbinenko
2009-08-09 11:55 ` Michal Suchanek
1 sibling, 2 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-08 19:06 UTC (permalink / raw)
To: The development of GRUB 2
Hello
I cannot get any sense of these patches "with moving code around
omitted" so I tried the git repository in Vladimir's signature.
Maybe I am missing something but the function of this code escapes me:
static grub_err_t
grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
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. */
if (x > active_mode_info.x_resolution)
{
x = 0;
width = 0;
}
if (y > active_mode_info.y_resolution)
{
y = 0;
height = 0;
}
if (x + width > active_mode_info.x_resolution)
width = active_mode_info.x_resolution - x;
if (y + height > active_mode_info.y_resolution)
height = active_mode_info.y_resolution - y;
return grub_video_fb_set_viewport (x, y, width, height);
}
As I understand it the code checks the bounds against the active
videomode and then sets the viewport on the active render target.
Since the active render target can be arbitrarily set by the user (to,
say an offscreen bitmap for rendering the terminal text) I do not see
how these two parts match.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-08 19:06 ` Michal Suchanek
@ 2009-08-08 22:03 ` Michal Suchanek
2009-08-10 12:30 ` Vladimir 'phcoder' Serbinenko
1 sibling, 0 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-08 22:03 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/8 Michal Suchanek <hramrach@centrum.cz>:
> Hello
>
> I cannot get any sense of these patches "with moving code around
> omitted" so I tried the git repository in Vladimir's signature.
>
> Maybe I am missing something but the function of this code escapes me:
>
> static grub_err_t
> grub_video_vbe_set_viewport (unsigned int x, unsigned int y,
> 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. */
> if (x > active_mode_info.x_resolution)
> {
> x = 0;
> width = 0;
> }
>
> if (y > active_mode_info.y_resolution)
> {
> y = 0;
> height = 0;
> }
>
> if (x + width > active_mode_info.x_resolution)
> width = active_mode_info.x_resolution - x;
>
> if (y + height > active_mode_info.y_resolution)
> height = active_mode_info.y_resolution - y;
> return grub_video_fb_set_viewport (x, y, width, height);
> }
>
> As I understand it the code checks the bounds against the active
> videomode and then sets the viewport on the active render target.
> Since the active render target can be arbitrarily set by the user (to,
> say an offscreen bitmap for rendering the terminal text) I do not see
> how these two parts match.
>
It seems that this check should be done in grub_video_fb_set_viewport
instead, and this function completely eliminated until viewport on
non-active target can be set. The assumption about bounds being
checked beforehand could break for the blit* functions in fbblit.c
because the video_fb blit dispatcher only checks viewport on the
target, and viewport is not checked against mode when set.
There is get_data_ptr in fbutil.c and grub_video_fb_get_video_ptr in
video_fb.c that seem to do the same thing. They do not have the
warning abut bounds checking which they do not do. This warning is
also missing from get/set_pixel.
Perhaps there should also be get/set_pixel method for video adapters?
The functions in fbutil.c probably should not be used from outside fb
this library but there are no user counterparts in video_fb.c
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-02 22:01 ` Vladimir 'phcoder' Serbinenko
2009-08-08 19:06 ` Michal Suchanek
@ 2009-08-09 11:55 ` Michal Suchanek
2009-08-10 12:36 ` Vladimir 'phcoder' Serbinenko
1 sibling, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-09 11:55 UTC (permalink / raw)
To: The development of GRUB 2
Hello,
both in the previous complete patch and Vladimir's git repository
introduce a grub_video_rect_t type.
Is there some intention to change the interface to use this structure?
I was looking at the the various places that use points and
rectangles. It's quite inconsistent and unclear now.
There is an anonymous viewport structure inside render target which is
the same as the rectangle type. Many coordinates and sizes are signed
and many are unsigned leading to numerous casts and/or signed vs
unsigned comparison warnings.
The blit functions take a rectangle and a point specified as six
separate integers which makes it somewhat unclear what is what.
The other thing that bothers me is that the video drivers fill in the
render target structure during video initialization.
In my view the render target structure should not be public. The video
driver should fill in the video mode structure and then call a
function that fills in render target based on video mode and video
data (framebuffer memory). This code is currently replicated
needlessly in the vbe and sdl drivers.
Bitmaps could be created in the same way.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-08 19:06 ` Michal Suchanek
2009-08-08 22:03 ` Michal Suchanek
@ 2009-08-10 12:30 ` Vladimir 'phcoder' Serbinenko
1 sibling, 0 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-10 12:30 UTC (permalink / raw)
To: The development of GRUB 2
>
> As I understand it the code checks the bounds against the active
> videomode and then sets the viewport on the active render target.
> Since the active render target can be arbitrarily set by the user (to,
> say an offscreen bitmap for rendering the terminal text) I do not see
> how these two parts match.
Well this code was already there before my patch. I just restructured
it. It basically requires viewport to be legal. For offscreen
rendering use allocate_render_target
In my patch I tried not to modify the behaviour as far as possible.
Your comments about improving the design are welcome but could you
start a separate thread? If an improvement that you propose is small
in code send a patch together with proposal - it allows to speak about
something that is here rather something that could be. If it's bigger
then discuss before implementing, perhaps send a small pseudo-patch
which shows how it will be implemented. Pseudo patches don't have to
work but are just for discussion.
>
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-09 11:55 ` Michal Suchanek
@ 2009-08-10 12:36 ` Vladimir 'phcoder' Serbinenko
2009-08-10 13:34 ` Michal Suchanek
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-10 12:36 UTC (permalink / raw)
To: The development of GRUB 2
On Sun, Aug 9, 2009 at 1:55 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> Hello,
>
> both in the previous complete patch and Vladimir's git repository
> introduce a grub_video_rect_t type.
This is from Collin's double buffering patch.
> The other thing that bothers me is that the video drivers fill in the
> render target structure during video initialization.
>
> In my view the render target structure should not be public.
It isn't. If you read the code you'll see that video_render_target is
anonymous structure except in drivers.
> The video
> driver should fill in the video mode structure and then call a
> function that fills in render target based on video mode and video
> data (framebuffer memory). This code is currently replicated
> needlessly in the vbe and sdl drivers.
I split on the most natural spot I found - render targets. Everything
that works with render targets is moved to video_fb. Perhaps it's not
the best spot but cutting at natural function ensures drivers won't
have to undo something video_fb does. In future if drivers share code
which can be moved to vide_fb then I'm ok with it but I prefer to see
more real drivers first before fine-tuning split limit especially away
fro ma natural spot
As for moving data from video info to render target the problem is
that video_fb can't be aware about the structures used by drivers. and
so I see no way around it
>
> Bitmaps could be created in the same way.
>
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 12:36 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-10 13:34 ` Michal Suchanek
2009-08-10 14:11 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-10 13:34 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Sun, Aug 9, 2009 at 1:55 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> Hello,
>>
>> both in the previous complete patch and Vladimir's git repository
>> introduce a grub_video_rect_t type.
> This is from Collin's double buffering patch.
OK, let's drop rectangles from here.
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>
>> As I understand it the code checks the bounds against the active
>> videomode and then sets the viewport on the active render target.
>> Since the active render target can be arbitrarily set by the user (to,
>> say an offscreen bitmap for rendering the terminal text) I do not see
>> how these two parts match.
> Well this code was already there before my patch. I just restructured
> it. It basically requires viewport to be legal. For offscreen
If the code works the way described above than it requires the
viewport to be inside the videomode bounds for any render target for
which viewport is set, including offscreen targets. This is not what
legal veiwport is about.
If it was broken to start with then it should be perhaps fixed in a
separate patch before the split.
> rendering use allocate_render_target
> In my patch I tried not to modify the behaviour as far as possible.
> Your comments about improving the design are welcome but could you
> start a separate thread? If an improvement that you propose is small
> in code send a patch together with proposal - it allows to speak about
> something that is here rather something that could be. If it's bigger
> then discuss before implementing, perhaps send a small pseudo-patch
> which shows how it will be implemented. Pseudo patches don't have to
> work but are just for discussion.
I can try to put together a patch that fixes this. It is not unrelated
to the fb split, though. The driver code messes with the wrong
structure here because it tries to do what should be done at the fb
level.
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Sun, Aug 9, 2009 at 1:55 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> The other thing that bothers me is that the video drivers fill in the
>> render target structure during video initialization.
>>
>> In my view the render target structure should not be public.
> It isn't. If you read the code you'll see that video_render_target is
> anonymous structure except in drivers.
Yes, but the driver that uses the fb library to handle rendering need
not touch the render target.
>> The video
>> driver should fill in the video mode structure and then call a
>> function that fills in render target based on video mode and video
>> data (framebuffer memory). This code is currently replicated
>> needlessly in the vbe and sdl drivers.
> I split on the most natural spot I found - render targets. Everything
> that works with render targets is moved to video_fb. Perhaps it's not
That's the point here. There are two places in the driver that work
with render targets but the code was not moved to video_fb.
One is the filling out of the render target structure, the other is
the bounds checking for viewport.
> the best spot but cutting at natural function ensures drivers won't
> have to undo something video_fb does. In future if drivers share code
> which can be moved to vide_fb then I'm ok with it but I prefer to see
> more real drivers first before fine-tuning split limit especially away
> fro ma natural spot
What I want to do here is the split to be exactly at the natural spot
- video_fb works with render targets, everything outside of there uses
them as opaque structures.
If other drivers used different (accelerated) rendering methods but
implemented only some of the rendering functions then sharing of the
framebuffer might be possible by using two render targets - one for
the accelerated operations, the other for video_fb operations. Making
that work with things like doublebufferenig might be somewhat
challenging, though.
> As for moving data from video info to render target the problem is
> that video_fb can't be aware about the structures used by drivers. and
> so I see no way around it
I do not want to move any data here.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 13:34 ` Michal Suchanek
@ 2009-08-10 14:11 ` Vladimir 'phcoder' Serbinenko
2009-08-10 14:38 ` Michal Suchanek
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-10 14:11 UTC (permalink / raw)
To: The development of GRUB 2
>
>
> 2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>>
>>> As I understand it the code checks the bounds against the active
>>> videomode and then sets the viewport on the active render target.
>>> Since the active render target can be arbitrarily set by the user (to,
>>> say an offscreen bitmap for rendering the terminal text) I do not see
>>> how these two parts match.
>> Well this code was already there before my patch. I just restructured
>> it. It basically requires viewport to be legal. For offscreen
>
> If the code works the way described above than it requires the
> viewport to be inside the videomode bounds for any render target for
> which viewport is set, including offscreen targets. This is not what
> legal veiwport is about.
>
> If it was broken to start with then it should be perhaps fixed in a
> separate patch before the split.
>
Nothing is broken here. Just we don't use the things like setting
viewport outside the real screen. For offscreen rendering use
grub_video_create_render_target and then blit it later on. I like this
way. Unlike setting viewport to invisible coordinates it's clean and
doesn't create any issues if two parts of code decide to use the same
invisible offset. If you want us to consider to change this way of
doing you need to provide a useful testcase. Just tearing downing
existing, working and tested code without benefit isn't good.
> I can try to put together a patch that fixes this. It is not unrelated
> to the fb split, though. The driver code messes with the wrong
> structure here because it tries to do what should be done at the fb
> level.
Retrieving framebuffer address and parameters has to be done in
driver. Using any special functions to encapsulate this information
just leads to more calls and troubles for double buffering. The design
of video_fb.c is that it does only what it's explicitly asked to do
and doesn't try to be complete driver
>> It isn't. If you read the code you'll see that video_render_target is
>> anonymous structure except in drivers.
>
> Yes, but the driver that uses the fb library to handle rendering need
> not touch the render target.
Why not? It just passes parameters to values this way
> That's the point here. There are two places in the driver that work
> with render targets but the code was not moved to video_fb.
>
> One is the filling out of the render target structure, the other is
> the bounds checking for viewport.
Both pieces of code check against the current mode. It's just because
vbe does most of job for us that this code is a bunch of assignments
but it may be more complex. I don't see what your problem with filling
render target about screen parameters is
> What I want to do here is the split to be exactly at the natural spot
> - video_fb works with render targets, everything outside of there uses
> them as opaque structures.
>
Then you pass video mode info which is just a screen render target
>
> If other drivers used different (accelerated) rendering methods but
> implemented only some of the rendering functions then sharing of the
> framebuffer might be possible by using two render targets - one for
> the accelerated operations, the other for video_fb operations.
Actually this is another point why driver should be able to manipulate
framebuffer render targets. If you use acceleration then you may have
something different than a normal framebuffer. Trying to use
framebuffer on a screen as whole will cause strange effects. The
driver may however ask video_fb to do operations on some parts of
screen which are framebuffers even when the whole screen isn't. In
this case it's the responsibility of driver to determine which
accelerated render target corresponds to which framebuffer render
target
>
>> As for moving data from video info to render target the problem is
>> that video_fb can't be aware about the structures used by drivers. and
>> so I see no way around it
>
> I do not want to move any data here.
Well it's exactly what you ask.
>
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 14:11 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-10 14:38 ` Michal Suchanek
2009-08-10 15:10 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-10 14:38 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>
>>
>> 2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>>>
>>>> As I understand it the code checks the bounds against the active
>>>> videomode and then sets the viewport on the active render target.
>>>> Since the active render target can be arbitrarily set by the user (to,
>>>> say an offscreen bitmap for rendering the terminal text) I do not see
>>>> how these two parts match.
>>> Well this code was already there before my patch. I just restructured
>>> it. It basically requires viewport to be legal. For offscreen
>>
>> If the code works the way described above than it requires the
>> viewport to be inside the videomode bounds for any render target for
>> which viewport is set, including offscreen targets. This is not what
>> legal veiwport is about.
>>
>> If it was broken to start with then it should be perhaps fixed in a
>> separate patch before the split.
>>
> Nothing is broken here. Just we don't use the things like setting
> viewport outside the real screen. For offscreen rendering use
> grub_video_create_render_target and then blit it later on. I like this
Yes, but set_viewport works on the active target. You create an
offscreen target and set it as the active target and want to set the
viewport on it. Depending on its size this function either needlessly
limits you to the current screen mode or allows illegal viewport to be
set.
It simply compares apples and oranges.
> way. Unlike setting viewport to invisible coordinates it's clean and
> doesn't create any issues if two parts of code decide to use the same
> invisible offset. If you want us to consider to change this way of
> doing you need to provide a useful testcase. Just tearing downing
> existing, working and tested code without benefit isn't good.
I do not want to tear it down - just move the check to video_fb and
check against the video mode info provided with the target rather
than the active video mode which should do the right thing for the
screen framebuffer as well as offscreen targets.
It might just happen to do the right thing now because nobody uses
render targets larger than the screen and everybody sets the viewport
sane so the check is not needed but it's broken nonetheless.
>
>> I can try to put together a patch that fixes this. It is not unrelated
>> to the fb split, though. The driver code messes with the wrong
>> structure here because it tries to do what should be done at the fb
>> level.
> Retrieving framebuffer address and parameters has to be done in
> driver. Using any special functions to encapsulate this information
> just leads to more calls and troubles for double buffering. The design
> of video_fb.c is that it does only what it's explicitly asked to do
> and doesn't try to be complete driver
That's completely fine.
I just want the drivers not touch the render target structure so that
it is possible to add features to video_fb (such as framebuffer
rotation) later without breaking the drivers that do not use them.
>>> It isn't. If you read the code you'll see that video_render_target is
>>> anonymous structure except in drivers.
>>
>> Yes, but the driver that uses the fb library to handle rendering need
>> not touch the render target.
> Why not? It just passes parameters to values this way
Because it breaks encapsulation and needlessly duplicates code.
>> That's the point here. There are two places in the driver that work
>> with render targets but the code was not moved to video_fb.
>>
>> One is the filling out of the render target structure, the other is
>> the bounds checking for viewport.
> Both pieces of code check against the current mode. It's just because
> vbe does most of job for us that this code is a bunch of assignments
> but it may be more complex. I don't see what your problem with filling
> render target about screen parameters is
Exactly that it may get more complex. You have to change the code in
all drivers then.
>> What I want to do here is the split to be exactly at the natural spot
>> - video_fb works with render targets, everything outside of there uses
>> them as opaque structures.
>>
> Then you pass video mode info which is just a screen render target
Yes, without any needless redundancy.
>>
>> If other drivers used different (accelerated) rendering methods but
>> implemented only some of the rendering functions then sharing of the
>> framebuffer might be possible by using two render targets - one for
>> the accelerated operations, the other for video_fb operations.
> Actually this is another point why driver should be able to manipulate
> framebuffer render targets. If you use acceleration then you may have
> something different than a normal framebuffer. Trying to use
> framebuffer on a screen as whole will cause strange effects. The
> driver may however ask video_fb to do operations on some parts of
> screen which are framebuffers even when the whole screen isn't. In
> this case it's the responsibility of driver to determine which
> accelerated render target corresponds to which framebuffer render
> target
For that they should be able to create and use render targets but not
manipulate them directly.
>>
>>> As for moving data from video info to render target the problem is
>>> that video_fb can't be aware about the structures used by drivers. and
>>> so I see no way around it
>>
>> I do not want to move any data here.
> Well it's exactly what you ask.
Where?
The mode_info is already part of the framebuffer so I only ask that
the driver fills in the mode_info and has a render target created from
that rather than creating a render target itself.
If features are later added to the render target (such as rotation)
this code needs to be aware of them. However, if the structure was
filled out in fb_video then these new features are transparent.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 14:38 ` Michal Suchanek
@ 2009-08-10 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-10 18:41 ` Michal Suchanek
2009-08-12 13:08 ` Michal Suchanek
0 siblings, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-10 15:10 UTC (permalink / raw)
To: The development of GRUB 2
On Mon, Aug 10, 2009 at 4:38 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> Yes, but set_viewport works on the active target. You create an
> offscreen target and set it as the active target and want to set the
> viewport on it. Depending on its size this function either needlessly
> limits you to the current screen mode or allows illegal viewport to be
> set.
>
> It simply compares apples and oranges.
>
Fixed in repo. New patch is coming after testing
> I just want the drivers not touch the render target structure so that
> it is possible to add features to video_fb (such as framebuffer
> rotation) later without breaking the drivers that do not use them.
>
> Because it breaks encapsulation and needlessly duplicates code.
I'm not sure that encapsulation is good in this particular case.
Clearly the driver should take the lead and not the framebuffer
library. Now it's coded with "library of functions" concept and
changing concept will put strains on drivers. I don't know which
approach is better in a long run
>> Both pieces of code check against the current mode. It's just because
>> vbe does most of job for us that this code is a bunch of assignments
>> but it may be more complex. I don't see what your problem with filling
>> render target about screen parameters is
>
> Exactly that it may get more complex. You have to change the code in
> all drivers then.
Why? Driver just sets fields framebuf? In which cases does it need to
be modified?
>> Then you pass video mode info which is just a screen render target
>
> Yes, without any needless redundancy.
Passing framebuffer parameters one way or another you have redundancy
> For that they should be able to create and use render targets but not
> manipulate them directly.
>
They do. They need to say "this render target is at ... with these parameters"
>
> The mode_info is already part of the framebuffer so I only ask that
> the driver fills in the mode_info and has a render target created from
> that rather than creating a render target itself.
mode_info lacks crucial data like framebuffer address.
> If features are later added to the render target (such as rotation)
> this code needs to be aware of them. However, if the structure was
> filled out in fb_video then these new features are transparent.
>
But if a driver partially accelerates rotation it needs to tell which
buffers are rotated and which aren't. Basically we have 2 possible
benefits but I'm not sure which one is better. What do others think?
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 15:10 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-10 18:41 ` Michal Suchanek
2009-08-10 19:43 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:08 ` Michal Suchanek
1 sibling, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-10 18:41 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Mon, Aug 10, 2009 at 4:38 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> Yes, but set_viewport works on the active target. You create an
>> offscreen target and set it as the active target and want to set the
>> viewport on it. Depending on its size this function either needlessly
>> limits you to the current screen mode or allows illegal viewport to be
>> set.
>>
>> It simply compares apples and oranges.
>>
> Fixed in repo. New patch is coming after testing
Thanks
>> I just want the drivers not touch the render target structure so that
>> it is possible to add features to video_fb (such as framebuffer
>> rotation) later without breaking the drivers that do not use them.
>>
>> Because it breaks encapsulation and needlessly duplicates code.
> I'm not sure that encapsulation is good in this particular case.
> Clearly the driver should take the lead and not the framebuffer
> library. Now it's coded with "library of functions" concept and
> changing concept will put strains on drivers. I don't know which
> approach is better in a long run
>>> Both pieces of code check against the current mode. It's just because
>>> vbe does most of job for us that this code is a bunch of assignments
>>> but it may be more complex. I don't see what your problem with filling
>>> render target about screen parameters is
>>
>> Exactly that it may get more complex. You have to change the code in
>> all drivers then.
> Why? Driver just sets fields framebuf? In which cases does it need to
> be modified?
>>> Then you pass video mode info which is just a screen render target
>>
>> Yes, without any needless redundancy.
> Passing framebuffer parameters one way or another you have redundancy
>> For that they should be able to create and use render targets but not
>> manipulate them directly.
>>
> They do. They need to say "this render target is at ... with these parameters"
>>
>> The mode_info is already part of the framebuffer so I only ask that
>> the driver fills in the mode_info and has a render target created from
>> that rather than creating a render target itself.
> mode_info lacks crucial data like framebuffer address.
Yes, it does.
I would like a video_fb function like
grub_video_fb_create_render_target_from_buffer(void * buffer, int
allocated, const grub_video_mode_info_t * mode_info)
>> If features are later added to the render target (such as rotation)
>> this code needs to be aware of them. However, if the structure was
>> filled out in fb_video then these new features are transparent.
>>
> But if a driver partially accelerates rotation it needs to tell which
> buffers are rotated and which aren't. Basically we have 2 possible
Yes, and it can create them rotated or not as appropriate (and specify
that in the mode_info). If the rotation is done in hardware then it
should be transparent and the buffer is effectively non-rotated as far
as video_fb cares.
> benefits but I'm not sure which one is better. What do others think?
I am sure that for doing transparent rotation in video_fb
encapsulation is good. I can do without it or patch it in with the
rotation if I get it into working state.
The only other users of the render_target structure are drivers and
from what I have seen so far they should better be kept at good
distance from it.
However, an opinion of somebody else who looks at the graphics
subsystem would be welcome.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 18:41 ` Michal Suchanek
@ 2009-08-10 19:43 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:17 ` Michal Suchanek
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-10 19:43 UTC (permalink / raw)
To: The development of GRUB 2
> I would like a video_fb function like
> grub_video_fb_create_render_target_from_buffer(void * buffer, int
> allocated, const grub_video_mode_info_t * mode_info)
Well this is pretty much what we do directly. New fields can be added
to fbrender_target with no problem. (btw currently driver manages only
screen render target and completely delegates other functions to
video_fb)
> I am sure that for doing transparent rotation in video_fb
> encapsulation is good. I can do without it or patch it in with the
> rotation if I get it into working state.
Actually it's enough to follow simple rules like
blitting target on target isn't rotated but coordinates are adjusted
blitting non-target on target is rotated.
This way video adapter doesn't have to know about nature of blitting operations.
Anyway you need to adjust width and height returned by mode_info.
A function video_fb_transform_coordinates can do this. This way
framebuffer can apply any transformation, not just rotation w/o driver
to know.
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-10 18:41 ` Michal Suchanek
@ 2009-08-12 13:08 ` Michal Suchanek
2009-08-12 13:16 ` Vladimir 'phcoder' Serbinenko
1 sibling, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-12 13:08 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Mon, Aug 10, 2009 at 4:38 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> Yes, but set_viewport works on the active target. You create an
>> offscreen target and set it as the active target and want to set the
>> viewport on it. Depending on its size this function either needlessly
>> limits you to the current screen mode or allows illegal viewport to be
>> set.
>>
>> It simply compares apples and oranges.
>>
> Fixed in repo. New patch is coming after testing
Does not build.
Otherwise it works as expected. I can build a rescue CD with gfxterm
and a lame background image.
Thanks
Michal
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
index ac9eb4b..f97d7ac 100644
--- a/video/fb/video_fb.c
+++ b/video/fb/video_fb.c
@@ -160,23 +160,23 @@ grub_video_fb_set_viewport (unsigned int x,
unsigned int y,
{
/* Make sure viewport is withing screen dimensions. If viewport was set
to be out of the region, mark its size as zero. */
- if (x > render_target->mode_info.x_resolution)
+ if (x > render_target->mode_info.width)
{
x = 0;
width = 0;
}
- if (y > render_target->mode_info.y_resolution)
+ if (y > render_target->mode_info.height)
{
y = 0;
height = 0;
}
- if (x + width > render_target->mode_info.x_resolution)
- width = render_target->mode_info.x_resolution - x;
+ if (x + width > render_target->mode_info.width)
+ width = render_target->mode_info.width - x;
- if (y + height > render_target->mode_info.y_resolution)
- height = render_target->mode_info.y_resolution - y;
+ if (y + height > render_target->mode_info.height)
+ height = render_target->mode_info.height - y;
render_target->viewport.x = x;
render_target->viewport.y = y;
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-12 13:08 ` Michal Suchanek
@ 2009-08-12 13:16 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:38 ` Michal Suchanek
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-12 13:16 UTC (permalink / raw)
To: The development of GRUB 2
On Wed, Aug 12, 2009 at 3:08 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> 2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>> On Mon, Aug 10, 2009 at 4:38 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>>> Yes, but set_viewport works on the active target. You create an
>>> offscreen target and set it as the active target and want to set the
>>> viewport on it. Depending on its size this function either needlessly
>>> limits you to the current screen mode or allows illegal viewport to be
>>> set.
>>>
>>> It simply compares apples and oranges.
>>>
>> Fixed in repo. New patch is coming after testing
>
> Does not build.
>
> Otherwise it works as expected. I can build a rescue CD with gfxterm
> and a lame background image.
>
Thank you for testing (unfortunately I didn't come to this yet). Your
fix is applied to my repo
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-10 19:43 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-12 13:17 ` Michal Suchanek
2009-08-12 13:45 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-12 13:17 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>> I would like a video_fb function like
>> grub_video_fb_create_render_target_from_buffer(void * buffer, int
>> allocated, const grub_video_mode_info_t * mode_info)
> Well this is pretty much what we do directly. New fields can be added
> to fbrender_target with no problem. (btw currently driver manages only
> screen render target and completely delegates other functions to
> video_fb)
>> I am sure that for doing transparent rotation in video_fb
>> encapsulation is good. I can do without it or patch it in with the
>> rotation if I get it into working state.
> Actually it's enough to follow simple rules like
> blitting target on target isn't rotated but coordinates are adjusted
Why would it not be rotated?
Depending on the direction of the two targets a transformation may apply.
> blitting non-target on target is rotated.
If non-target does not support rotation then there is no other
possibility, obviously.
> This way video adapter doesn't have to know about nature of blitting operations.
> Anyway you need to adjust width and height returned by mode_info.
> A function video_fb_transform_coordinates can do this. This way
Yes, it can. However, driver unaware of rotation won't use it which is
why I want it to be internal to video_fb at least for drivers that do
not implement any operations themselves.
> framebuffer can apply any transformation, not just rotation w/o driver
> to know.
Obviously, the video_fb can do anything (within reason - it needs to
follow the current interface) behind the driver's back as long as
there is working encapsulation in place.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-12 13:16 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-12 13:38 ` Michal Suchanek
0 siblings, 0 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-12 13:38 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/12 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Wed, Aug 12, 2009 at 3:08 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> 2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>> On Mon, Aug 10, 2009 at 4:38 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
>>>> Yes, but set_viewport works on the active target. You create an
>>>> offscreen target and set it as the active target and want to set the
>>>> viewport on it. Depending on its size this function either needlessly
>>>> limits you to the current screen mode or allows illegal viewport to be
>>>> set.
>>>>
>>>> It simply compares apples and oranges.
>>>>
>>> Fixed in repo. New patch is coming after testing
>>
>> Does not build.
>>
>> Otherwise it works as expected. I can build a rescue CD with gfxterm
>> and a lame background image.
>>
> Thank you for testing (unfortunately I didn't come to this yet). Your
> fix is applied to my repo
There is the same broken code (although unused) in master/util/sdl.c
Thanks
Michal
diff --git a/util/sdl.c b/util/sdl.c
index 3d0a637..72abac5 100644
--- a/util/sdl.c
+++ b/util/sdl.c
@@ -165,32 +165,6 @@ grub_video_sdl_set_palette (unsigned int start,
unsigned int count,
return grub_video_fb_set_palette (start, count, palette_data);
}
-grub_err_t
-grub_video_sdl_set_viewport (unsigned int x, unsigned int y,
- 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. */
- if (x > (unsigned) window->w)
- {
- x = 0;
- width = 0;
- }
-
- if (y > (unsigned) window->h)
- {
- y = 0;
- height = 0;
- }
-
- if (x + width > (unsigned) window->w)
- width = window->w - x;
-
- if (y + height > (unsigned) window->h)
- height = window->h - y;
- return grub_video_fb_set_viewport (x, y, width, height);
-}
-
static grub_err_t
grub_video_sdl_swap_buffers (void)
{
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-12 13:17 ` Michal Suchanek
@ 2009-08-12 13:45 ` Vladimir 'phcoder' Serbinenko
2009-08-13 15:59 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-12 13:45 UTC (permalink / raw)
To: The development of GRUB 2
On Wed, Aug 12, 2009 at 3:17 PM, Michal Suchanek<hramrach@centrum.cz> wrote:
> 2009/8/10 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>> I would like a video_fb function like
>>> grub_video_fb_create_render_target_from_buffer(void * buffer, int
>>> allocated, const grub_video_mode_info_t * mode_info)
>> Well this is pretty much what we do directly. New fields can be added
>> to fbrender_target with no problem. (btw currently driver manages only
>> screen render target and completely delegates other functions to
>> video_fb)
>>> I am sure that for doing transparent rotation in video_fb
>>> encapsulation is good. I can do without it or patch it in with the
>>> rotation if I get it into working state.
>> Actually it's enough to follow simple rules like
>> blitting target on target isn't rotated but coordinates are adjusted
>
>> framebuffer can apply any transformation, not just rotation w/o driver
>> to know.
>
> Obviously, the video_fb can do anything (within reason - it needs to
> follow the current interface) behind the driver's back as long as
> there is working encapsulation in place.
Considering that vbe.c and sdl.c currently aren't affected a lot
whether there is or there isn't encapsulation in place, I'm ok tih
encapsulating it but if any driver needs the breach of encapsulation
it will be broken and I'll post no opposition to it.
I'll do the encapsulation tomorrow.
>
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-12 13:45 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-13 15:59 ` Vladimir 'phcoder' Serbinenko
2009-08-13 19:41 ` Robert Millan
2009-08-14 0:13 ` Michal Suchanek
0 siblings, 2 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-13 15:59 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 803 bytes --]
> Considering that vbe.c and sdl.c currently aren't affected a lot
> whether there is or there isn't encapsulation in place, I'm ok tih
> encapsulating it but if any driver needs the breach of encapsulation
> it will be broken and I'll post no opposition to it.
> I'll do the encapsulation tomorrow.
Patch attached. One incremental version (for review) and one complete
(for patching)
>>
>> Thanks
>>
>> Michal
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
[-- Attachment #2: framebuf-add.diff --]
[-- Type: text/plain, Size: 9593 bytes --]
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
index 11e22c6..08cd7b8 100644
--- a/include/grub/fbfill.h
+++ b/include/grub/fbfill.h
@@ -24,6 +24,29 @@
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;
+};
+
void
grub_video_fbfill (struct grub_video_fbblit_info *dst,
grub_video_color_t color, int x, int y,
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
index 9ae4101..03ef385 100644
--- a/include/grub/video_fb.h
+++ b/include/grub/video_fb.h
@@ -28,28 +28,7 @@
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_fbrender_target;
#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
@@ -126,6 +105,11 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
unsigned int mode_type __attribute__ ((unused)));
grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+ const struct grub_video_mode_info *mode_info,
+ void *ptr);
+
+grub_err_t
grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
grub_err_t
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
index f97d7ac..e4f8f6d 100644
--- a/video/fb/video_fb.c
+++ b/video/fb/video_fb.c
@@ -1081,6 +1081,45 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
}
grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+ const struct grub_video_mode_info *mode_info,
+ void *ptr)
+{
+ struct grub_video_fbrender_target *target;
+ unsigned y;
+
+ /* Allocate memory for render target. */
+ target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+ if (! target)
+ return grub_errno;
+
+ /* Mark render target as unallocated. */
+ target->is_allocated = 0;
+ target->data = ptr;
+
+ grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
+
+ /* Reset viewport to match new mode. */
+ target->viewport.x = 0;
+ target->viewport.y = 0;
+ target->viewport.width = mode_info->width;
+ target->viewport.height = mode_info->height;
+
+ /* Mark framebuffer memory as non allocated. */
+ target->is_allocated = 0;
+
+ /* Clear render target with black and maximum transparency. */
+ for (y = 0; y < mode_info->height; y++)
+ grub_memset (target->data + mode_info->pitch * y, 0,
+ mode_info->bytes_per_pixel * mode_info->width);
+
+ /* 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. */
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
index f73242f..1a0f587 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -35,7 +35,8 @@ static struct grub_vbe_mode_info_block active_mode_info;
static struct
{
- struct grub_video_render_target render_target;
+ struct grub_video_mode_info mode_info;
+ struct grub_video_render_target *render_target;
unsigned int bytes_per_scan_line;
unsigned int bytes_per_pixel;
@@ -475,39 +476,29 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
in order to fasten later operations. */
mode_in_use = best_mode;
- /* Fill mode info details in framebuffer's render target. */
- framebuffer.render_target.data = framebuffer.ptr;
- framebuffer.render_target.mode_info.width = active_mode_info.x_resolution;
- framebuffer.render_target.mode_info.height = active_mode_info.y_resolution;
+ /* Fill mode info details. */
+ framebuffer.mode_info.width = active_mode_info.x_resolution;
+ framebuffer.mode_info.height = active_mode_info.y_resolution;
if (framebuffer.index_color_mode)
- framebuffer.render_target.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+ framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
else
- 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. */
- 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;
-
- /* Mark framebuffer memory as non allocated. */
- framebuffer.render_target.is_allocated = 0;
+ framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+
+ framebuffer.mode_info.bpp = active_mode_info.bits_per_pixel;
+ framebuffer.mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
+ framebuffer.mode_info.pitch = framebuffer.bytes_per_scan_line;
+ framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me. */
+ framebuffer.mode_info.red_mask_size = active_mode_info.red_mask_size;
+ framebuffer.mode_info.red_field_pos = active_mode_info.red_field_position;
+ framebuffer.mode_info.green_mask_size = active_mode_info.green_mask_size;
+ framebuffer.mode_info.green_field_pos = active_mode_info.green_field_position;
+ framebuffer.mode_info.blue_mask_size = active_mode_info.blue_mask_size;
+ framebuffer.mode_info.blue_field_pos = active_mode_info.blue_field_position;
+ framebuffer.mode_info.reserved_mask_size = active_mode_info.rsvd_mask_size;
+ framebuffer.mode_info.reserved_field_pos = active_mode_info.rsvd_field_position;
+
+ framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
/* Copy default palette to initialize emulated palette. */
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
@@ -515,8 +506,12 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
if (err)
return err;
- /* Reset render target to framebuffer one. */
- return grub_video_fb_set_active_render_target (&framebuffer.render_target);
+ err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
+ if (err)
+ return err;
+
+ return grub_video_fb_set_active_render_target (framebuffer.render_target);
}
/* Couldn't found matching mode. */
@@ -553,7 +548,7 @@ static grub_err_t
grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
{
if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
- target = &framebuffer.render_target;
+ target = framebuffer.render_target;
return grub_video_fb_set_active_render_target (target);
}
@@ -562,12 +557,14 @@ static grub_err_t
grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
void **framebuf)
{
- grub_err_t err;
- err = grub_video_fb_get_info (mode_info);
- if (err)
- return err;
+ grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
*framebuf = (char *) framebuffer.ptr;
+ grub_free (mode_list);
+ mode_list = 0;
+
+ grub_video_fb_fini ();
+
return GRUB_ERR_NONE;
}
[-- Attachment #3: framebuf.diff.gz --]
[-- Type: application/x-gzip, Size: 25877 bytes --]
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-13 15:59 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-13 19:41 ` Robert Millan
2009-08-13 20:36 ` Vladimir 'phcoder' Serbinenko
2009-08-14 0:13 ` Michal Suchanek
1 sibling, 1 reply; 47+ messages in thread
From: Robert Millan @ 2009-08-13 19:41 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Aug 13, 2009 at 05:59:11PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> > Considering that vbe.c and sdl.c currently aren't affected a lot
> > whether there is or there isn't encapsulation in place, I'm ok tih
> > encapsulating it but if any driver needs the breach of encapsulation
> > it will be broken and I'll post no opposition to it.
> > I'll do the encapsulation tomorrow.
> Patch attached. One incremental version (for review) and one complete
> (for patching)
Please go ahead (I assume it raises no warnings and it's well tested).
One small detail:
> + grub_free (mode_list);
> + mode_list = 0;
I would prefer if we used NULL for pointers. I know we don't do that
everywhere, but it makes code easier to understand.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-13 19:41 ` Robert Millan
@ 2009-08-13 20:36 ` Vladimir 'phcoder' Serbinenko
2009-08-13 21:01 ` Robert Millan
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-13 20:36 UTC (permalink / raw)
To: The development of GRUB 2
> Please go ahead (I assume it raises no warnings and it's well tested).
I tested the latest version with gfxterm and xnu loader. I use
previous version in my daily bootloader. I'll run another series of
tests before comitting.
>
> One small detail:
>
>> + grub_free (mode_list);
>> + mode_list = 0;
>
> I would prefer if we used NULL for pointers. I know we don't do that
> everywhere, but it makes code easier to understand.
From GCS: "Zero without a cast is perfectly fine as a null pointer
constant, except when calling a varargs function. "
>
> --
> Robert Millan
>
> The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
> how) you may access your data; but nobody's threatening your freedom: we
> still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-13 20:36 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-13 21:01 ` Robert Millan
0 siblings, 0 replies; 47+ messages in thread
From: Robert Millan @ 2009-08-13 21:01 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Aug 13, 2009 at 10:36:37PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> > Please go ahead (I assume it raises no warnings and it's well tested).
> I tested the latest version with gfxterm and xnu loader. I use
> previous version in my daily bootloader. I'll run another series of
> tests before comitting.
> >
> > One small detail:
> >
> >> + grub_free (mode_list);
> >> + mode_list = 0;
> >
> > I would prefer if we used NULL for pointers. I know we don't do that
> > everywhere, but it makes code easier to understand.
> >From GCS: "Zero without a cast is perfectly fine as a null pointer
> constant, except when calling a varargs function. "
Even if it's not mandated by GCS, it does make the code easier to read,
because of the loaded meaning in this expression (just like 'A' can be
more meaningful than 0x41).
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-13 15:59 ` Vladimir 'phcoder' Serbinenko
2009-08-13 19:41 ` Robert Millan
@ 2009-08-14 0:13 ` Michal Suchanek
2009-08-14 10:39 ` Michal Suchanek
2009-08-14 11:41 ` Vladimir 'phcoder' Serbinenko
1 sibling, 2 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-14 0:13 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/13 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>> Considering that vbe.c and sdl.c currently aren't affected a lot
>> whether there is or there isn't encapsulation in place, I'm ok tih
>> encapsulating it but if any driver needs the breach of encapsulation
>> it will be broken and I'll post no opposition to it.
>> I'll do the encapsulation tomorrow.
> Patch attached. One incremental version (for review) and one complete
> (for patching)
The patch as presented here works for me.
However, I wonder some of the changes:
In the latest round of patches struct grub_video_fbrender_target
declaration was needlessly and somewhat illogically moved from
video_fb.h to fbfill.h.
I am not sure if this is to hide the structure from other code but it
logically belongs to video_fb.h.
In grub_video_vbe_setup function in vbe.c the default palette is
loaded before the created render target is set as active. I guess this
would be a problem if the palette was actually needed/supported.
Changing the order to create, set_active, set_palette makes the code
fail for me,though.
In this same code struct grub_video_mode_info mode_info is added in
the last round of patches but I cannot find where the changed code
touches the variable. This is somewhat odd.
In create_render_target_from_pointer the is_allocated is set to 0 twice.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-14 0:13 ` Michal Suchanek
@ 2009-08-14 10:39 ` Michal Suchanek
2009-08-14 11:41 ` Vladimir 'phcoder' Serbinenko
1 sibling, 0 replies; 47+ messages in thread
From: Michal Suchanek @ 2009-08-14 10:39 UTC (permalink / raw)
To: The development of GRUB 2
2009/8/14 Michal Suchanek <hramrach@centrum.cz>:
> 2009/8/13 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>> Considering that vbe.c and sdl.c currently aren't affected a lot
>>> whether there is or there isn't encapsulation in place, I'm ok tih
>>> encapsulating it but if any driver needs the breach of encapsulation
>>> it will be broken and I'll post no opposition to it.
>>> I'll do the encapsulation tomorrow.
>> Patch attached. One incremental version (for review) and one complete
>
> In grub_video_vbe_setup function in vbe.c the default palette is
> loaded before the created render target is set as active. I guess this
> would be a problem if the palette was actually needed/supported.
> Changing the order to create, set_active, set_palette makes the code
> fail for me,though.
>
> In this same code struct grub_video_mode_info mode_info is added in
> the last round of patches but I cannot find where the changed code
> touches the variable. This is somewhat odd.
Looking at grub_video_vbe_setup I think this could get some more
decrufting but this is outside of the scope of framebuffer split and
can be looked at once the split is in.
Thanks
Michal
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-14 0:13 ` Michal Suchanek
2009-08-14 10:39 ` Michal Suchanek
@ 2009-08-14 11:41 ` Vladimir 'phcoder' Serbinenko
2009-08-14 12:57 ` Michal Suchanek
1 sibling, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-14 11:41 UTC (permalink / raw)
To: The development of GRUB 2
On Fri, Aug 14, 2009 at 2:13 AM, Michal Suchanek<hramrach@centrum.cz> wrote:
> 2009/8/13 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>> Considering that vbe.c and sdl.c currently aren't affected a lot
>>> whether there is or there isn't encapsulation in place, I'm ok tih
>>> encapsulating it but if any driver needs the breach of encapsulation
>>> it will be broken and I'll post no opposition to it.
>>> I'll do the encapsulation tomorrow.
>> Patch attached. One incremental version (for review) and one complete
>> (for patching)
>
> The patch as presented here works for me.
>
> However, I wonder some of the changes:
>
> In the latest round of patches struct grub_video_fbrender_target
> declaration was needlessly and somewhat illogically moved from
> video_fb.h to fbfill.h.
fbfill.h is a private header whereas video_fb.h is public one. You're
the one who requested encapsulation
>
> I am not sure if this is to hide the structure from other code but it
> logically belongs to video_fb.h.
>
Again, you're the one who requested encapsulation.
> In grub_video_vbe_setup function in vbe.c the default palette is
> loaded before the created render target is set as active. I guess this
> would be a problem if the palette was actually needed/supported.
> Changing the order to create, set_active, set_palette makes the code
> fail for me,though.
Works for me. Have you forgotten about 'return' ?
>
> In this same code struct grub_video_mode_info mode_info is added in
> the last round of patches but I cannot find where the changed code
> touches the variable. This is somewhat odd.
grep is your friend:
framebuffer.mode_info.width = active_mode_info.x_resolution;
and follows. Since now vbe.c can't manipulate directly the target.
Again, you're the one who requested encapsulation.
>
> In create_render_target_from_pointer the is_allocated is set to 0 twice.
Fixed
>
I'm running the series of tests now and when I'm finished I'll commit
it. After that you're welcome to submit patches for the problems you
spot (you already talked about few)
> Thanks
>
> Michal
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-14 11:41 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-14 12:57 ` Michal Suchanek
2009-08-14 13:23 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Michal Suchanek @ 2009-08-14 12:57 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 2893 bytes --]
2009/8/14 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
> On Fri, Aug 14, 2009 at 2:13 AM, Michal Suchanek<hramrach@centrum.cz> wrote:
>> 2009/8/13 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>:
>>>> Considering that vbe.c and sdl.c currently aren't affected a lot
>>>> whether there is or there isn't encapsulation in place, I'm ok tih
>>>> encapsulating it but if any driver needs the breach of encapsulation
>>>> it will be broken and I'll post no opposition to it.
>>>> I'll do the encapsulation tomorrow.
>>> Patch attached. One incremental version (for review) and one complete
>>> (for patching)
>>
>> The patch as presented here works for me.
>>
>> However, I wonder some of the changes:
>>
>> In the latest round of patches struct grub_video_fbrender_target
>> declaration was needlessly and somewhat illogically moved from
>> video_fb.h to fbfill.h.
> fbfill.h is a private header whereas video_fb.h is public one. You're
> the one who requested encapsulation
OK, I did not get why fbfill.h of the three private headers.
Perhaps fbutil.h which already declares blit_info would be a better place then.
>> In grub_video_vbe_setup function in vbe.c the default palette is
>> loaded before the created render target is set as active. I guess this
>> would be a problem if the palette was actually needed/supported.
>> Changing the order to create, set_active, set_palette makes the code
>> fail for me,though.
> Works for me. Have you forgotten about 'return' ?
Yes, perhaps I did something wrong when reordering the calls for the first time.
>>
>> In this same code struct grub_video_mode_info mode_info is added in
>> the last round of patches but I cannot find where the changed code
>> touches the variable. This is somewhat odd.
> grep is your friend:
> framebuffer.mode_info.width = active_mode_info.x_resolution;
> and follows. Since now vbe.c can't manipulate directly the target.
> Again, you're the one who requested encapsulation.
Sorry, I just confused the
grub_video_mode_info mode_info
with the
grub_vbe_mode_info_block mode_info
Perhaps a more distinctive name for the latter would be helpful, though.
>>
>> In create_render_target_from_pointer the is_allocated is set to 0 twice.
> Fixed
>>
> I'm running the series of tests now and when I'm finished I'll commit
> it. After that you're welcome to submit patches for the problems you
> spot (you already talked about few)
This is a patch against the current (as far as git knows) framebuf branch:
* move video_fb_fender_target structure declaration to fbutil.h
* remove duplicate assignment in create_render_target_from_pointer
+ quiet warning
* rename local variable in grub_video_vbe_setup
* remove grub_video_fb_get_video_ptr from video_fb.c (dup in fbutil.c)
Take which you want
Thanks
Michal
[-- Attachment #2: fbsplit_cleanup.patch --]
[-- Type: text/x-diff, Size: 20186 bytes --]
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
index 08cd7b8..11e22c6 100644
--- a/include/grub/fbfill.h
+++ b/include/grub/fbfill.h
@@ -24,29 +24,6 @@
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;
-};
-
void
grub_video_fbfill (struct grub_video_fbblit_info *dst,
grub_video_color_t color, int x, int y,
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
index 76e1e57..fc1e885 100644
--- a/include/grub/fbutil.h
+++ b/include/grub/fbutil.h
@@ -25,13 +25,36 @@
#include <grub/types.h>
#include <grub/video.h>
+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_fbblit_info
{
struct grub_video_mode_info *mode_info;
void *data;
};
-grub_uint8_t *get_data_ptr (struct grub_video_fbblit_info *source,
+grub_uint8_t *grub_video_fb_get_video_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,
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
index 03ef385..17debd6 100644
--- a/include/grub/video_fb.h
+++ b/include/grub/video_fb.h
@@ -33,9 +33,6 @@ struct grub_video_fbrender_target;
#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
-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);
diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c
index 138eba8..5b613bc 100644
--- a/video/fb/fbblit.c
+++ b/video/fb/fbblit.c
@@ -83,8 +83,8 @@ grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
grub_memmove (dstptr, srcptr, width * bpp);
}
@@ -110,8 +110,8 @@ grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -153,8 +153,8 @@ grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -197,8 +197,8 @@ grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -245,8 +245,8 @@ grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -285,8 +285,8 @@ grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -321,8 +321,8 @@ grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -358,8 +358,8 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -394,8 +394,8 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -491,8 +491,8 @@ grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -572,8 +572,8 @@ grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+ dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
for (j = 0; j < height; j++)
{
@@ -656,8 +656,8 @@ grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -721,8 +721,8 @@ grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
@@ -788,8 +788,8 @@ grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
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);
+ srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+ dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
for (i = 0; i < width; i++)
{
diff --git a/video/fb/fbutil.c b/video/fb/fbutil.c
index 09cbb12..1fa48ec 100644
--- a/video/fb/fbutil.c
+++ b/video/fb/fbutil.c
@@ -16,12 +16,23 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+/* SPECIAL NOTES!
+
+ Please note following when reading the code below:
+
+ - In this driver we assume that every memory can be accessed by same memory
+ bus. If there are different address spaces do not use this code as a base
+ code for other archs.
+
+ - Every function in this code assumes that bounds checking has been done in
+ previous phase and they are opted out in here. */
+
#include <grub/fbutil.h>
#include <grub/types.h>
#include <grub/video.h>
grub_uint8_t *
-get_data_ptr (struct grub_video_fbblit_info *source,
+grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
unsigned int x, unsigned int y)
{
grub_uint8_t *ptr = 0;
@@ -72,24 +83,24 @@ get_pixel (struct grub_video_fbblit_info *source,
switch (source->mode_info->bpp)
{
case 32:
- color = *(grub_uint32_t *)get_data_ptr (source, x, y);
+ color = *(grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
break;
case 24:
{
grub_uint8_t *ptr;
- ptr = get_data_ptr (source, x, y);
+ ptr = grub_video_fb_get_video_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);
+ color = *(grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
break;
case 8:
- color = *(grub_uint8_t *)get_data_ptr (source, x, y);
+ color = *(grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
break;
case 1:
@@ -120,7 +131,7 @@ set_pixel (struct grub_video_fbblit_info *source,
{
grub_uint32_t *ptr;
- ptr = (grub_uint32_t *)get_data_ptr (source, x, y);
+ ptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
*ptr = color;
}
@@ -131,7 +142,7 @@ set_pixel (struct grub_video_fbblit_info *source,
grub_uint8_t *ptr;
grub_uint8_t *colorptr = (grub_uint8_t *)&color;
- ptr = get_data_ptr (source, x, y);
+ ptr = grub_video_fb_get_video_ptr (source, x, y);
ptr[0] = colorptr[0];
ptr[1] = colorptr[1];
@@ -144,7 +155,7 @@ set_pixel (struct grub_video_fbblit_info *source,
{
grub_uint16_t *ptr;
- ptr = (grub_uint16_t *)get_data_ptr (source, x, y);
+ ptr = (grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
*ptr = (grub_uint16_t) (color & 0xFFFF);
}
@@ -154,7 +165,7 @@ set_pixel (struct grub_video_fbblit_info *source,
{
grub_uint8_t *ptr;
- ptr = (grub_uint8_t *)get_data_ptr (source, x, y);
+ ptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
*ptr = (grub_uint8_t) (color & 0xFF);
}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
index a9cd76b..902e683 100644
--- a/video/fb/video_fb.c
+++ b/video/fb/video_fb.c
@@ -83,44 +83,6 @@ grub_video_fb_get_info (struct grub_video_mode_info *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)
@@ -1105,12 +1067,9 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
target->viewport.width = mode_info->width;
target->viewport.height = mode_info->height;
- /* Mark framebuffer memory as non allocated. */
- target->is_allocated = 0;
-
/* Clear render target with black and maximum transparency. */
for (y = 0; y < mode_info->height; y++)
- grub_memset (target->data + mode_info->pitch * y, 0,
+ grub_memset ((char *) target->data + mode_info->pitch * y, 0,
mode_info->bytes_per_pixel * mode_info->width);
/* Save result to caller. */
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
index b3fe4d6..27ea08e 100644
--- a/video/i386/pc/vbe.c
+++ b/video/i386/pc/vbe.c
@@ -364,7 +364,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
unsigned int mode_type)
{
grub_uint16_t *p;
- struct grub_vbe_mode_info_block mode_info;
+ struct grub_vbe_mode_info_block vbe_mode_info;
struct grub_vbe_mode_info_block best_mode_info;
grub_uint32_t best_mode = 0;
int depth;
@@ -378,7 +378,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
{
grub_uint32_t mode = *p;
- grub_vbe_get_video_mode_info (mode, &mode_info);
+ grub_vbe_get_video_mode_info (mode, &vbe_mode_info);
if (grub_errno != GRUB_ERR_NONE)
{
/* Could not retrieve mode info, retreat. */
@@ -386,33 +386,33 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
break;
}
- if ((mode_info.mode_attributes & 0x001) == 0)
+ if ((vbe_mode_info.mode_attributes & 0x001) == 0)
/* If not available, skip it. */
continue;
- if ((mode_info.mode_attributes & 0x002) == 0)
+ if ((vbe_mode_info.mode_attributes & 0x002) == 0)
/* Not enough information. */
continue;
- if ((mode_info.mode_attributes & 0x008) == 0)
+ if ((vbe_mode_info.mode_attributes & 0x008) == 0)
/* Monochrome is unusable. */
continue;
- if ((mode_info.mode_attributes & 0x080) == 0)
+ if ((vbe_mode_info.mode_attributes & 0x080) == 0)
/* We support only linear frame buffer modes. */
continue;
- if ((mode_info.mode_attributes & 0x010) == 0)
+ if ((vbe_mode_info.mode_attributes & 0x010) == 0)
/* We allow only graphical modes. */
continue;
- if ((mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
- && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
+ if ((vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
+ && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
/* Not compatible memory model. */
continue;
- if ((mode_info.x_resolution != width)
- || (mode_info.y_resolution != height))
+ if ((vbe_mode_info.x_resolution != width)
+ || (vbe_mode_info.y_resolution != height))
/* Non matching resolution. */
continue;
@@ -420,28 +420,28 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
if ((mode_type & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0)
{
if (((mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
- && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL))
+ && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL))
/* Requested only index color modes. */
continue;
if (((mode_type & GRUB_VIDEO_MODE_TYPE_RGB) != 0)
- && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
+ && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
/* Requested only RGB modes. */
continue;
}
/* If there is a request for specific depth, ignore others. */
- if ((depth != 0) && (mode_info.bits_per_pixel != depth))
+ if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth))
continue;
/* Select mode with most number of bits per pixel. */
if (best_mode != 0)
- if (mode_info.bits_per_pixel < best_mode_info.bits_per_pixel)
+ if (vbe_mode_info.bits_per_pixel < best_mode_info.bits_per_pixel)
continue;
/* Save so far best mode information for later use. */
best_mode = mode;
- grub_memcpy (&best_mode_info, &mode_info, sizeof (mode_info));
+ grub_memcpy (&best_mode_info, &vbe_mode_info, sizeof (vbe_mode_info));
}
/* Try to initialize best mode found. */
@@ -482,18 +482,18 @@ grub_video_vbe_setup (unsigned int width, unsigned int height,
framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
- /* Copy default palette to initialize emulated palette. */
- err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
- grub_video_fbstd_colors);
+ err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
if (err)
return err;
- err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
-
+ err = grub_video_fb_set_active_render_target (framebuffer.render_target);
if (err)
return err;
- return grub_video_fb_set_active_render_target (framebuffer.render_target);
+ /* Copy default palette to initialize emulated palette. */
+ return grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+ grub_video_fbstd_colors);
}
/* Couldn't found matching mode. */
^ permalink raw reply related [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-14 12:57 ` Michal Suchanek
@ 2009-08-14 13:23 ` Vladimir 'phcoder' Serbinenko
2009-08-14 13:24 ` Vladimir 'phcoder' Serbinenko
0 siblings, 1 reply; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-14 13:23 UTC (permalink / raw)
To: The development of GRUB 2
Framebuffer patch comitted and I removed framebuf branch on my repo.
>
> OK, I did not get why fbfill.h of the three private headers.
>
> Perhaps fbutil.h which already declares blit_info would be a better place then.
>
I haven't looked in depth how private headers were organised, I just
moved the same layout to fb*. Perhaps we need only one framebuffer
private header now
>>> In grub_video_vbe_setup function in vbe.c the default palette is
>>> loaded before the created render target is set as active. I guess this
>>> would be a problem if the palette was actually needed/supported.
>>> Changing the order to create, set_active, set_palette makes the code
>>> fail for me,though.
>> Works for me. Have you forgotten about 'return' ?
>
> Yes, perhaps I did something wrong when reordering the calls for the first time.
>
It's already reordered in comitted version
>>>
>>> In this same code struct grub_video_mode_info mode_info is added in
>>> the last round of patches but I cannot find where the changed code
>>> touches the variable. This is somewhat odd.
>> grep is your friend:
>> framebuffer.mode_info.width = active_mode_info.x_resolution;
>> and follows. Since now vbe.c can't manipulate directly the target.
>> Again, you're the one who requested encapsulation.
>
> Sorry, I just confused the
> grub_video_mode_info mode_info
> with the
> grub_vbe_mode_info_block mode_info
>
> Perhaps a more distinctive name for the latter would be helpful, though.
>
I'm ok with rename.
> This is a patch against the current (as far as git knows) framebuf branch:
This branch doesn't exist anymore since it's upstream ;)
>
> * move video_fb_fender_target structure declaration to fbutil.h
Requires me to looks at how three headers are organised.
> * remove duplicate assignment in create_render_target_from_pointer
> + quiet warning
Is already done in committed version
> * rename local variable in grub_video_vbe_setup
Good
> * remove grub_video_fb_get_video_ptr from video_fb.c (dup in fbutil.c)
Good patch too
>
> Take which you want
>
Could you send them as separate patches with changelogs? It's
especially important in your case since you have no copyright
assignment yet and we have to decide which patches can go in without
such. I'm not maintainer so I need explicit consent from them to apply
your patches before you sign copyright assignment
> Thanks
>
> Michal
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: Fwd: [PATCH 1/2] Framebuffer split
2009-08-14 13:23 ` Vladimir 'phcoder' Serbinenko
@ 2009-08-14 13:24 ` Vladimir 'phcoder' Serbinenko
0 siblings, 0 replies; 47+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-14 13:24 UTC (permalink / raw)
To: The development of GRUB 2
On Fri, Aug 14, 2009 at 3:23 PM, Vladimir 'phcoder'
Serbinenko<phcoder@gmail.com> wrote:
> Framebuffer patch comitted and I removed framebuf branch on my repo.
>>
>> OK, I did not get why fbfill.h of the three private headers.
>>
>> Perhaps fbutil.h which already declares blit_info would be a better place then.
>>
> I haven't looked in depth how private headers were organised, I just
> moved the same layout to fb*. Perhaps we need only one framebuffer
> private header now
>>>> In grub_video_vbe_setup function in vbe.c the default palette is
>>>> loaded before the created render target is set as active. I guess this
>>>> would be a problem if the palette was actually needed/supported.
>>>> Changing the order to create, set_active, set_palette makes the code
>>>> fail for me,though.
>>> Works for me. Have you forgotten about 'return' ?
>>
>> Yes, perhaps I did something wrong when reordering the calls for the first time.
>>
> It's already reordered in comitted version
>>>>
>>>> In this same code struct grub_video_mode_info mode_info is added in
>>>> the last round of patches but I cannot find where the changed code
>>>> touches the variable. This is somewhat odd.
>>> grep is your friend:
>>> framebuffer.mode_info.width = active_mode_info.x_resolution;
>>> and follows. Since now vbe.c can't manipulate directly the target.
>>> Again, you're the one who requested encapsulation.
>>
>> Sorry, I just confused the
>> grub_video_mode_info mode_info
>> with the
>> grub_vbe_mode_info_block mode_info
>>
>> Perhaps a more distinctive name for the latter would be helpful, though.
>>
> I'm ok with rename.
>> This is a patch against the current (as far as git knows) framebuf branch:
> This branch doesn't exist anymore since it's upstream ;)
>>
>> * move video_fb_fender_target structure declaration to fbutil.h
> Requires me to looks at how three headers are organised.
>> * remove duplicate assignment in create_render_target_from_pointer
>> + quiet warning
> Is already done in committed version
>> * rename local variable in grub_video_vbe_setup
> Good
>> * remove grub_video_fb_get_video_ptr from video_fb.c (dup in fbutil.c)
> Good patch too
>>
>> Take which you want
>>
> Could you send them as separate patches with changelogs? It's
> especially important in your case since you have no copyright
> assignment yet and we have to decide which patches can go in without
> such. I'm not maintainer so I need explicit consent from them to apply
> your patches before you sign copyright assignment
And please consider this thread closed and post your patches in a new thread
>> Thanks
>>
>> Michal
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>>
>
>
>
> --
> Regards
> Vladimir 'phcoder' Serbinenko
>
> Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
>
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
^ permalink raw reply [flat|nested] 47+ messages in thread
end of thread, other threads:[~2009-08-14 13:24 UTC | newest]
Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <d7ead6de0907230248s9af4c51ic4a172d2279f0b8b@mail.gmail.com>
[not found] ` <d7ead6de0907230250h13df5d6du29ce32ef0e187123@mail.gmail.com>
2009-07-23 9:52 ` Fwd: [PATCH 1/2] Framebuffer split Vladimir 'phcoder' Serbinenko
2009-07-23 23:41 ` Pavel Roskin
2009-07-25 9:57 ` Vladimir 'phcoder' Serbinenko
2009-07-26 22:06 ` Vladimir 'phcoder' Serbinenko
2009-07-28 17:50 ` Robert Millan
2009-07-28 21:21 ` Vladimir 'phcoder' Serbinenko
2009-07-31 16:00 ` Robert Millan
2009-07-31 20:31 ` Vladimir 'phcoder' Serbinenko
2009-08-01 14:41 ` Robert Millan
2009-08-01 14:50 ` Michal Suchanek
2009-08-01 15:02 ` Robert Millan
2009-08-01 15:01 ` Robert Millan
2009-08-01 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-01 16:03 ` Vladimir 'phcoder' Serbinenko
2009-08-02 22:01 ` Vladimir 'phcoder' Serbinenko
2009-08-08 19:06 ` Michal Suchanek
2009-08-08 22:03 ` Michal Suchanek
2009-08-10 12:30 ` Vladimir 'phcoder' Serbinenko
2009-08-09 11:55 ` Michal Suchanek
2009-08-10 12:36 ` Vladimir 'phcoder' Serbinenko
2009-08-10 13:34 ` Michal Suchanek
2009-08-10 14:11 ` Vladimir 'phcoder' Serbinenko
2009-08-10 14:38 ` Michal Suchanek
2009-08-10 15:10 ` Vladimir 'phcoder' Serbinenko
2009-08-10 18:41 ` Michal Suchanek
2009-08-10 19:43 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:17 ` Michal Suchanek
2009-08-12 13:45 ` Vladimir 'phcoder' Serbinenko
2009-08-13 15:59 ` Vladimir 'phcoder' Serbinenko
2009-08-13 19:41 ` Robert Millan
2009-08-13 20:36 ` Vladimir 'phcoder' Serbinenko
2009-08-13 21:01 ` Robert Millan
2009-08-14 0:13 ` Michal Suchanek
2009-08-14 10:39 ` Michal Suchanek
2009-08-14 11:41 ` Vladimir 'phcoder' Serbinenko
2009-08-14 12:57 ` Michal Suchanek
2009-08-14 13:23 ` Vladimir 'phcoder' Serbinenko
2009-08-14 13:24 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:08 ` Michal Suchanek
2009-08-12 13:16 ` Vladimir 'phcoder' Serbinenko
2009-08-12 13:38 ` Michal Suchanek
2009-08-02 21:43 ` Robert Millan
2009-08-02 21:52 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:14 ` Michal Suchanek
2009-08-01 15:17 ` Vladimir 'phcoder' Serbinenko
2009-08-01 15:32 ` Michal Suchanek
2009-08-02 21:29 ` Robert Millan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.