Use dispmanx scaling (#1)

* Use dispmanx scaling
* There is the new SDL hint SDL_VIDEO_RPI_SCALE_MODE. There are three
values.
 * 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.
* Add aspect ratio hint
This commit is contained in:
Stefan 2016-07-06 21:53:43 +02:00 committed by Jools Wills
parent dbd2aa7753
commit c1a44d38a0
2 changed files with 81 additions and 9 deletions

View file

@ -621,6 +621,29 @@ 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.
*/
#define SDL_HINT_VIDEO_RPI_SCALE_MODE "SDL_VIDEO_RPI_SCALE_MODE"
/**
* \brief Tell dispmanx to set an 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.
*

View file

@ -31,6 +31,7 @@
*/
/* SDL internals */
#include "SDL_hints.h"
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
@ -214,6 +215,9 @@ RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
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;
@ -235,23 +239,68 @@ 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;
float srcAspect = 1;
float dstAspect = 1;
/* 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 '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;
dispman_update = vc_dispmanx_update_start( 0 );
wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);