Browse Source

wayland: Fixups for new DPI code

Add support for the pixel density hint and fix integer scaling to assume that exclusive fullscreen pixel density values are always 1.
Frank Praznik 1 year ago
parent
commit
68edc72ae8
2 changed files with 13 additions and 9 deletions
  1. 6 5
      src/video/wayland/SDL_waylandvideo.c
  2. 7 4
      src/video/wayland/SDL_waylandwindow.c

+ 6 - 5
src/video/wayland/SDL_waylandvideo.c

@@ -529,11 +529,12 @@ static void display_handle_mode(void *data,
 static void display_handle_done(void *data,
                                 struct wl_output *output)
 {
+    const SDL_bool highdpi_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_ENABLE_HIGH_PIXEL_DENSITY, SDL_TRUE);
+    const SDL_bool mode_emulation_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION, SDL_TRUE);
     SDL_DisplayData *driverdata = (SDL_DisplayData *)data;
     SDL_VideoData *video = driverdata->videodata;
     SDL_DisplayMode native_mode, desktop_mode;
     SDL_VideoDisplay *dpy;
-    const SDL_bool mode_emulation_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION, SDL_TRUE);
 
     /*
      * When using xdg-output, two wl-output.done events will be emitted:
@@ -610,7 +611,7 @@ static void display_handle_done(void *data,
 
     desktop_mode.w = driverdata->screen_width;
     desktop_mode.h = driverdata->screen_height;
-    desktop_mode.pixel_density = driverdata->scale_factor;
+    desktop_mode.pixel_density = highdpi_enabled ? driverdata->scale_factor : 1.0f;
     desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
     desktop_mode.driverdata = driverdata->output;
 
@@ -630,11 +631,11 @@ static void display_handle_done(void *data,
         /* ...otherwise expose the integer scaled variants of the desktop resolution down to 1. */
         int i;
 
-        desktop_mode.w = driverdata->screen_width;
-        desktop_mode.h = driverdata->screen_height;
+        desktop_mode.pixel_density = 1.0f;
 
         for (i = (int)driverdata->scale_factor; i > 0; --i) {
-            desktop_mode.pixel_density = (float)i;
+            desktop_mode.w = driverdata->screen_width * i;
+            desktop_mode.h = driverdata->screen_height * i;
             SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
         }
     }

+ 7 - 4
src/video/wayland/SDL_waylandwindow.c

@@ -91,9 +91,10 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height)
     int buf_width;
     int buf_height;
 
+    /* Exclusive fullscreen modes always have a pixel density of 1 */
     if (data->is_fullscreen && window->fullscreen_exclusive) {
-        buf_width = (int)SDL_lroundf(window->current_fullscreen_mode.w * window->current_fullscreen_mode.pixel_density);
-        buf_height = (int)SDL_lroundf(window->current_fullscreen_mode.h * window->current_fullscreen_mode.pixel_density);
+        buf_width = window->current_fullscreen_mode.w;
+        buf_height = window->current_fullscreen_mode.h;
     } else {
         /* Round fractional backbuffer sizes halfway away from zero. */
         buf_width = (int)SDL_lroundf(data->requested_window_width * data->windowed_scale_factor);
@@ -229,9 +230,11 @@ static void ConfigureWindowGeometry(SDL_Window *window)
                 data->wl_window_width = output_width;
                 data->wl_window_height = output_height;
             } else {
-                /* Always use the mode dimensions for integer scaling. */
+                /* Calculate the integer scale from the mode and output. */
+                const int32_t int_scale = SDL_max(window->current_fullscreen_mode.w / output_width, 1);
+
                 UnsetDrawSurfaceViewport(window);
-                wl_surface_set_buffer_scale(data->surface, (int32_t)window->current_fullscreen_mode.pixel_density);
+                wl_surface_set_buffer_scale(data->surface, int_scale);
 
                 data->wl_window_width = window->current_fullscreen_mode.w;
                 data->wl_window_height = window->current_fullscreen_mode.h;