mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-20 22:16:49 +01:00
kmsdrm: use PLANE and CRTC to do hardware-driven window scaling and AR-correction.
This commit is contained in:
parent
fe3f97961b
commit
31b1794534
@ -142,10 +142,12 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
|||||||
info.plane = dispdata->display_plane;
|
info.plane = dispdata->display_plane;
|
||||||
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
info.fb_id = fb->fb_id;
|
info.fb_id = fb->fb_id;
|
||||||
info.src_w = dispdata->mode.hdisplay;
|
|
||||||
info.src_h = dispdata->mode.vdisplay;
|
info.src_w = window->w;
|
||||||
info.crtc_w = dispdata->mode.hdisplay;
|
info.src_h = window->h;
|
||||||
info.crtc_h = dispdata->mode.vdisplay;
|
info.crtc_w = windata->output_w;
|
||||||
|
info.crtc_h = windata->output_h;
|
||||||
|
info.crtc_x = windata->output_x;
|
||||||
|
|
||||||
ret = drm_atomic_set_plane_props(&info);
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -237,10 +239,12 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
|
|||||||
info.plane = dispdata->display_plane;
|
info.plane = dispdata->display_plane;
|
||||||
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
info.fb_id = fb->fb_id;
|
info.fb_id = fb->fb_id;
|
||||||
info.src_w = dispdata->mode.hdisplay;
|
|
||||||
info.src_h = dispdata->mode.vdisplay;
|
info.src_w = window->w;
|
||||||
info.crtc_w = dispdata->mode.hdisplay;
|
info.src_h = window->h;
|
||||||
info.crtc_h = dispdata->mode.vdisplay;
|
info.crtc_w = windata->output_w;
|
||||||
|
info.crtc_h = windata->output_h;
|
||||||
|
info.crtc_x = windata->output_x;
|
||||||
|
|
||||||
ret = drm_atomic_set_plane_props(&info);
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -629,6 +629,7 @@ KMSDRM_CreateDevice(int devindex)
|
|||||||
device->SetWindowIcon = KMSDRM_SetWindowIcon;
|
device->SetWindowIcon = KMSDRM_SetWindowIcon;
|
||||||
device->SetWindowPosition = KMSDRM_SetWindowPosition;
|
device->SetWindowPosition = KMSDRM_SetWindowPosition;
|
||||||
device->SetWindowSize = KMSDRM_SetWindowSize;
|
device->SetWindowSize = KMSDRM_SetWindowSize;
|
||||||
|
device->SetWindowFullscreen = KMSDRM_SetWindowFullscreen;
|
||||||
device->ShowWindow = KMSDRM_ShowWindow;
|
device->ShowWindow = KMSDRM_ShowWindow;
|
||||||
device->HideWindow = KMSDRM_HideWindow;
|
device->HideWindow = KMSDRM_HideWindow;
|
||||||
device->RaiseWindow = KMSDRM_RaiseWindow;
|
device->RaiseWindow = KMSDRM_RaiseWindow;
|
||||||
@ -814,9 +815,8 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
|||||||
{
|
{
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
Uint32 width = window->w;
|
||||||
Uint32 width = dispdata->mode.hdisplay;
|
Uint32 height = window->h;
|
||||||
Uint32 height = dispdata->mode.vdisplay;
|
|
||||||
Uint32 surface_fmt = GBM_FORMAT_ARGB8888;
|
Uint32 surface_fmt = GBM_FORMAT_ARGB8888;
|
||||||
Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
||||||
#if SDL_VIDEO_OPENGL_EGL
|
#if SDL_VIDEO_OPENGL_EGL
|
||||||
@ -1273,12 +1273,12 @@ int
|
|||||||
KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||||
{
|
{
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* DO NOT add dynamic videomode changes unless you can REALLY test */
|
/* DO NOT add dynamic videomode changes. It makes NO SENSE since the */
|
||||||
/* on all available KMS drivers and fix them in-kernel, and also test */
|
/* PRIMARY PLANE and the CRTC reading it can be used to scale image, */
|
||||||
/* all SDL2 software: things will fail one way or another, and it */
|
/* so any window will appear fullscren with AR correction with NO extra */
|
||||||
/* greatly increases backend complexiity thus compromising it's */
|
/* video memory bandwidth usage. */
|
||||||
/* maintenance. It's NOT as easy as reconstructing GBM and EGL surfaces.*/
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1287,7 +1287,9 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
|||||||
{
|
{
|
||||||
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
|
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
|
||||||
SDL_VideoDisplay *display = NULL;
|
SDL_VideoDisplay *display = NULL;
|
||||||
|
SDL_DisplayData *dispdata = NULL;
|
||||||
SDL_WindowData *windata = NULL;
|
SDL_WindowData *windata = NULL;
|
||||||
|
float ratio;
|
||||||
|
|
||||||
#if SDL_VIDEO_OPENGL_EGL
|
#if SDL_VIDEO_OPENGL_EGL
|
||||||
if (!_this->egl_data) {
|
if (!_this->egl_data) {
|
||||||
@ -1301,10 +1303,22 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
|||||||
windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
|
windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
|
||||||
|
|
||||||
display = SDL_GetDisplayForWindow(window);
|
display = SDL_GetDisplayForWindow(window);
|
||||||
|
dispdata = display->driverdata;
|
||||||
|
|
||||||
/* Windows have one size for now */
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
window->w = display->desktop_mode.w;
|
/* Windows only have one possible size in fullscreen mode. */
|
||||||
window->h = display->desktop_mode.h;
|
window->w = dispdata->mode.hdisplay;
|
||||||
|
window->h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_w = dispdata->mode.hdisplay;
|
||||||
|
windata->output_h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_x = 0;
|
||||||
|
} else {
|
||||||
|
/* Get output (CRTC) size and position, for AR correction. */
|
||||||
|
ratio = (float)window->w / (float)window->h;
|
||||||
|
windata->output_w = dispdata->mode.vdisplay * ratio;
|
||||||
|
windata->output_h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_x = (dispdata->mode.hdisplay - windata->output_w) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't force fullscreen on all windows: it confuses programs that try
|
/* Don't force fullscreen on all windows: it confuses programs that try
|
||||||
to set a window fullscreen after creating it as non-fullscreen (sm64ex) */
|
to set a window fullscreen after creating it as non-fullscreen (sm64ex) */
|
||||||
@ -1401,6 +1415,36 @@ KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
|
{
|
||||||
|
|
||||||
|
SDL_WindowData *windata = window->driverdata;
|
||||||
|
SDL_DisplayData *dispdata = display->driverdata;
|
||||||
|
float ratio;
|
||||||
|
|
||||||
|
KMSDRM_SetPendingSurfacesDestruction(_this, window);
|
||||||
|
|
||||||
|
if (fullscreen) {
|
||||||
|
/* Windows only have one possible size in fullscreen mode. */
|
||||||
|
window->w = dispdata->mode.hdisplay;
|
||||||
|
window->h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_w = dispdata->mode.hdisplay;
|
||||||
|
windata->output_h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_x = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Get output (CRTC) size and position, for AR correction. */
|
||||||
|
ratio = (float)window->w / (float)window->h;
|
||||||
|
windata->output_w = dispdata->mode.vdisplay * ratio;
|
||||||
|
windata->output_h = dispdata->mode.vdisplay;
|
||||||
|
windata->output_x = (dispdata->mode.hdisplay - windata->output_w) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KMSDRM_CreateSurfaces(_this, window)) {
|
||||||
|
SDL_SetError("Can't recreate window surfaces on SetWindowFullscreen.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void
|
||||||
KMSDRM_ShowWindow(_THIS, SDL_Window * window)
|
KMSDRM_ShowWindow(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,12 @@ typedef struct SDL_WindowData
|
|||||||
#if SDL_VIDEO_OPENGL_EGL
|
#if SDL_VIDEO_OPENGL_EGL
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For scaling and AR correction. */
|
||||||
|
int32_t output_w;
|
||||||
|
int32_t output_h;
|
||||||
|
int32_t output_x;
|
||||||
|
|
||||||
} SDL_WindowData;
|
} SDL_WindowData;
|
||||||
|
|
||||||
typedef struct KMSDRM_FBInfo
|
typedef struct KMSDRM_FBInfo
|
||||||
@ -133,21 +139,19 @@ typedef struct KMSDRM_FBInfo
|
|||||||
uint32_t fb_id; /* DRM framebuffer ID */
|
uint32_t fb_id; /* DRM framebuffer ID */
|
||||||
} KMSDRM_FBInfo;
|
} KMSDRM_FBInfo;
|
||||||
|
|
||||||
/* Info passed to set_plane_props calls. hdisplay and vdisplay in a drm mode are uint16_t,
|
|
||||||
so that's what we use for sizes and positions here. IDs are uint32_t as always. */
|
|
||||||
typedef struct KMSDRM_PlaneInfo
|
typedef struct KMSDRM_PlaneInfo
|
||||||
{
|
{
|
||||||
struct plane *plane;
|
struct plane *plane;
|
||||||
uint32_t fb_id;
|
uint32_t fb_id;
|
||||||
uint32_t crtc_id;
|
uint32_t crtc_id;
|
||||||
uint16_t src_x;
|
int32_t src_x;
|
||||||
uint16_t src_y;
|
int32_t src_y;
|
||||||
uint16_t src_w;
|
int32_t src_w;
|
||||||
uint16_t src_h;
|
int32_t src_h;
|
||||||
uint16_t crtc_x;
|
int32_t crtc_x;
|
||||||
uint16_t crtc_y;
|
int32_t crtc_y;
|
||||||
uint16_t crtc_w;
|
int32_t crtc_w;
|
||||||
uint16_t crtc_h;
|
int32_t crtc_h;
|
||||||
} KMSDRM_PlaneInfo;
|
} KMSDRM_PlaneInfo;
|
||||||
|
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
@ -182,6 +186,7 @@ void KMSDRM_SetWindowTitle(_THIS, SDL_Window * window);
|
|||||||
void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
||||||
void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window);
|
void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_SetWindowSize(_THIS, SDL_Window * window);
|
void KMSDRM_SetWindowSize(_THIS, SDL_Window * window);
|
||||||
|
void KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen);
|
||||||
void KMSDRM_ShowWindow(_THIS, SDL_Window * window);
|
void KMSDRM_ShowWindow(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_HideWindow(_THIS, SDL_Window * window);
|
void KMSDRM_HideWindow(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_RaiseWindow(_THIS, SDL_Window * window);
|
void KMSDRM_RaiseWindow(_THIS, SDL_Window * window);
|
||||||
|
Loading…
Reference in New Issue
Block a user