mirror of https://github.com/libsdl-org/SDL
wayland: Correct mode values to use pixels instead of screen units
Fixes the Wayland backend to report the desktop mode dimensions in pixels instead of screen units, adjusts enumerated fullscreen resolutions to use the correct pixel values and scaling, and changes some nomenclature to reflect the terminology used in the new DPI system.
This commit is contained in:
parent
0229091f37
commit
ba74e76e56
|
@ -298,7 +298,7 @@ static void xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xd
|
|||
{
|
||||
SDL_WaylandOutputData *driverdata = data;
|
||||
|
||||
if (driverdata->width != 0 && driverdata->height != 0) {
|
||||
if (driverdata->screen_width != 0 && driverdata->screen_height != 0) {
|
||||
/* FIXME: GNOME has a bug where the logical size does not account for
|
||||
* scale, resulting in bogus viewport sizes.
|
||||
*
|
||||
|
@ -307,7 +307,7 @@ static void xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xd
|
|||
* detected otherwise), then override if necessary.
|
||||
* -flibit
|
||||
*/
|
||||
const float scale = (float)driverdata->width / (float)width;
|
||||
const float scale = (float)driverdata->screen_width / (float)width;
|
||||
if ((scale == 1.0f) && (driverdata->scale_factor != 1.0f)) {
|
||||
SDL_LogWarn(
|
||||
SDL_LOG_CATEGORY_VIDEO,
|
||||
|
@ -316,8 +316,8 @@ static void xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xd
|
|||
}
|
||||
}
|
||||
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
driverdata->screen_width = width;
|
||||
driverdata->screen_height = height;
|
||||
driverdata->has_logical_size = SDL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -414,12 +414,15 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
|||
|
||||
int i;
|
||||
SDL_DisplayMode mode;
|
||||
const int native_width = dpy->display_modes->w;
|
||||
const int native_height = dpy->display_modes->h;
|
||||
const int native_width = dpy->display_modes->pixel_w;
|
||||
const int native_height = dpy->display_modes->pixel_h;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(mode_list); ++i) {
|
||||
mode = *dpy->display_modes;
|
||||
SDL_zero(mode);
|
||||
mode.format = dpy->display_modes->format;
|
||||
mode.display_scale = 1.0f;
|
||||
mode.refresh_rate = dpy->display_modes->refresh_rate;
|
||||
mode.driverdata = dpy->display_modes->driverdata;
|
||||
|
||||
if (rot_90) {
|
||||
mode.pixel_w = mode_list[i].h;
|
||||
|
@ -521,16 +524,16 @@ static void display_handle_mode(void *data,
|
|||
SDL_WaylandOutputData *driverdata = data;
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
driverdata->native_width = width;
|
||||
driverdata->native_height = height;
|
||||
driverdata->pixel_width = width;
|
||||
driverdata->pixel_height = height;
|
||||
|
||||
/*
|
||||
* Don't rotate this yet, wl-output coordinates are transformed in
|
||||
* handle_done and xdg-output coordinates are pre-transformed.
|
||||
*/
|
||||
if (!driverdata->has_logical_size) {
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
driverdata->screen_width = width;
|
||||
driverdata->screen_height = height;
|
||||
}
|
||||
|
||||
driverdata->refresh = refresh;
|
||||
|
@ -565,11 +568,11 @@ static void display_handle_done(void *data,
|
|||
native_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
native_mode.pixel_w = driverdata->native_height;
|
||||
native_mode.pixel_h = driverdata->native_width;
|
||||
native_mode.pixel_w = driverdata->pixel_height;
|
||||
native_mode.pixel_h = driverdata->pixel_width;
|
||||
} else {
|
||||
native_mode.pixel_w = driverdata->native_width;
|
||||
native_mode.pixel_h = driverdata->native_height;
|
||||
native_mode.pixel_w = driverdata->pixel_width;
|
||||
native_mode.pixel_h = driverdata->pixel_height;
|
||||
}
|
||||
native_mode.display_scale = 1.0f;
|
||||
native_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
|
@ -581,20 +584,20 @@ static void display_handle_done(void *data,
|
|||
|
||||
if (driverdata->has_logical_size) { /* If xdg-output is present, calculate the true scale of the desktop */
|
||||
if (video->viewporter) {
|
||||
driverdata->scale_factor = (float)native_mode.w / (float)driverdata->width;
|
||||
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
|
||||
}
|
||||
} else { /* Scale the desktop coordinates, if xdg-output isn't present */
|
||||
driverdata->width /= driverdata->scale_factor;
|
||||
driverdata->height /= driverdata->scale_factor;
|
||||
driverdata->screen_width /= driverdata->scale_factor;
|
||||
driverdata->screen_height /= driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* xdg-output dimensions are already transformed, so no need to rotate. */
|
||||
if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) {
|
||||
desktop_mode.pixel_w = driverdata->width;
|
||||
desktop_mode.pixel_h = driverdata->height;
|
||||
desktop_mode.pixel_w = driverdata->pixel_width;
|
||||
desktop_mode.pixel_h = driverdata->pixel_height;
|
||||
} else {
|
||||
desktop_mode.pixel_w = driverdata->height;
|
||||
desktop_mode.pixel_h = driverdata->width;
|
||||
desktop_mode.pixel_w = driverdata->pixel_height;
|
||||
desktop_mode.pixel_h = driverdata->pixel_width;
|
||||
}
|
||||
desktop_mode.display_scale = driverdata->scale_factor;
|
||||
desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
|
@ -617,10 +620,15 @@ static void display_handle_done(void *data,
|
|||
if (video->viewporter != NULL) {
|
||||
SDL_AddDisplayMode(dpy, &native_mode);
|
||||
} else {
|
||||
/* ...if not, expose the integer scale desktop modes down to 1.0. */
|
||||
/* ...if not, expose some smaller, integer scaled resolutions. */
|
||||
int i;
|
||||
for (i = (int)driverdata->scale_factor - 1; i > 0; --i) {
|
||||
const int base_pixel_w = desktop_mode.pixel_w / (int)desktop_mode.display_scale;
|
||||
const int base_pixel_h = desktop_mode.pixel_h / (int)desktop_mode.display_scale;
|
||||
for (i = 1; i < (int)desktop_mode.display_scale; ++i) {
|
||||
desktop_mode.pixel_w = base_pixel_w * i;
|
||||
desktop_mode.pixel_h = base_pixel_h * i;
|
||||
desktop_mode.display_scale = (float)i;
|
||||
|
||||
SDL_AddDisplayMode(dpy, &desktop_mode);
|
||||
}
|
||||
}
|
||||
|
@ -629,23 +637,23 @@ static void display_handle_done(void *data,
|
|||
/* Add emulated modes if wp_viewporter is supported and mode emulation is enabled. */
|
||||
if (video->viewporter && mode_emulation_enabled) {
|
||||
const SDL_bool rot_90 = ((driverdata->transform & WL_OUTPUT_TRANSFORM_90) != 0) ||
|
||||
(driverdata->width < driverdata->height);
|
||||
(driverdata->screen_width < driverdata->screen_height);
|
||||
AddEmulatedModes(dpy, rot_90);
|
||||
}
|
||||
|
||||
/* Calculate the display DPI */
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
driverdata->hdpi = driverdata->physical_height ? (((float)driverdata->height) * 25.4f / driverdata->physical_height) : 0.0f;
|
||||
driverdata->vdpi = driverdata->physical_width ? (((float)driverdata->width) * 25.4f / driverdata->physical_width) : 0.0f;
|
||||
driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->height,
|
||||
driverdata->width,
|
||||
driverdata->hdpi = driverdata->physical_height ? (((float)driverdata->pixel_height) * 25.4f / driverdata->physical_height) : 0.0f;
|
||||
driverdata->vdpi = driverdata->physical_width ? (((float)driverdata->pixel_width) * 25.4f / driverdata->physical_width) : 0.0f;
|
||||
driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->pixel_height,
|
||||
driverdata->pixel_width,
|
||||
((float)driverdata->physical_height) / 25.4f,
|
||||
((float)driverdata->physical_width) / 25.4f);
|
||||
} else {
|
||||
driverdata->hdpi = driverdata->physical_width ? (((float)driverdata->width) * 25.4f / driverdata->physical_width) : 0.0f;
|
||||
driverdata->vdpi = driverdata->physical_height ? (((float)driverdata->height) * 25.4f / driverdata->physical_height) : 0.0f;
|
||||
driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->width,
|
||||
driverdata->height,
|
||||
driverdata->hdpi = driverdata->physical_width ? (((float)driverdata->pixel_width) * 25.4f / driverdata->physical_width) : 0.0f;
|
||||
driverdata->vdpi = driverdata->physical_height ? (((float)driverdata->pixel_height) * 25.4f / driverdata->physical_height) : 0.0f;
|
||||
driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->pixel_width,
|
||||
driverdata->pixel_height,
|
||||
((float)driverdata->physical_width) / 25.4f,
|
||||
((float)driverdata->physical_height) / 25.4f);
|
||||
}
|
||||
|
|
|
@ -109,8 +109,8 @@ struct SDL_WaylandOutputData
|
|||
struct zxdg_output_v1 *xdg_output;
|
||||
uint32_t registry_id;
|
||||
float scale_factor;
|
||||
int native_width, native_height;
|
||||
int x, y, width, height, refresh, transform;
|
||||
int pixel_width, pixel_height;
|
||||
int x, y, screen_width, screen_height, refresh, transform;
|
||||
SDL_DisplayOrientation orientation;
|
||||
int physical_width, physical_height;
|
||||
float ddpi, hdpi, vdpi;
|
||||
|
|
|
@ -62,8 +62,8 @@ static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height,
|
|||
|
||||
int fs_width, fs_height;
|
||||
int buf_width, buf_height;
|
||||
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->width;
|
||||
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->height;
|
||||
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
|
||||
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
|
||||
|
||||
/*
|
||||
* Fullscreen desktop mandates a desktop sized window, so that's what applications will get.
|
||||
|
@ -76,24 +76,24 @@ static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height,
|
|||
|
||||
/* If the application is DPI aware, we can expose the true backbuffer size */
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
buf_width = output->native_width;
|
||||
buf_height = output->native_height;
|
||||
buf_width = output->pixel_width;
|
||||
buf_height = output->pixel_height;
|
||||
} else {
|
||||
buf_width = fs_width;
|
||||
buf_height = fs_height;
|
||||
}
|
||||
} else {
|
||||
/* If a mode was set, use it, otherwise use the native resolution. */
|
||||
if (window->fullscreen_mode.w != 0 && window->fullscreen_mode.h != 0) {
|
||||
fs_width = window->fullscreen_mode.w;
|
||||
fs_height = window->fullscreen_mode.h;
|
||||
buf_width = (int)SDL_lroundf((float)fs_width * window->fullscreen_mode.display_scale);
|
||||
buf_height = (int)SDL_lroundf((float)fs_height * window->fullscreen_mode.display_scale);
|
||||
if (window->fullscreen_mode.pixel_w != 0 && window->fullscreen_mode.pixel_h != 0) {
|
||||
fs_width = window->fullscreen_mode.screen_w;
|
||||
fs_height = window->fullscreen_mode.screen_h;
|
||||
buf_width = window->fullscreen_mode.pixel_w;
|
||||
buf_height = window->fullscreen_mode.pixel_h;
|
||||
} else {
|
||||
fs_width = disp->display_modes[0].w;
|
||||
fs_height = disp->display_modes[0].h;
|
||||
buf_width = (int)SDL_lroundf((float)fs_width * disp->display_modes[0].display_scale);
|
||||
buf_height = (int)SDL_lroundf((float)fs_width * disp->display_modes[0].display_scale);
|
||||
fs_width = disp->display_modes[0].screen_w;
|
||||
fs_height = disp->display_modes[0].screen_h;
|
||||
buf_width = disp->display_modes[0].pixel_w;
|
||||
buf_height = disp->display_modes[0].pixel_h;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,21 +129,23 @@ static SDL_bool WindowNeedsViewport(SDL_Window *window)
|
|||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoData *video = wind->waylandData;
|
||||
SDL_WaylandOutputData *output = ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata);
|
||||
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
|
||||
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
|
||||
int fs_width, fs_height;
|
||||
|
||||
/*
|
||||
* A viewport is only required when scaling is enabled and:
|
||||
* - The surface scale is fractional.
|
||||
* - A fullscreen mode is being emulated and the mode does not match the logical desktop dimensions.
|
||||
* - The desktop uses fractional scaling and the high-DPI flag is set.
|
||||
*/
|
||||
if (video->viewporter != NULL) {
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
if (SurfaceScaleIsFractional(window)) {
|
||||
return SDL_TRUE;
|
||||
} else if (FullscreenModeEmulation(window)) {
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
|
||||
if (fs_width != output->width || fs_height != output->height) {
|
||||
if (fs_width != output_width || fs_height != output_height) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
} else if (SurfaceScaleIsFractional(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,8 +227,8 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
int fs_width, fs_height;
|
||||
const int output_width = data->fs_output_width ? data->fs_output_width : output->width;
|
||||
const int output_height = data->fs_output_height ? data->fs_output_height : output->height;
|
||||
const int output_width = data->fs_output_width ? data->fs_output_width : output->screen_width;
|
||||
const int output_height = data->fs_output_height ? data->fs_output_height : output->screen_height;
|
||||
|
||||
window_size_changed = data->window_width != output_width || data->window_height != output_height;
|
||||
|
||||
|
@ -238,14 +240,21 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
wl_surface_set_buffer_scale(data->surface, 1);
|
||||
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height,
|
||||
output_width, output_height);
|
||||
|
||||
data->window_width = output_width;
|
||||
data->window_height = output_height;
|
||||
|
||||
data->pointer_scale_x = (float)fs_width / (float)output_width;
|
||||
data->pointer_scale_y = (float)fs_height / (float)output_height;
|
||||
} else {
|
||||
wl_surface_set_buffer_scale(data->surface, (int32_t)window->fullscreen_mode.display_scale);
|
||||
}
|
||||
data->window_width = output_width;
|
||||
data->window_height = output_height;
|
||||
|
||||
data->pointer_scale_x = (float)fs_width / (float)output_width;
|
||||
data->pointer_scale_y = (float)fs_height / (float)output_height;
|
||||
data->window_width = fs_width;
|
||||
data->window_height = fs_height;
|
||||
|
||||
data->pointer_scale_x = 1.0f;
|
||||
data->pointer_scale_y = 1.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
window_size_changed = data->window_width != window->w || data->window_height != window->h;
|
||||
|
@ -444,13 +453,13 @@ static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
|
|||
* otherwise, fall back to SDL_WINDOW_FULLSCREEN_DESKTOP.
|
||||
*/
|
||||
if (!wind->fullscreen_flags) {
|
||||
if (window->fullscreen_mode.w && window->fullscreen_mode.h) {
|
||||
if (window->fullscreen_mode.pixel_w && window->fullscreen_mode.pixel_h) {
|
||||
wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN;
|
||||
} else {
|
||||
wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
} else if (wind->fullscreen_flags != SDL_WINDOW_FULLSCREEN_DESKTOP &&
|
||||
(!window->fullscreen_mode.w || !window->fullscreen_mode.h)) {
|
||||
(!window->fullscreen_mode.pixel_w || !window->fullscreen_mode.pixel_h)) {
|
||||
wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue