mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-21 22:32:31 +08:00
wayland: Refactor for video core changes
Accommodate the new video core changes. The new video core changes allow for some window geometry calculation refactoring that simplify the system: - Removal of helper functions - Eliminate some discrepancies between the libdecor and xdg-toplevel paths - No need to short-circuit the video core window size event deduplication check - Exclusive fullscreen windows will always end up on the correct output, even when fullscreen is initiated from the compositor - Better handling of cases where the desktop is scaled, but does not expose the viewport protocol - Return the display bounds for the emulated mode if an exclusive fullscreen window has focus - Fixed cases where changing display properties during runtime wouldn't update the display mode lists - General cleanup
This commit is contained in:
committed by
Sam Lantinga
parent
47cdb532f1
commit
7def1438c3
@@ -361,7 +361,7 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
||||
static void AddEmulatedModes(SDL_DisplayData *dispdata, SDL_bool rot_90)
|
||||
{
|
||||
struct EmulatedMode
|
||||
{
|
||||
@@ -413,8 +413,9 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
||||
|
||||
int i;
|
||||
SDL_DisplayMode mode;
|
||||
const int native_width = dpy->desktop_mode.pixel_w;
|
||||
const int native_height = dpy->desktop_mode.pixel_h;
|
||||
SDL_VideoDisplay *dpy = dispdata->display ? SDL_GetVideoDisplay(dispdata->display) : &dispdata->placeholder;
|
||||
const int native_width = dispdata->pixel_width;
|
||||
const int native_height = dispdata->pixel_height;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(mode_list); ++i) {
|
||||
SDL_zero(mode);
|
||||
@@ -423,18 +424,19 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
||||
mode.refresh_rate = dpy->desktop_mode.refresh_rate;
|
||||
mode.driverdata = dpy->desktop_mode.driverdata;
|
||||
|
||||
if (rot_90) {
|
||||
mode.pixel_w = mode_list[i].h;
|
||||
mode.pixel_h = mode_list[i].w;
|
||||
} else {
|
||||
mode.pixel_w = mode_list[i].w;
|
||||
mode.pixel_h = mode_list[i].h;
|
||||
}
|
||||
|
||||
/* Only add modes that are smaller than the native mode. */
|
||||
if ((mode.pixel_w < native_width && mode.pixel_h < native_height) ||
|
||||
(mode.pixel_w < native_width && mode.pixel_h == native_height) ||
|
||||
(mode.pixel_w == native_width && mode.pixel_h < native_height)) {
|
||||
if ((mode_list[i].w < native_width && mode_list[i].h < native_height) ||
|
||||
(mode_list[i].w < native_width && mode_list[i].h == native_height) ||
|
||||
(mode_list[i].w == native_width && mode_list[i].h < native_height)) {
|
||||
|
||||
if (rot_90) {
|
||||
mode.pixel_w = mode_list[i].h;
|
||||
mode.pixel_h = mode_list[i].w;
|
||||
} else {
|
||||
mode.pixel_w = mode_list[i].w;
|
||||
mode.pixel_h = mode_list[i].h;
|
||||
}
|
||||
|
||||
SDL_AddFullscreenDisplayMode(dpy, &mode);
|
||||
}
|
||||
}
|
||||
@@ -452,22 +454,6 @@ static void display_handle_geometry(void *data,
|
||||
|
||||
{
|
||||
SDL_DisplayData *driverdata = (SDL_DisplayData *)data;
|
||||
SDL_VideoDisplay *display;
|
||||
int i;
|
||||
|
||||
if (driverdata->wl_output_done_count) {
|
||||
/* Clear the wl_output ref so Reset doesn't free it */
|
||||
display = SDL_GetVideoDisplay(driverdata->display);
|
||||
for (i = 0; i < display->num_fullscreen_modes; ++i) {
|
||||
display->fullscreen_modes[i].driverdata = NULL;
|
||||
}
|
||||
|
||||
/* Okay, now it's safe to reset */
|
||||
SDL_ResetFullscreenDisplayModes(display);
|
||||
|
||||
/* The display has officially started over. */
|
||||
driverdata->wl_output_done_count = 0;
|
||||
}
|
||||
|
||||
/* Apply the change from wl-output only if xdg-output is not supported */
|
||||
if (!driverdata->has_logical_position) {
|
||||
@@ -558,14 +544,29 @@ static void display_handle_done(void *data,
|
||||
|
||||
driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1);
|
||||
|
||||
if (driverdata->wl_output_done_count != event_await_count) {
|
||||
if (driverdata->wl_output_done_count < event_await_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the display was already created, reset and rebuild the mode list. */
|
||||
if (driverdata->display != 0) {
|
||||
int i;
|
||||
dpy = SDL_GetVideoDisplay(driverdata->display);
|
||||
|
||||
/* Clear the wl_output ref so Reset doesn't free it */
|
||||
for (i = 0; i < dpy->num_fullscreen_modes; ++i) {
|
||||
dpy->fullscreen_modes[i].driverdata = NULL;
|
||||
}
|
||||
|
||||
/* Okay, now it's safe to reset */
|
||||
SDL_ResetFullscreenDisplayModes(dpy);
|
||||
}
|
||||
|
||||
/* The native display resolution */
|
||||
SDL_zero(native_mode);
|
||||
native_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
/* Transform the pixel values, if necessary. */
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
native_mode.pixel_w = driverdata->pixel_height;
|
||||
native_mode.pixel_h = driverdata->pixel_width;
|
||||
@@ -577,27 +578,29 @@ static void display_handle_done(void *data,
|
||||
native_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
native_mode.driverdata = driverdata->output;
|
||||
|
||||
if (driverdata->has_logical_size) { /* If xdg-output is present... */
|
||||
if (video->viewporter) {
|
||||
/* ...and viewports are supported, calculate the true scale of the output. */
|
||||
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
|
||||
} else {
|
||||
/* ...otherwise, the 'native' pixel values are a multiple of the logical screen size. */
|
||||
driverdata->pixel_width = driverdata->screen_width * (int)driverdata->scale_factor;
|
||||
driverdata->pixel_height = driverdata->screen_height * (int)driverdata->scale_factor;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the screen coordinates from the pixel values, if xdg-output isn't present.
|
||||
* Use the native mode pixel values since they are pre-transformed.
|
||||
*/
|
||||
driverdata->screen_width = native_mode.pixel_w / (int)driverdata->scale_factor;
|
||||
driverdata->screen_height = native_mode.pixel_h / (int)driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* The scaled desktop mode */
|
||||
SDL_zero(desktop_mode);
|
||||
desktop_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
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.pixel_w / (float)driverdata->screen_width;
|
||||
}
|
||||
} else { /* Scale the desktop coordinates, if xdg-output isn't present */
|
||||
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->pixel_width;
|
||||
desktop_mode.pixel_h = driverdata->pixel_height;
|
||||
} else {
|
||||
desktop_mode.pixel_w = driverdata->pixel_height;
|
||||
desktop_mode.pixel_h = driverdata->pixel_width;
|
||||
}
|
||||
desktop_mode.screen_w = driverdata->screen_width;
|
||||
desktop_mode.screen_h = driverdata->screen_height;
|
||||
desktop_mode.display_scale = driverdata->scale_factor;
|
||||
desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
desktop_mode.driverdata = driverdata->output;
|
||||
@@ -609,25 +612,23 @@ static void display_handle_done(void *data,
|
||||
}
|
||||
|
||||
/* Set the desktop display mode. */
|
||||
SDL_memcpy(&dpy->desktop_mode, &desktop_mode, sizeof(&dpy->desktop_mode));
|
||||
SDL_SetDesktopDisplayMode(dpy, &desktop_mode);
|
||||
|
||||
/* If the desktop is scaled... */
|
||||
if (driverdata->scale_factor > 1.0f) {
|
||||
/* ...expose the native resolution if viewports are available... */
|
||||
if (video->viewporter != NULL) {
|
||||
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
|
||||
} else {
|
||||
/* ...if not, expose some smaller, integer scaled resolutions. */
|
||||
int 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;
|
||||
/* ...expose the unscaled, native resolution if the scale is 1.0 or viewports are available... */
|
||||
if (driverdata->scale_factor == 1.0f || video->viewporter != NULL) {
|
||||
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
|
||||
} else {
|
||||
/* ...if not, expose the integer scaled variants of the desktop resolution down to 1. */
|
||||
int i;
|
||||
|
||||
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
|
||||
}
|
||||
desktop_mode.pixel_w = 0;
|
||||
desktop_mode.pixel_h = 0;
|
||||
desktop_mode.screen_w = driverdata->screen_width;
|
||||
desktop_mode.screen_h = driverdata->screen_height;
|
||||
|
||||
for (i = (int)driverdata->scale_factor; i > 0; --i) {
|
||||
desktop_mode.display_scale = (float)i;
|
||||
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +636,7 @@ static void display_handle_done(void *data,
|
||||
if (video->viewporter && mode_emulation_enabled) {
|
||||
const SDL_bool rot_90 = ((driverdata->transform & WL_OUTPUT_TRANSFORM_90) != 0) ||
|
||||
(driverdata->screen_width < driverdata->screen_height);
|
||||
AddEmulatedModes(dpy, rot_90);
|
||||
AddEmulatedModes(driverdata, rot_90);
|
||||
}
|
||||
|
||||
/* Calculate the display DPI */
|
||||
@@ -974,8 +975,19 @@ static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *
|
||||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
rect->x = driverdata->x;
|
||||
rect->y = driverdata->y;
|
||||
rect->w = display->current_mode->screen_w;
|
||||
rect->h = display->current_mode->screen_h;
|
||||
|
||||
/* When an emulated, exclusive fullscreen window has focus, treat the mode dimensions as the display bounds. */
|
||||
if (display->fullscreen_window &&
|
||||
display->fullscreen_window->fullscreen_exclusive &&
|
||||
display->fullscreen_window == SDL_GetFocusWindow() &&
|
||||
display->fullscreen_window->fullscreen_mode.screen_w != 0 &&
|
||||
display->fullscreen_window->fullscreen_mode.screen_h != 0) {
|
||||
rect->w = display->fullscreen_window->fullscreen_mode.screen_w;
|
||||
rect->h = display->fullscreen_window->fullscreen_mode.screen_h;
|
||||
} else {
|
||||
rect->w = display->current_mode->screen_w;
|
||||
rect->h = display->current_mode->screen_h;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,14 +106,13 @@ struct SDL_WindowData
|
||||
float windowed_scale_factor;
|
||||
float pointer_scale_x;
|
||||
float pointer_scale_y;
|
||||
int requested_window_width, requested_window_height;
|
||||
int drawable_width, drawable_height;
|
||||
int fs_output_width, fs_output_height;
|
||||
int window_width, window_height;
|
||||
int wl_window_width, wl_window_height;
|
||||
int system_min_required_width;
|
||||
int system_min_required_height;
|
||||
SDL_bool needs_resize_event;
|
||||
SDL_bool floating_resize_pending;
|
||||
SDL_bool was_floating;
|
||||
SDL_DisplayID fullscreen_display;
|
||||
SDL_bool floating;
|
||||
SDL_bool is_fullscreen;
|
||||
SDL_bool in_fullscreen_transition;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user