Allow Cocoa_VideoInit to succeed when current display mode has invalid flags

This fixes a specific issue seen on macOS 10.14.6 where a DELL E248WFP
Display connected to a 2014 Mac Mini with a scaled 1920x1080 resolution
selected and SDL_Init(SDL_INIT_VIDEO) failed with the error: "The video
driver did not add any displays".

The underlying cause was that the current 1080p display mode did not
have the flag kDisplayModeSafeFlag, the check for which was added in
a963e36, with the idea that certain display modes should not be
candidates for switching to in fullscreen exclusive mode. That may well
be the right thing to do for filtering down a list of candidate modes,
but it doesn't pay to be so picky about the current mode. After all,
this current mode was set by System Preferences, the picture does appear
correctly on screen, and other non-SDL based applications launch and run
correctly in this mode.

Therefore the fix is to have GetDisplayMode only filter out a mode based
on flags if it's part of a candidate list, but if it's the current mode
and it can possibly be converted to an SDL_DisplayMode, do so.
This commit is contained in:
James Howard 2021-10-19 10:49:17 -07:00 committed by Sam Lantinga
parent 649a33ae47
commit d9c44b6537
1 changed files with 7 additions and 5 deletions

View File

@ -162,7 +162,7 @@ GetDisplayModePixelFormat(CGDisplayModeRef vidmode)
}
static SDL_bool
GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmodeCurrent, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
{
SDL_DisplayModeData *data;
bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode);
@ -178,7 +178,9 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi
return SDL_FALSE;
}
if (!HasValidDisplayModeFlags(vidmode)) {
/* Don't fail the current mode based on flags because this could prevent Cocoa_InitModes from
* succeeding if the current mode lacks certain flags (esp kDisplayModeSafeFlag). */
if (!vidmodeCurrent && !HasValidDisplayModeFlags(vidmode)) {
return SDL_FALSE;
}
@ -375,7 +377,7 @@ Cocoa_InitModes(_THIS)
SDL_zero(display);
/* this returns a stddup'ed string */
display.name = (char *)Cocoa_GetDisplayName(displays[i]);
if (!GetDisplayMode(_this, moderef, NULL, link, &mode)) {
if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) {
CVDisplayLinkRelease(link);
CGDisplayModeRelease(moderef);
SDL_free(display.name);
@ -499,7 +501,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
* sure there are no duplicates so it's safe to always add the desktop mode
* even in cases where it is in the CopyAllDisplayModes list.
*/
if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, NULL, link, &desktopmode)) {
if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) {
if (!SDL_AddDisplayMode(display, &desktopmode)) {
CFRelease(((SDL_DisplayModeData*)desktopmode.driverdata)->modes);
SDL_free(desktopmode.driverdata);
@ -546,7 +548,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
SDL_DisplayMode mode;
if (GetDisplayMode(_this, moderef, modes, link, &mode)) {
if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) {
if (!SDL_AddDisplayMode(display, &mode)) {
CFRelease(((SDL_DisplayModeData*)mode.driverdata)->modes);
SDL_free(mode.driverdata);