From a66cad79c1bc099cf1835e2f43a891bfb2227671 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 18 May 2023 12:15:23 -0700
Subject: [PATCH] SDL_GetClosestFullscreenDisplayMode() now takes a boolean
whether to include high density modes
Also changed the match to prioritize resolution over refresh rate
---
include/SDL3/SDL_video.h | 2 +-
src/dynapi/SDL_dynapi_procs.h | 2 +-
src/test/SDL_test_common.c | 18 ++++++++++++++----
src/video/SDL_video.c | 15 ++++++++++++---
src/video/kmsdrm/SDL_kmsdrmvideo.c | 2 +-
src/video/uikit/SDL_uikitwindow.m | 7 ++++++-
test/testautomation_video.c | 9 ++-------
7 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index 2f8c644c8b7e..f78e9c0bc810 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -473,7 +473,7 @@ extern DECLSPEC const SDL_DisplayMode **SDLCALL SDL_GetFullscreenDisplayModes(SD
* \sa SDL_GetDisplays
* \sa SDL_GetFullscreenDisplayModes
*/
-extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate);
+extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate, SDL_bool include_high_density_modes);
/**
* Get information about the desktop's display mode.
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index da3ad52239e1..fa6e6b6f43c1 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -903,7 +903,7 @@ SDL_DYNAPI_PROC(int,SDL_ConvertAudioSamples,(SDL_AudioFormat a, Uint8 b, int c,
SDL_DYNAPI_PROC(SDL_DisplayID*,SDL_GetDisplays,(int *a),(a),return)
SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetPrimaryDisplay,(void),(),return)
SDL_DYNAPI_PROC(const SDL_DisplayMode**,SDL_GetFullscreenDisplayModes,(SDL_DisplayID a, int *b),(a,b),return)
-SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d, SDL_bool e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_GetRenderOutputSize,(SDL_Renderer *a, int *b, int *c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_ConvertEventToRenderCoordinates,(SDL_Renderer *a, SDL_Event *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SetRenderScale,(SDL_Renderer *a, float b, float c),(a,b,c),return)
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index dd9d16a888e0..02d390cd27ef 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1288,9 +1288,15 @@ SDLTest_CommonInit(SDLTest_CommonState *state)
}
}
- fullscreen_mode = SDL_GetClosestFullscreenDisplayMode(state->displayID, state->window_w, state->window_h, state->refresh_rate);
- if (fullscreen_mode) {
- SDL_memcpy(&state->fullscreen_mode, fullscreen_mode, sizeof(state->fullscreen_mode));
+ {
+ SDL_bool include_high_density_modes = SDL_FALSE;
+ if (state->window_flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
+ include_high_density_modes = SDL_TRUE;
+ }
+ fullscreen_mode = SDL_GetClosestFullscreenDisplayMode(state->displayID, state->window_w, state->window_h, state->refresh_rate, include_high_density_modes);
+ if (fullscreen_mode) {
+ SDL_memcpy(&state->fullscreen_mode, fullscreen_mode, sizeof(state->fullscreen_mode));
+ }
}
state->windows =
@@ -1866,7 +1872,11 @@ static void FullscreenTo(SDLTest_CommonState *state, int index, int windowId)
new_mode.displayID = displays[index];
if (SDL_SetWindowFullscreenMode(window, &new_mode) < 0) {
/* Try again with a default mode */
- mode = SDL_GetClosestFullscreenDisplayMode(displays[index], state->window_w, state->window_h, state->refresh_rate);
+ SDL_bool include_high_density_modes = SDL_FALSE;
+ if (state->window_flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
+ include_high_density_modes = SDL_TRUE;
+ }
+ mode = SDL_GetClosestFullscreenDisplayMode(displays[index], state->window_w, state->window_h, state->refresh_rate, include_high_density_modes);
SDL_SetWindowFullscreenMode(window, mode);
}
}
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index d4b1d99a93e5..974ac30b5df9 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1062,7 +1062,7 @@ const SDL_DisplayMode **SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, i
return modes;
}
-const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate)
+const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate, SDL_bool include_high_density_modes)
{
const SDL_DisplayMode **modes;
const SDL_DisplayMode *mode, *closest = NULL;
@@ -1096,6 +1096,9 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display
* This mode must be skipped, but closer modes may still follow */
continue;
}
+ if (mode->pixel_density > 1.0f && !include_high_density_modes) {
+ continue;
+ }
if (closest) {
float current_aspect_ratio = (float)mode->w / mode->h;
float closest_aspect_ratio = (float)closest->w / closest->h;
@@ -1104,7 +1107,8 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display
continue;
}
- if (SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) {
+ if (mode->w == closest->w && mode->h == closest->h &&
+ SDL_fabsf(closest->refresh_rate - refresh_rate) < SDL_fabsf(mode->refresh_rate - refresh_rate)) {
/* We already found a mode and the new mode is further from our
* refresh rate target */
continue;
@@ -3272,7 +3276,12 @@ void SDL_OnWindowDisplayChanged(SDL_Window *window)
const SDL_DisplayMode *new_mode = NULL;
if (window->requested_fullscreen_mode.w != 0 || window->requested_fullscreen_mode.h != 0) {
- new_mode = SDL_GetClosestFullscreenDisplayMode(displayID, window->requested_fullscreen_mode.w, window->requested_fullscreen_mode.h, window->requested_fullscreen_mode.refresh_rate);
+ SDL_bool include_high_density_modes = SDL_FALSE;
+
+ if (window->requested_fullscreen_mode.pixel_density > 1.0f) {
+ include_high_density_modes = SDL_TRUE;
+ }
+ new_mode = SDL_GetClosestFullscreenDisplayMode(displayID, window->requested_fullscreen_mode.w, window->requested_fullscreen_mode.h, window->requested_fullscreen_mode.refresh_rate, include_high_density_modes);
}
if (new_mode) {
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index d1a2b4abdfc9..3654928088a0 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -498,7 +498,7 @@ static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display,
const SDL_DisplayMode *closest;
drmModeModeInfo *drm_mode;
- closest = SDL_GetClosestFullscreenDisplayMode(display->id, width, height, 0.0f);
+ closest = SDL_GetClosestFullscreenDisplayMode(display->id, width, height, 0.0f, SDL_FALSE);
if (closest) {
const SDL_DisplayModeData *modedata = (const SDL_DisplayModeData *)closest->driverdata;
drm_mode = &connector->modes[modedata->mode_index];
diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m
index d115a91f172e..a26b0e4f9fe7 100644
--- a/src/video/uikit/SDL_uikitwindow.m
+++ b/src/video/uikit/SDL_uikitwindow.m
@@ -169,7 +169,12 @@ int UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
#if !TARGET_OS_TV
const CGSize origsize = data.uiscreen.currentMode.size;
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
- const SDL_DisplayMode *bestmode = SDL_GetClosestFullscreenDisplayMode(display->id, window->w, window->h, 0.0f);
+ const SDL_DisplayMode *bestmode;
+ SDL_bool include_high_density_modes = SDL_FALSE;
+ if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
+ include_high_density_modes = SDL_TRUE;
+ }
+ bestmode = SDL_GetClosestFullscreenDisplayMode(display->id, window->w, window->h, 0.0f, include_high_density_modes);
if (bestmode) {
SDL_UIKitDisplayModeData *modedata = (__bridge SDL_UIKitDisplayModeData *)bestmode->driverdata;
[data.uiscreen setCurrentMode:modedata.uiscreenmode];
diff --git a/test/testautomation_video.c b/test/testautomation_video.c
index 7dc8ca4c151b..8907893260e3 100644
--- a/test/testautomation_video.c
+++ b/test/testautomation_video.c
@@ -303,10 +303,7 @@ static int video_getClosestDisplayModeCurrentResolution(void *arg)
SDL_memcpy(¤t, modes[0], sizeof(current));
/* Make call */
- closest = SDL_GetClosestFullscreenDisplayMode(displays[i],
- current.w,
- current.h,
- current.refresh_rate);
+ closest = SDL_GetClosestFullscreenDisplayMode(displays[i], current.w, current.h, current.refresh_rate, SDL_FALSE);
SDLTest_AssertPass("Call to SDL_GetClosestFullscreenDisplayMode(target=current)");
SDLTest_Assert(closest != NULL, "Verify returned value is not NULL");
@@ -356,9 +353,7 @@ static int video_getClosestDisplayModeRandomResolution(void *arg)
target.refresh_rate = (variation & 8) ? (float)SDLTest_RandomIntegerInRange(25, 120) : 0.0f;
/* Make call; may or may not find anything, so don't validate any further */
- SDL_GetClosestFullscreenDisplayMode(displays[i], target.w,
- target.h,
- target.refresh_rate);
+ SDL_GetClosestFullscreenDisplayMode(displays[i], target.w, target.h, target.refresh_rate, SDL_FALSE);
SDLTest_AssertPass("Call to SDL_GetClosestFullscreenDisplayMode(target=random/variation%d)", variation);
}
}