We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3949

Summary: OSX: Exclusive fullscreen failure in CGDisplaySetDisplayMode happening in dota2
Product: SDL Reporter: Dan Ginsburg <dang>
Component: videoAssignee: Alex Szpakowski <amaranth72>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: ewasylishen
Version: 2.0.6   
Hardware: x86_64   
OS: macOS 10.12   

Description Dan Ginsburg 2017-11-08 19:39:50 UTC
The problem is that on several Mac models on version 10.12.5, 10.12.6, and 10.11.6 with AMD hardware are failing to enter exclusive fullscreen mode in Dota 2.  See: https://github.com/ValveSoftware/Dota-2/issues/1333

I am able to repro this on Mac Pro 10.11.6 with AMD FirePro D300 by setting my desktop resolution to Scaled 1600x900 and then choosing Exclusive Fullscreen 1920x1080 in Dota 2.  After restarting Dota 2, each time it will fail to enter exclusive fullscreen mode.

I've bisected the problem to this change: 

http://hg.libsdl.org/SDL/rev/1e26564c7288

Reverting that change makes the bug go awawy.

What is happening is that:
* That commit changed Cocoa_GetDisplayModes to pass a dict with kCGDisplayShowDuplicateLowResolutionModes to CGDisplayCopyAllDisplayModes.  If I remove that portion of the change, it resolves the issue.
* What is happening is that in Cocoa_SetDisplayMode the call to CGDisplaySetDisplayMode is returning kCGErrorFailure.
* I also see this in the output log:

Nov  8 11:29:28  dota2[62909] <Warning>: displaySetMode: unable to find mode dict in array

I tried changing CGDisplaySetDisplayMode to take a similar dict, but it does not fix the problem.

It seems the kCGDisplayShowDuplicateLowResolutionModes is an undocumented API so I wonder if it can't reliably be used.
Comment 1 Sam Lantinga 2017-11-08 19:57:04 UTC
Alex, this is affecting DOTA 2, so we're going to back out the change until you have a chance to look at it.
Comment 2 Eric Wasylishen 2017-11-09 21:37:16 UTC
BTW here is a quick hacky bit of logging you can paste in Cocoa_GetDisplayModes to see what kCGDisplayShowDuplicateLowResolutionModes is doing on that machine / config:

    {
        NSLog(@"display modes for %s with kCGDisplayShowDuplicateLowResolutionModes set to true:", Cocoa_GetDisplayName(data->display));
        for (id mode in (NSArray *)CGDisplayCopyAllDisplayModes(data->display, (CFDictionaryRef)@{(id)kCGDisplayShowDuplicateLowResolutionModes : (id)kCFBooleanTrue})) {
            CGDisplayModeRef cgmode = (CGDisplayModeRef)mode;
            NSLog(@"    %dx%d points, %dx%d pixels @ %d Hz", (int)CGDisplayModeGetWidth(cgmode), (int)CGDisplayModeGetHeight(cgmode), (int)CGDisplayModeGetPixelWidth(cgmode), (int)CGDisplayModeGetPixelHeight(cgmode), (int)CGDisplayModeGetRefreshRate(cgmode));
        }
        NSLog(@"display modes for %s with no flags:", Cocoa_GetDisplayName(data->display));
        for (id mode in (NSArray*)CGDisplayCopyAllDisplayModes(data->display, NULL)) {
            CGDisplayModeRef cgmode = (CGDisplayModeRef)mode;
            NSLog(@"    %dx%d points, %dx%d pixels @ %d Hz", (int)CGDisplayModeGetWidth(cgmode), (int)CGDisplayModeGetHeight(cgmode), (int)CGDisplayModeGetPixelWidth(cgmode), (int)CGDisplayModeGetPixelHeight(cgmode), (int)CGDisplayModeGetRefreshRate(cgmode));
        }
    }

On my 15" retina macbook pro (2012) with nVidia graphics, setting kCGDisplayShowDuplicateLowResolutionModes to true causes "high DPI" display modes to show up in the list, e.g. "1920x1200 points, 3840x2400 pixels @ 0 Hz", otherwise all of the modes have equal points and pixels sizes.

It might also be worth checking the CGDisplayModeGetWidth and CGDisplayModeGetPixelWidth of the mode that causes CGDisplaySetDisplayMode to fail.

At first glance it seems like on the AMD machine, kCGDisplayShowDuplicateLowResolutionModes is causing some 1920x1080 points mode to be returned that can't actually be switched to.
Comment 3 Alex Szpakowski 2019-10-24 23:17:15 UTC
I've applied an improved version of the original change that was backed out. This time it also falls back to the legacy codepath on macOS 10.12 and older: https://hg.libsdl.org/SDL/rev/d62dcbe19211