diff --git a/configure.ac b/configure.ac index 250dfc1c4..9d7854d35 100644 --- a/configure.ac +++ b/configure.ac @@ -1586,6 +1586,10 @@ else fi AC_SUBST([BOOT_TIME_STATS]) +AC_ARG_ENABLE([grub-emu-sdl2], + [AS_HELP_STRING([--enable-grub-emu-sdl2], + [build and install the `grub-emu' debugging utility with SDL2 support (default=guessed)])]) + AC_ARG_ENABLE([grub-emu-sdl], [AS_HELP_STRING([--enable-grub-emu-sdl], [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) @@ -1595,6 +1599,28 @@ AC_ARG_ENABLE([grub-emu-pci], [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) if test "$platform" = emu; then + if test x"$enable_grub_emu_sdl2" = xno ; then + grub_emu_sdl2_excuse="explicitly disabled" + fi + [if [ x"$grub_emu_sdl2_excuse" = x ]; then + # Check for libSDL libraries.] + PKG_CHECK_MODULES([SDL2], [sdl2], [ + AC_DEFINE([HAVE_SDL2], [1], [Define to 1 if you have SDL2 library.]) + AC_SUBST(HAVE_SDL2)], + [grub_emu_sdl2_excuse="libSDL2 libraries are required to build \`grub-emu' with SDL2 support"]) + [fi] + if test x"enable_grub_emu_sdl2" = xyes && test x"$grub_emu_sdl2_excuse" != x ; then + AC_MSG_ERROR([SDL2 support for grub-emu was explicitly requested but can't be compiled ($grub_emu_sdl2_excuse)]) + fi + if test x"$grub_emu_sdl2_excuse" = x ; then + enable_grub_emu_sdl2=yes + else + enable_grub_emu_sdl2=no + fi + if test x"$enable_grub_emu_sdl2" = xyes ; then + grub_emu_sdl_excuse="disabled by sdl2" + fi + if test x"$enable_grub_emu_sdl" = xno ; then grub_emu_sdl_excuse="explicitly disabled" @@ -1643,12 +1669,14 @@ AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"], enable_grub_emu_pci=no fi + AC_SUBST([enable_grub_emu_sdl2]) AC_SUBST([enable_grub_emu_sdl]) AC_SUBST([enable_grub_emu_pci]) else # Ignore --enable-emu-* if platform is not emu + enable_grub_emu_sdl2=no enable_grub_emu_sdl=no enable_grub_emu_pci=no fi @@ -2075,6 +2103,7 @@ AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu]) AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) +AM_CONDITIONAL([COND_GRUB_EMU_SDL2], [test x$enable_grub_emu_sdl2 = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) @@ -2153,6 +2182,11 @@ echo "*******************************************************" echo GRUB2 will be compiled with following components: echo Platform: "$target_cpu"-"$platform" if [ x"$platform" = xemu ]; then +if [ x"$grub_emu_sdl2_excuse" = x ]; then +echo SDL2 support for grub-emu: Yes +else +echo SDL2 support for grub-emu: No "($grub_emu_sdl2_excuse)" +fi if [ x"$grub_emu_sdl_excuse" = x ]; then echo SDL support for grub-emu: Yes else diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index d32f2b662..f0cb2f2cc 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -317,6 +317,9 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/exec.h if COND_GRUB_EMU_SDL KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h endif +if COND_GRUB_EMU_SDL2 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h +endif if COND_GRUB_EMU_PCI KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h endif diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e458aa665..d2cf29584 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -418,7 +418,7 @@ program = { ldadd = 'kernel.exec$(EXEEXT)'; ldadd = '$(MODULE_FILES)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; @@ -430,7 +430,7 @@ program = { emu_nodist = symlist.c; ldadd = 'kernel.exec$(EXEEXT)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; @@ -2325,6 +2325,14 @@ module = { condition = COND_GRUB_EMU_SDL; }; +module = { + name = sdl; + emu = video/emu/sdl.c; + enable = emu; + condition = COND_GRUB_EMU_SDL2; + cflags = '$(SDL2_CFLAGS)'; +}; + module = { name = datehook; common = hook/datehook.c; diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c index c1b66f01e..cb8490e35 100644 --- a/grub-core/video/emu/sdl.c +++ b/grub-core/video/emu/sdl.c @@ -18,6 +18,9 @@ #define grub_video_render_target grub_video_fbrender_target +#include +#include + #include #include #include @@ -25,11 +28,22 @@ #include #include #include +#ifdef HAVE_SDL2 +#include +#else #include +#endif GRUB_MOD_LICENSE ("GPLv3+"); +#ifdef HAVE_SDL2 +static SDL_Window *window = NULL; +static SDL_Texture *texture = NULL; +static SDL_Renderer *renderer = NULL; +#else static SDL_Surface *window = NULL; +#endif +static SDL_Surface *surface = NULL; static struct grub_video_render_target *sdl_render_target; static struct grub_video_mode_info mode_info; @@ -72,7 +86,7 @@ get_mask_size (grub_uint32_t mask) static grub_err_t grub_video_sdl_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) { int depth; int flags = 0; @@ -91,6 +105,35 @@ grub_video_sdl_setup (unsigned int width, unsigned int height, height = 600; } +#ifdef HAVE_SDL2 + window = SDL_CreateWindow ("grub-emu", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, height, flags); + if(window == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open window: %s", + SDL_GetError ()); + renderer = SDL_CreateRenderer (window, -1, 0); + if (renderer == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open renderer: %s", + SDL_GetError ()); + texture = SDL_CreateTexture (renderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + width, height); + if (texture == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not create texture: %s", + SDL_GetError ()); + + /* + * An empty surface that acts as the pixel buffer, the texture will receive the pixels + * from here. + */ + surface = SDL_CreateRGBSurface (0, width, height, depth, 0, 0, 0, 0); + if (surface == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open surface: %s", + SDL_GetError ()); +#else if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) || !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) flags |= SDL_DOUBLEBUF; @@ -102,51 +145,55 @@ grub_video_sdl_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_BAD_DEVICE, "could not open window: %s", SDL_GetError ()); + surface = window; +#endif grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target)); - mode_info.width = window->w; - mode_info.height = window->h; mode_info.mode_type = 0; - if (window->flags & SDL_DOUBLEBUF) + mode_info.width = surface->w; + mode_info.height = surface->h; +#ifndef HAVE_SDL2 + if (surface->flags & SDL_DOUBLEBUF) mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - if (window->format->palette) +#endif + if (surface->format->palette) mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; else mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB; - mode_info.bpp = window->format->BitsPerPixel; - mode_info.bytes_per_pixel = window->format->BytesPerPixel; - mode_info.pitch = window->pitch; + mode_info.bpp = surface->format->BitsPerPixel; + mode_info.bytes_per_pixel = surface->format->BytesPerPixel; + mode_info.pitch = surface->pitch; /* In index color mode, number of colors. In RGB mode this is 256. */ - if (window->format->palette) + if (surface->format->palette) mode_info.number_of_colors - = 1 << window->format->BitsPerPixel; + = 1 << surface->format->BitsPerPixel; else mode_info.number_of_colors = 256; - if (! window->format->palette) + if (! surface->format->palette) { mode_info.red_mask_size - = get_mask_size (window->format->Rmask >> window->format->Rshift); - mode_info.red_field_pos = window->format->Rshift; + = get_mask_size (surface->format->Rmask >> surface->format->Rshift); + mode_info.red_field_pos = surface->format->Rshift; mode_info.green_mask_size - = get_mask_size (window->format->Gmask >> window->format->Gshift); - mode_info.green_field_pos = window->format->Gshift; + = get_mask_size (surface->format->Gmask >> surface->format->Gshift); + mode_info.green_field_pos = surface->format->Gshift; mode_info.blue_mask_size - = get_mask_size (window->format->Bmask >> window->format->Bshift); - mode_info.blue_field_pos = window->format->Bshift; + = get_mask_size (surface->format->Bmask >> surface->format->Bshift); + mode_info.blue_field_pos = surface->format->Bshift; mode_info.reserved_mask_size - = get_mask_size (window->format->Amask >> window->format->Ashift); - mode_info.reserved_field_pos = window->format->Ashift; + = get_mask_size (surface->format->Amask >> surface->format->Ashift); + mode_info.reserved_field_pos = surface->format->Ashift; mode_info.blit_format = grub_video_get_blit_format (&mode_info); } err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target, &mode_info, - window->pixels); + surface->pixels); if (err) return err; @@ -163,7 +210,7 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { unsigned i; - if (window->format->palette) + if (surface->format->palette) { SDL_Color *tmp; if (start >= mode_info.number_of_colors) @@ -178,9 +225,17 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, tmp[i].r = palette_data[i].r; tmp[i].g = palette_data[i].g; tmp[i].b = palette_data[i].b; +#ifdef HAVE_SDL2 + tmp[i].a = palette_data[i].a; +#else tmp[i].unused = palette_data[i].a; +#endif } +#ifdef HAVE_SDL2 + SDL_SetPaletteColors (surface->format->palette, tmp, 0 /* firstcolor */, count); +#else SDL_SetColors (window, tmp, start, count); +#endif grub_free (tmp); } @@ -190,9 +245,22 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_sdl_swap_buffers (void) { +#ifdef HAVE_SDL2 + if (SDL_UpdateTexture (texture, NULL, surface->pixels, surface->w * sizeof (Uint32)) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not update texture: %s", + SDL_GetError ()); + if (SDL_RenderClear (renderer) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not clear renderer: %s", + SDL_GetError ()); + if (SDL_RenderCopy (renderer, texture, NULL, NULL) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not copy texture to renderer: %s", + SDL_GetError ()); + SDL_RenderPresent (renderer); +#else if (SDL_Flip (window) < 0) return grub_error (GRUB_ERR_BAD_DEVICE, "could not swap buffers: %s", SDL_GetError ()); +#endif return GRUB_ERR_NONE; } diff --git a/include/grub/sdl.h b/include/grub/sdl.h index e4efdc9b1..8f10b8817 100644 --- a/include/grub/sdl.h +++ b/include/grub/sdl.h @@ -15,10 +15,24 @@ * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ +#include void EXPORT_FUNC (SDL_Quit) (void); -void EXPORT_FUNC (SDL_SetColors) (void); void EXPORT_FUNC (SDL_Init) (void); void EXPORT_FUNC (SDL_GetError) (void); +#ifdef HAVE_SDL2 +void EXPORT_FUNC (SDL_CreateWindow) (void); +void EXPORT_FUNC (SDL_GetWindowSurface) (void); +void EXPORT_FUNC (SDL_CreateRenderer) (void); +void EXPORT_FUNC (SDL_CreateRGBSurface) (void); +void EXPORT_FUNC (SDL_CreateTexture) (void); +void EXPORT_FUNC (SDL_UpdateTexture) (void); +void EXPORT_FUNC (SDL_SetPaletteColors) (void); +void EXPORT_FUNC (SDL_RenderClear) (void); +void EXPORT_FUNC (SDL_RenderCopy) (void); +void EXPORT_FUNC (SDL_RenderPresent) (void); +#else void EXPORT_FUNC (SDL_Flip) (void); +void EXPORT_FUNC (SDL_SetColors) (void); void EXPORT_FUNC (SDL_SetVideoMode) (void); +#endif