diff --git a/CMakeLists.txt b/CMakeLists.txt index bd59d89b2..3032c938d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -366,6 +366,7 @@ set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE}) set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) set_option(WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS}) set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) +set_option(VIDEO_MALI "Use Mali EGL video driver" ${UNIX_SYS}) set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) set_option(VIDEO_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS}) @@ -1046,6 +1047,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID) CheckWayland() CheckVivante() CheckKMSDRM() + CheckMali() endif() if(UNIX) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 5d4d2f936..c054a81fd 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -738,6 +738,29 @@ macro(CheckVivante) endif(VIDEO_VIVANTE) endmacro(CheckVivante) +# Requires: +# - n/a +macro(CheckMali) + if(VIDEO_MALI) + check_c_source_compiles(" + #define LINUX + #define EGL_API_FB + #include + int main(int argc, char** argv) {}" HAVE_VIDEO_MALI_EGL_FB) + if(HAVE_VIDEO_MALI_EGL_FB) + set(HAVE_VIDEO_MALI TRUE) + set(HAVE_SDL_VIDEO TRUE) + + file(GLOB MALI_SOURCES ${SDL2_SOURCE_DIR}/src/video/mali-fbdev/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MALI_SOURCES}) + set(SDL_VIDEO_DRIVER_MALI 1) + set(SDL_CFLAGS "${SDL_CFLAGS} -DLINUX -DEGL_API_FB") + list(APPEND EXTRA_LIBS EGL) + endif(HAVE_VIDEO_MALI_EGL_MALI) + endif(VIDEO_MALI) +endmacro(CheckMali) + + # Requires: # - nada macro(CheckOpenGLX11) diff --git a/configure b/configure index ab7b65887..4e38f7a5b 100755 --- a/configure +++ b/configure @@ -868,6 +868,7 @@ enable_video_x11_scrnsaver enable_video_x11_xshape enable_video_x11_vm enable_video_vivante +enable_video_mali enable_video_cocoa enable_render_metal enable_video_directfb @@ -1646,6 +1647,7 @@ Optional Features: enable X11 XShape support [[default=yes]] --enable-video-x11-vm use X11 VM extension for fullscreen [[default=yes]] --enable-video-vivante use Vivante EGL video driver [[default=yes]] + --enable-video-mali use Mali EGL video driver [[default=no]] --enable-video-cocoa use Cocoa video driver [[default=yes]] --enable-render-metal enable the Metal render driver [[default=yes]] --enable-video-directfb use DirectFB video driver [[default=no]] @@ -19857,7 +19859,7 @@ $as_echo "$have_video_rpi" >&6; } if test x$have_video_rpi = xyes; then CFLAGS="$CFLAGS $RPI_CFLAGS" - SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" + #SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" EXTRA_CFLAGS="$EXTRA_CFLAGS $RPI_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS $RPI_LIBS" SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" @@ -21467,6 +21469,56 @@ $as_echo "#define SDL_VIDEO_DRIVER_VIVANTE_VDK 1" >>confdefs.h fi } +CheckMaliVideo() +{ + # Check whether --enable-video-mali was given. +if test "${enable_video_mali+set}" = set; then : + enableval=$enable_video_mali; +else + enable_video_mali=no +fi + + if test x$enable_video = xyes -a x$enable_video_mali = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mali FB API" >&5 +$as_echo_n "checking for Mali FB API... " >&6; } + have_mali_egl=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define LINUX + #define EGL_API_FB + #include + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + have_mali_egl=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_mali_egl" >&5 +$as_echo "$have_mali_egl" >&6; } + + if test x$have_mali_egl = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_MALI 1" >>confdefs.h + + EXTRA_CFLAGS="$EXTRA_CFLAGS -DLINUX -DEGL_API_FB" + SOURCES="$SOURCES $srcdir/src/video/mali-fbdev/*.c" + SUMMARY_video="${SUMMARY_video} mali" + have_video=yes + fi + fi +} + CheckHaikuVideo() { if test x$enable_video = xyes; then @@ -24483,6 +24535,7 @@ case "$host" in CheckLinuxVersion CheckRPATH CheckVivanteVideo + CheckMaliVideo # Set up files for the audio library if test x$enable_audio = xyes; then diff --git a/configure.ac b/configure.ac index 9e782c653..d7f7e3009 100644 --- a/configure.ac +++ b/configure.ac @@ -1588,7 +1588,7 @@ AS_HELP_STRING([--enable-video-rpi], [use Raspberry Pi video driver [[default=ye if test x$have_video_rpi = xyes; then CFLAGS="$CFLAGS $RPI_CFLAGS" - SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" + #SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" EXTRA_CFLAGS="$EXTRA_CFLAGS $RPI_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS $RPI_LIBS" SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" @@ -2006,6 +2006,35 @@ AS_HELP_STRING([--enable-video-vivante], [use Vivante EGL video driver [[default fi } +dnl Set up the Mali video driver if enabled +CheckMaliVideo() +{ + AC_ARG_ENABLE(video-mali, +AC_HELP_STRING([--enable-video-mali], [use Mali EGL video driver [[default=yes]]]), + , enable_video_mali=yes) + if test x$enable_video = xyes -a x$enable_video_mali = xyes; then + AC_MSG_CHECKING(for Mali FB API) + have_mali_egl=no + AC_TRY_COMPILE([ + #define LINUX + #define EGL_API_FB + #include + ],[ + ],[ + have_mali_egl=yes + ]) + AC_MSG_RESULT($have_mali_egl) + + if test x$have_mali_egl = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_MALI, 1, [ ]) + EXTRA_CFLAGS="$EXTRA_CFLAGS -DLINUX -DEGL_API_FB" + SOURCES="$SOURCES $srcdir/src/video/mali-fbdev/*.c" + SUMMARY_video="${SUMMARY_video} mali" + have_video=yes + fi + fi +} + dnl Set up the Haiku video driver if enabled CheckHaikuVideo() { @@ -3400,6 +3429,7 @@ case "$host" in CheckLinuxVersion CheckRPATH CheckVivanteVideo + CheckMaliVideo # Set up files for the audio library if test x$enable_audio = xyes; then diff --git a/debian/control b/debian/control index a3411335a..450aa2925 100644 --- a/debian/control +++ b/debian/control @@ -13,8 +13,6 @@ Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), fcitx-libs-dev [linux-any], libasound2-dev [linux-any], - libgl1-mesa-dev, - libpulse-dev, libudev-dev [linux-any], libdbus-1-dev [linux-any], libibus-1.0-dev[linux-any], @@ -30,16 +28,16 @@ Build-Depends: debhelper (>= 9), libxxf86vm-dev Homepage: http://www.libsdl.org/ -Package: libsdl2 +Package: libsdl2-2.0-0 Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, - libudev0 [linux-any], + libudev0 | libudev1 [linux-any], libdbus-1-3 [linux-any] -Conflicts: libsdl-1.3-0 -Replaces: libsdl-1.3-0 +Conflicts: libsdl-1.3-0, libsdl2 +Replaces: libsdl-1.3-0, libsdl2 Description: Simple DirectMedia Layer SDL is a library that allows programs portable low level access to a video framebuffer, audio output, mouse, and keyboard. @@ -51,9 +49,10 @@ Section: libdevel Architecture: any Multi-Arch: same Depends: ${misc:Depends}, - libsdl2 (= ${binary:Version}), + libsdl2-2.0-0 (= ${binary:Version}), libc6-dev, - libgl1-mesa-dev + libgl1-mesa-dev, + libx11-dev Conflicts: libsdl-1.3-dev Replaces: libsdl-1.3-dev Description: Simple DirectMedia Layer development files @@ -68,7 +67,7 @@ Section: debug Architecture: any Multi-Arch: same Depends: ${misc:Depends}, - libsdl2 (= ${binary:Version}), + libsdl2-2.0-0 (= ${binary:Version}), Description: Simple DirectMedia Layer debug files SDL is a library that allows programs portable low level access to a video framebuffer, audio output, mouse, and keyboard. diff --git a/debian/libsdl2.install b/debian/libsdl2-2.0-0.install similarity index 100% rename from debian/libsdl2.install rename to debian/libsdl2-2.0-0.install diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 5e9e5bcea..ef928eebd 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -330,6 +330,7 @@ #cmakedefine SDL_VIDEO_DRIVER_RPI @SDL_VIDEO_DRIVER_RPI@ #cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@ #cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@ +#cmakedefine SDL_VIDEO_DRIVER_MALI @SDL_VIDEO_DRIVER_MALI@ #cmakedefine SDL_VIDEO_DRIVER_KMSDRM @SDL_VIDEO_DRIVER_KMSDRM@ #cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index a5e9d1328..0b93b3614 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -335,6 +335,7 @@ #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM #undef SDL_VIDEO_DRIVER_ANDROID #undef SDL_VIDEO_DRIVER_EMSCRIPTEN +#undef SDL_VIDEO_DRIVER_MALI #undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 8fa0dd660..b2baeaf52 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -922,6 +922,33 @@ extern "C" { */ #define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" +/** + * \brief Tell dispmanx to stretch the SDL window to fill the display. + * + * This hint only applies to the rpi video driver. + * + * The variable can be set to the following values: + * "0" - Window resolution is desktop resolution. + * This is the behaviour of SDL <= 2.0.4. (default) + * "1" - Requested video resolution will be scaled to desktop resolution. + * Aspect ratio of requested video resolution will be respected. + * "2" - Requested video resolution will be scaled to desktop resolution. + * "3" - Requested video resolution will be scaled to desktop resolution. + * Aspect ratio of requested video resolution will be respected. + * If possible output resolution will be integral multiple of video + * resolution. + */ +#define SDL_HINT_VIDEO_RPI_SCALE_MODE "SDL_VIDEO_RPI_SCALE_MODE" + +/** + * \brief Tell dispmanx to set a specific aspect ratio. + * + * This hint only applies to the rpi video driver. + * + * Must be set together with SDL_HINT_VIDEO_RPI_SCALE_MODE=1. + */ +#define SDL_HINT_VIDEO_RPI_RATIO "SDL_VIDEO_RPI_RATIO" + /** * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. * diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c index ae2c7f324..2d137124b 100644 --- a/src/core/linux/SDL_evdev.c +++ b/src/core/linux/SDL_evdev.c @@ -446,18 +446,6 @@ SDL_EVDEV_translate_keycode(int keycode) if (keycode < SDL_arraysize(linux_scancode_table)) scancode = linux_scancode_table[keycode]; - if (scancode == SDL_SCANCODE_UNKNOWN) { - /* BTN_TOUCH is handled elsewhere, but we might still end up here if - you get an unexpected BTN_TOUCH from something SDL believes is not - a touch device. In this case, we'd rather not get a misleading - SDL_Log message about an unknown key. */ - if (keycode != BTN_TOUCH) { - SDL_Log("The key you just pressed is not recognized by SDL. To help " - "get this fixed, please report this to the SDL forums/mailing list " - " EVDEV KeyCode %d", keycode); - } - } - return scancode; } diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index dcc1b7440..f8a8639f3 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1047,7 +1047,7 @@ SDL_JoystickUpdate(void) if (joystick->delayed_guide_button) { SDL_GameControllerHandleDelayedGuideButton(joystick); } - } + if (joystick->force_recentering) { /* Tell the app that everything is centered/unpressed... */ @@ -1067,6 +1067,8 @@ SDL_JoystickUpdate(void) joystick->force_recentering = SDL_FALSE; } + + } } SDL_LockJoysticks(); diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index ad8309196..482f87474 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -609,7 +609,7 @@ ConfigJoystick(SDL_Joystick * joystick, int fd) ++joystick->nbuttons; } } - for (i = 0; i < ABS_MAX; ++i) { + for (i = 0; i < ABS_MISC; ++i) { /* Skip hats */ if (i == ABS_HAT0X) { i = ABS_HAT3Y; @@ -906,6 +906,10 @@ HandleInputEvents(SDL_Joystick * joystick) events[i].value); break; case EV_ABS: + if (code >= ABS_MISC) { + break; + } + switch (code) { case ABS_HAT0X: case ABS_HAT0Y: diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 778e555c3..fd59a963e 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -45,6 +45,8 @@ #if SDL_VIDEO_DRIVER_RPI /* Raspbian places the OpenGL ES/EGL binaries in a non standard path */ +#include +#define DEFAULT_OGL ( vc4 ? "libGL.so.1" : "" ) #define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" ) #define DEFAULT_OGL_ES2 ( vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so" ) #define ALT_EGL "libEGL.so" @@ -52,7 +54,7 @@ #define DEFAULT_OGL_ES_PVR ( vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so" ) #define DEFAULT_OGL_ES ( vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so" ) -#elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE +#elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_MALI || SDL_VIDEO_DRIVER_VIVANTE /* Android */ #define DEFAULT_EGL "libEGL.so" #define DEFAULT_OGL_ES2 "libGLESv2.so" @@ -536,6 +538,7 @@ SDL_EGL_ChooseConfig(_THIS) EGLint found_configs = 0, value; /* 128 seems even nicer here */ EGLConfig configs[128]; + SDL_bool has_matching_format = SDL_FALSE; int i, j, best_bitdiff = -1, bitdiff; if (!_this->egl_data) { @@ -614,11 +617,24 @@ SDL_EGL_ChooseConfig(_THIS) return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig"); } + /* first ensure that a found config has a matching format, or the function will fall through. */ + for (i = 0; i < found_configs; i++ ) { + if (_this->egl_data->egl_required_visual_id) + { + EGLint format; + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, + configs[i], + EGL_NATIVE_VISUAL_ID, &format); + if (_this->egl_data->egl_required_visual_id == format) + has_matching_format = SDL_TRUE; + } + } + /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */ /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */ for (i = 0; i < found_configs; i++ ) { - if (_this->egl_data->egl_required_visual_id) + if (has_matching_format && _this->egl_data->egl_required_visual_id) { EGLint format; _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 75dc2bb26..814e536e2 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -959,6 +959,8 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, SDL_Color copy_color; SDL_Rect bounds; int ret; + int palette_ck_transform = 0; + int palette_ck_value = 0; if (!surface) { SDL_InvalidParamError("surface"); @@ -1019,8 +1021,23 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, bounds.y = 0; bounds.w = surface->w; bounds.h = surface->h; + + /* Transform colorkey to alpha. for cases where source palette has duplicate values, and colorkey is one of them */ + if (copy_flags & SDL_COPY_COLORKEY) { + if (surface->format->palette && !format->palette) { + palette_ck_transform = 1; + palette_ck_value = surface->format->palette->colors[surface->map->info.colorkey].a; + surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT; + } + } + ret = SDL_LowerBlit(surface, &bounds, convert, &bounds); + /* Restore value */ + if (palette_ck_transform) { + surface->format->palette->colors[surface->map->info.colorkey].a = palette_ck_value; + } + /* Clean up the original surface, and update converted surface */ convert->map->info.r = copy_color.r; convert->map->info.g = copy_color.g; @@ -1055,7 +1072,9 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) { /* The palette is identical, just set the same colorkey */ SDL_SetColorKey(convert, 1, surface->map->info.colorkey); - } else if (format->Amask) { + } else if (!format->palette) { + /* Was done by 'palette_ck_transform' */ + }else if (format->Amask) { set_colorkey_by_color = SDL_TRUE; ignore_alpha = SDL_FALSE; } else { diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index e88a8b60e..c991608f7 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -415,6 +415,7 @@ extern VideoBootStrap Android_bootstrap; extern VideoBootStrap PSP_bootstrap; extern VideoBootStrap RPI_bootstrap; extern VideoBootStrap KMSDRM_bootstrap; +extern VideoBootStrap MALI_bootstrap; extern VideoBootStrap DUMMY_bootstrap; extern VideoBootStrap Wayland_bootstrap; extern VideoBootStrap NACL_bootstrap; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index c63f74631..6220a4a75 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -37,9 +37,9 @@ #include "SDL_opengl.h" #endif /* SDL_VIDEO_OPENGL */ -#if SDL_VIDEO_OPENGL_ES +#if SDL_VIDEO_OPENGL_ES && !SDL_VIDEO_OPENGL #include "SDL_opengles.h" -#endif /* SDL_VIDEO_OPENGL_ES */ +#endif /* SDL_VIDEO_OPENGL_ES && !SDL_VIDEO_OPENGL */ /* GL and GLES2 headers conflict on Linux 32 bits */ #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL @@ -94,6 +94,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_PSP &PSP_bootstrap, #endif +#if SDL_VIDEO_DRIVER_MALI + &MALI_bootstrap, +#endif #if SDL_VIDEO_DRIVER_KMSDRM &KMSDRM_bootstrap, #endif diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h index e34642350..1b90de8cd 100644 --- a/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -61,7 +61,7 @@ SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connect SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx)) SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, void *user_data)) - +SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value)) SDL_KMSDRM_MODULE(GBM) SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm)) diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 54f623e29..d79e92337 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -87,6 +87,12 @@ static int get_dricount(void) if (!(stat(KMSDRM_DRI_PATH, &sb) == 0 && S_ISDIR(sb.st_mode))) { +#if SDL_VIDEO_DRIVER_RPI + // exit silently if VC4 driver is not active + SDL_bool vc4 = (0 == access("/sys/module/vc4/", F_OK)); + if (!vc4) + return 0; +#endif printf("The path %s cannot be opened or is not available\n", KMSDRM_DRI_PATH); return 0; @@ -139,6 +145,28 @@ KMSDRM_Available(void) return ret; } +static drmModeModeInfo * +connector_find_mode(drmModeConnector *connector, const char *mode_str, const unsigned int vrefresh) +{ + short i; + drmModeModeInfo *mode; + for (i = 0; i < connector->count_modes; i++) { + mode = &connector->modes[i]; + if (!strcmp(mode->name, mode_str)) { + /* If the vertical refresh frequency is not specified then return the + * first mode that match with the name. Else, return the mode that match + * the name and the specified vertical refresh frequency. + */ + if (vrefresh == 0) + return mode; + else if (mode->vrefresh == vrefresh) + return mode; + } + } + + return NULL; +} + static void KMSDRM_Destroy(SDL_VideoDevice * device) { @@ -344,12 +372,19 @@ KMSDRM_VideoInit(_THIS) SDL_bool found; int ret = 0; char *devname; + const char *crtc_override; + const char *mode_override; SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata); drmModeRes *resources = NULL; drmModeConnector *connector = NULL; drmModeEncoder *encoder = NULL; SDL_DisplayMode current_mode; SDL_VideoDisplay display; + const char *mode_line_override; + char *hint_video_mode = NULL; + unsigned short hint_vrefresh=0; + char* p; + drmModeModeInfo *override_mode = NULL; /* Allocate display internal data */ SDL_DisplayData *data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); @@ -382,6 +417,11 @@ KMSDRM_VideoInit(_THIS) goto cleanup; } +#ifdef DRM_CLIENT_CAP_ASPECT_RATIO + /* Expose aspect ratio flags to userspace if available */ + KMSDRM_drmSetClientCap(vdata->drm_fd, DRM_CLIENT_CAP_ASPECT_RATIO, 1); +#endif + /* Find the first available connector with modes */ resources = KMSDRM_drmModeGetResources(vdata->drm_fd); if (!resources) { @@ -466,9 +506,48 @@ KMSDRM_VideoInit(_THIS) SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u", vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x, vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height); - data->crtc_id = encoder->crtc_id; - data->cur_mode = vdata->saved_crtc->mode; - vdata->crtc_id = encoder->crtc_id; + + crtc_override = SDL_getenv("SDL_VIDEO_KMSDRM_CRTCID"); + if (crtc_override) + data->crtc_id = vdata->crtc_id = SDL_atoi(crtc_override); + else + data->crtc_id = vdata->crtc_id = encoder->crtc_id; + + mode_override = SDL_getenv("SDL_VIDEO_KMSDRM_MODEID"); + if (mode_override) + data->cur_mode = connector->modes[SDL_atoi(mode_override)]; + else + data->cur_mode = vdata->saved_crtc->mode; + + mode_line_override = SDL_getenv("SDL_VIDEO_KMSDRM_MODELINE"); + if (mode_line_override && !mode_override) { + /* Video mode override, formatted as WxH[@vRefresh] */ + SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO,"Override video mode received - %s", mode_line_override); + + p = strchr(mode_line_override, '@'); + if (p == NULL) { + hint_video_mode =strdup(mode_line_override); + } else { + hint_video_mode = strndup(mode_line_override, (unsigned int)(p - mode_line_override)); + hint_vrefresh = strtoul(p + 1, NULL, 10); + } + + override_mode = connector_find_mode(connector, hint_video_mode, hint_vrefresh); + if (override_mode) { + if ((*override_mode).hdisplay != data->cur_mode.hdisplay || + (*override_mode).vdisplay != data->cur_mode.vdisplay || + (*override_mode).vrefresh != data->cur_mode.vrefresh) { + SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "Changing video mode to %dx%d @ %d",(*override_mode).hdisplay, (*override_mode).vdisplay, (*override_mode).vrefresh); + current_mode.w = (*override_mode).hdisplay; + current_mode.h = (*override_mode).vdisplay; + current_mode.refresh_rate = (*override_mode).vrefresh; + data->cur_mode = (*override_mode); + } + } else { + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Cannot find a suitable video mode on connector %d for mode %s, using default", + connector->connector_id, mode_line_override); + } + } // select default mode if this one is not valid if (vdata->saved_crtc->mode_valid == 0) { diff --git a/src/video/mali-fbdev/SDL_maliopengles.c b/src/video/mali-fbdev/SDL_maliopengles.c new file mode 100644 index 000000000..0e4836d2e --- /dev/null +++ b/src/video/mali-fbdev/SDL_maliopengles.c @@ -0,0 +1,43 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_MALI && SDL_VIDEO_OPENGL_EGL + +#include "SDL_maliopengles.h" +#include "SDL_malivideo.h" + +/* EGL implementation of SDL OpenGL support */ + +int +MALI_GLES_LoadLibrary(_THIS, const char *path) +{ + return SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0); +} + +SDL_EGL_CreateContext_impl(MALI) +SDL_EGL_SwapWindow_impl(MALI) +SDL_EGL_MakeCurrent_impl(MALI) + +#endif /* SDL_VIDEO_DRIVER_MALI && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/mali-fbdev/SDL_maliopengles.h b/src/video/mali-fbdev/SDL_maliopengles.h new file mode 100644 index 000000000..121af74f9 --- /dev/null +++ b/src/video/mali-fbdev/SDL_maliopengles.h @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_maliopengles_h +#define _SDL_maliopengles_h + +#if SDL_VIDEO_DRIVER_MALI && SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +/* OpenGLES functions */ +#define MALI_GLES_GetAttribute SDL_EGL_GetAttribute +#define MALI_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define MALI_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define MALI_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define MALI_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define MALI_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int MALI_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext MALI_GLES_CreateContext(_THIS, SDL_Window * window); +extern int MALI_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int MALI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); + +#endif /* SDL_VIDEO_DRIVER_MALI && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_maliopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/mali-fbdev/SDL_malivideo.c b/src/video/mali-fbdev/SDL_malivideo.c new file mode 100644 index 000000000..1d076a68d --- /dev/null +++ b/src/video/mali-fbdev/SDL_malivideo.c @@ -0,0 +1,323 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_MALI + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_loadso.h" +#include "SDL_events.h" +#include "../../events/SDL_events_c.h" + +#ifdef SDL_INPUT_LINUXEV +#include "../../core/linux/SDL_evdev.h" +#endif + +#include "SDL_malivideo.h" +#include "SDL_maliopengles.h" + + +static int +MALI_Available(void) +{ + return 1; +} + +static void +MALI_Destroy(SDL_VideoDevice * device) +{ + if (device->driverdata != NULL) { + SDL_free(device->driverdata); + device->driverdata = NULL; + } +} + +static SDL_VideoDevice * +MALI_Create() +{ + SDL_VideoDevice *device; + + /* Initialize SDL_VideoDevice structure */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + device->driverdata = NULL; + + /* Setup amount of available displays and current display */ + device->num_displays = 0; + + /* Set device free function */ + device->free = MALI_Destroy; + + /* Setup all functions which we can handle */ + device->VideoInit = MALI_VideoInit; + device->VideoQuit = MALI_VideoQuit; + device->GetDisplayModes = MALI_GetDisplayModes; + device->SetDisplayMode = MALI_SetDisplayMode; + device->CreateSDLWindow = MALI_CreateWindow; + device->SetWindowTitle = MALI_SetWindowTitle; + device->SetWindowPosition = MALI_SetWindowPosition; + device->SetWindowSize = MALI_SetWindowSize; + device->ShowWindow = MALI_ShowWindow; + device->HideWindow = MALI_HideWindow; + device->DestroyWindow = MALI_DestroyWindow; + device->GetWindowWMInfo = MALI_GetWindowWMInfo; + + device->GL_LoadLibrary = MALI_GLES_LoadLibrary; + device->GL_GetProcAddress = MALI_GLES_GetProcAddress; + device->GL_UnloadLibrary = MALI_GLES_UnloadLibrary; + device->GL_CreateContext = MALI_GLES_CreateContext; + device->GL_MakeCurrent = MALI_GLES_MakeCurrent; + device->GL_SetSwapInterval = MALI_GLES_SetSwapInterval; + device->GL_GetSwapInterval = MALI_GLES_GetSwapInterval; + device->GL_SwapWindow = MALI_GLES_SwapWindow; + device->GL_DeleteContext = MALI_GLES_DeleteContext; + + device->PumpEvents = MALI_PumpEvents; + + return device; +} + +VideoBootStrap MALI_bootstrap = { + "mali", + "Mali EGL Video Driver", + MALI_Available, + MALI_Create +}; + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/*****************************************************************************/ + +int +MALI_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + SDL_DisplayData *data; + struct fb_var_screeninfo vinfo; + int fd; + + data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); + if (data == NULL) { + return SDL_OutOfMemory(); + } + + fd = open("/dev/fb0", O_RDWR, 0); + if (fd < 0) { + return SDL_SetError("mali-fbdev: Could not open framebuffer device"); + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) { + MALI_VideoQuit(_this); + return SDL_SetError("mali-fbdev: Could not get framebuffer information"); + } + /* Enable triple buffering */ + /* + vinfo.yres_virtual = vinfo.yres * 3; + if (ioctl(fd, FBIOPUT_VSCREENINFO, vinfo) == -1) { + printf("mali-fbdev: Error setting VSCREENINFO\n"); + } + */ + close(fd); + system("setterm -cursor off"); + + data->native_display.width = vinfo.xres; + data->native_display.height = vinfo.yres; + + SDL_zero(current_mode); + current_mode.w = vinfo.xres; + current_mode.h = vinfo.yres; + /* FIXME: Is there a way to tell the actual refresh rate? */ + current_mode.refresh_rate = 60; + /* 32 bpp for default */ + //current_mode.format = SDL_PIXELFORMAT_ABGR8888; + current_mode.format = SDL_PIXELFORMAT_RGBX8888; + + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = data; + + SDL_AddVideoDisplay(&display); + +#ifdef SDL_INPUT_LINUXEV + if (SDL_EVDEV_Init() < 0) { + return -1; + } +#endif + + return 0; +} + +void +MALI_VideoQuit(_THIS) +{ + /* Clear the framebuffer and ser cursor on again */ + int fd = open("/dev/tty", O_RDWR); + ioctl(fd, VT_ACTIVATE, 5); + ioctl(fd, VT_ACTIVATE, 1); + close(fd); + system("setterm -cursor on"); + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Quit(); +#endif + +} + +void +MALI_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + /* Only one display mode available, the current one */ + SDL_AddDisplayMode(display, &display->current_mode); +} + +int +MALI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +int +MALI_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *windowdata; + SDL_DisplayData *displaydata; + + displaydata = SDL_GetDisplayDriverData(0); + + /* Allocate window internal data */ + windowdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); + if (windowdata == NULL) { + return SDL_OutOfMemory(); + } + + /* Windows have one size for now */ + window->w = displaydata->native_display.width; + window->h = displaydata->native_display.height; + + /* OpenGL ES is the law here */ + window->flags |= SDL_WINDOW_OPENGL; + + if (!_this->egl_data) { + if (SDL_GL_LoadLibrary(NULL) < 0) { + return -1; + } + } + windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &displaydata->native_display); + + if (windowdata->egl_surface == EGL_NO_SURFACE) { + MALI_VideoQuit(_this); + return SDL_SetError("mali-fbdev: Can't create EGL window surface"); + } + + /* Setup driver data for this window */ + window->driverdata = windowdata; + + /* One window, it always has focus */ + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + + /* Window has been successfully created */ + return 0; +} + +void +MALI_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data; + + data = window->driverdata; + if (data) { + if (data->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, data->egl_surface); + data->egl_surface = EGL_NO_SURFACE; + } + SDL_free(data); + } + window->driverdata = NULL; +} + +void +MALI_SetWindowTitle(_THIS, SDL_Window * window) +{ +} + +void +MALI_SetWindowPosition(_THIS, SDL_Window * window) +{ +} + +void +MALI_SetWindowSize(_THIS, SDL_Window * window) +{ +} + +void +MALI_ShowWindow(_THIS, SDL_Window * window) +{ +} + +void +MALI_HideWindow(_THIS, SDL_Window * window) +{ +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool +MALI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major <= SDL_MAJOR_VERSION) { + return SDL_TRUE; + } else { + SDL_SetError("application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + } + + /* Failed to get window manager information */ + return SDL_FALSE; +} + +/*****************************************************************************/ +/* SDL event functions */ +/*****************************************************************************/ +void MALI_PumpEvents(_THIS) +{ +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Poll(); +#endif +} + +#endif /* SDL_VIDEO_DRIVER_MALI */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/mali-fbdev/SDL_malivideo.h b/src/video/mali-fbdev/SDL_malivideo.h new file mode 100644 index 000000000..c14667fa8 --- /dev/null +++ b/src/video/mali-fbdev/SDL_malivideo.h @@ -0,0 +1,80 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_malivideo_h +#define _SDL_malivideo_h + +#include "../../SDL_internal.h" +#include "../SDL_sysvideo.h" + +#include "SDL_egl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct SDL_DisplayData +{ + struct { + unsigned short width; + unsigned short height; + } native_display; +} SDL_DisplayData; + +typedef struct SDL_WindowData +{ + EGLSurface egl_surface; +} SDL_WindowData; + +/****************************************************************************/ +/* SDL_VideoDevice functions declaration */ +/****************************************************************************/ + +/* Display and window functions */ +int MALI_VideoInit(_THIS); +void MALI_VideoQuit(_THIS); +void MALI_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +int MALI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +int MALI_CreateWindow(_THIS, SDL_Window * window); +void MALI_SetWindowTitle(_THIS, SDL_Window * window); +void MALI_SetWindowPosition(_THIS, SDL_Window * window); +void MALI_SetWindowSize(_THIS, SDL_Window * window); +void MALI_ShowWindow(_THIS, SDL_Window * window); +void MALI_HideWindow(_THIS, SDL_Window * window); +void MALI_DestroyWindow(_THIS, SDL_Window * window); + +/* Window manager function */ +SDL_bool MALI_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +/* Event functions */ +void MALI_PumpEvents(_THIS); + +#endif /* _SDL_malivideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/raspberry/SDL_rpimouse.c b/src/video/raspberry/SDL_rpimouse.c index 0a51a40e6..134ebf6b7 100644 --- a/src/video/raspberry/SDL_rpimouse.c +++ b/src/video/raspberry/SDL_rpimouse.c @@ -226,6 +226,9 @@ RPI_FreeCursor(SDL_Cursor * cursor) SDL_free(cursor->driverdata); } SDL_free(cursor); + if (cursor == global_cursor) { + global_cursor = NULL; + } } } diff --git a/src/video/raspberry/SDL_rpivideo.c b/src/video/raspberry/SDL_rpivideo.c index 0f1ac00dc..4528191c0 100644 --- a/src/video/raspberry/SDL_rpivideo.c +++ b/src/video/raspberry/SDL_rpivideo.c @@ -31,6 +31,7 @@ */ /* SDL internals */ +#include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "SDL_version.h" #include "SDL_syswm.h" @@ -260,6 +261,9 @@ RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) int RPI_CreateWindow(_THIS, SDL_Window * window) { + const char *hintScale = SDL_GetHint(SDL_HINT_VIDEO_RPI_SCALE_MODE); + const char *hintRatio = SDL_GetHint(SDL_HINT_VIDEO_RPI_RATIO); + char scalemode = '0'; SDL_WindowData *wdata; SDL_VideoDisplay *display; SDL_DisplayData *displaydata; @@ -269,6 +273,10 @@ RPI_CreateWindow(_THIS, SDL_Window * window) DISPMANX_UPDATE_HANDLE_T dispman_update; uint32_t layer = SDL_RPI_VIDEOLAYER; const char *env; + float srcAspect = 1; + float dstAspect = 1; + int factor_x = 0; + int factor_y = 0; /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */ dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; @@ -283,24 +291,85 @@ RPI_CreateWindow(_THIS, SDL_Window * window) display = SDL_GetDisplayForWindow(window); displaydata = (SDL_DisplayData *) display->driverdata; - /* Windows have one size for now */ - window->w = display->desktop_mode.w; - window->h = display->desktop_mode.h; - - /* OpenGL ES is the law here, buddy */ - window->flags |= SDL_WINDOW_OPENGL; + if (hintScale != NULL) + scalemode = *hintScale; /* Create a dispman element and associate a window to it */ - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = window->w; - dst_rect.height = window->h; + switch(scalemode) { + case '3': + /* Pixel perfect scaling mode. */ + factor_x = (display->desktop_mode.w / window->w); + factor_y = (display->desktop_mode.h / window->h); + if ((factor_x != 0) && (factor_y != 0)) { + if (factor_x >= factor_y) { + dst_rect.width = window->w * factor_y; + dst_rect.height = window->h * factor_y; + } + else { + dst_rect.width = window->w * factor_x; + dst_rect.height = window->h * factor_x; + } + /* Center window. */ + dst_rect.x = (display->desktop_mode.w - dst_rect.width) / 2; + dst_rect.y = (display->desktop_mode.h - dst_rect.height) / 2; + break; + } + /* If integer scale is not possible fallback to mode 1. */ + case '1': + /* Fullscreen mode. */ + /* Calculate source and destination aspect ratios. */ + if (hintRatio != NULL) + srcAspect = strtof(hintRatio, NULL); + else + srcAspect = (float)window->w / (float)window->h; + /* only allow sensible aspect ratios */ + if (srcAspect < 0.2f || srcAspect > 6.0f) + srcAspect = (float)window->w / (float)window->h; + dstAspect = (float)display->desktop_mode.w / (float)display->desktop_mode.h; + /* If source and destination aspect ratios are not equal correct destination width. */ + if (srcAspect < dstAspect) { + dst_rect.width = (unsigned)(display->desktop_mode.h * srcAspect); + dst_rect.height = display->desktop_mode.h; + } + else if (srcAspect > dstAspect) { + dst_rect.width = display->desktop_mode.w; + dst_rect.height = (unsigned)((float)display->desktop_mode.w / srcAspect); + } + else { + dst_rect.width = display->desktop_mode.w; + dst_rect.height = display->desktop_mode.h; + } + /* Center window. */ + dst_rect.x = (display->desktop_mode.w - dst_rect.width) / 2; + dst_rect.y = (display->desktop_mode.h - dst_rect.height) / 2; + break; + case '2': + /* Fullscreen streched mode. */ + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = display->desktop_mode.w; + dst_rect.height = display->desktop_mode.h; + break; + default: + /* Default mode. */ + window->w = display->desktop_mode.w; + window->h = display->desktop_mode.h; + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = window->w; + dst_rect.height = window->h; + break; + } src_rect.x = 0; src_rect.y = 0; src_rect.width = window->w << 16; src_rect.height = window->h << 16; + /* OpenGL ES is the law here, buddy */ + window->flags |= SDL_WINDOW_OPENGL; + env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER); if (env) { layer = SDL_atoi(env);