diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 2f8c644c8b7e3..f78e9c0bc810c 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 da3ad52239e10..fa6e6b6f43c11 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 dd9d16a888e01..02d390cd27ef5 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 d4b1d99a93e50..974ac30b5df9f 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 d1a2b4abdfc9a..3654928088a02 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 d115a91f172ee..a26b0e4f9fe76 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 7dc8ca4c151b5..8907893260e37 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); } }