MacBook Pro with Retina display - strange behaviour


#1

Hi I wonder if someone could shed some light on this.
I’m using a MacBook Pro 2016 with a native display resolution of 2880x1800.
I’m calling SDL_CreateWindow with the flags SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI and requesting a size of 2880x1800. However, when I later check what resolution I actually got with SDL_GL_GetDrawableSize(WINDOW,&w,&h) it reports that the size is 1680x1050 (which completely agrees with what I am seeing on screen). Even more weirdly, if I call SDL_GetWindowSize(WINDOW,&w,&h) it reports 640x480.
I have set NSHighResolutionCapable in Info,plist. I have even inserted some objective C code to request high DPI drawing!
Is this normal? Is this expected behaviour? I want to make sure that I am getting the most out of my hardware.
Thanks very much in advance.


#2

According to the docs at https://wiki.libsdl.org/SDL_CreateWindow , the width/height params are unused if you specify fullscreen mode. Also, the width/height params of SDL_CreateWindow, and also those of SDL_GetWindowSize, use logical sizes, not physical pixels - so requesting a 2880x1800 window is actually requesting a 5760x3600 pixel window if your macbook is using 2x scaling.

I’m not sure why you got a drawable size of 1680x1050, though.

I would try creating a window with SDL_WINDOW_FULLSCREEN_DESKTOP (this gives you a fullscreen window without changing display modes), and then I expect SDL_GL_GetDrawableSize will return 2880x1800.


Scaled resolutions on retina screens on macOS
#3

Hi Eric,
Thanks so much for your quick reply,
Things are better now, but still very weird.
I changed the flag to SDL_WINDOW_FULLSCREEN_DESKTOP as you suggested and immediately everything in my game looked smaller. A good sign. But now SDL_GL_GetDrawableSize is returning 3360x2100. Which AFAIK my Mac isn’t even capable of! I tried to confirm what was happening by counting my game’s (now very tiny) tiles with my finger and arrived at almost the same figure: 3328x2048 (this is approximate). Which suggests that some pixels are now being missed out. Don’t know, utterly bewildered.
Also, when I made your suggested change, I noticed that the ESC “button” on the touch bar thingy became very unresponsive - I needed to press it several times to quit the game. Maybe this is just because my code is inefficient and it couldn’t cope with the new larger number of tiles… not sure though.
Thanks so much for your help, any other ideas/theories/suggestions very welcome!
Also: any MacBook Pro 2016 coders out there having similar issues?


#4

The 15" 2016 MBP defaults to a weird 1680x1050 @2x (3360x2100) resolution, which is then downscaled to the actual native resolution internally. You can change it to the native 1440x900 @2x (2880x1800) in System Preferences.


#5

Thanks for clarifying that, slime! I had no idea.


#6

Bump,
Hi Eric et al: Okay, I have just established that the documentation is incorrect (at least for a MacBook Pro 15"), because SDL_CreateWindow does behave differently when given different widths and heights in fullscreen mode. When I pass it 2880x1800 I get a very crisp, clear display with the mouse pointer looking (almost?) exactly as it does during general use of the computer. OTOH, if I pass it 1024x768 I get blurry scaled, large and blocky drawing including the mouse pointer.
BTW, I’m using OpenGL directly as in SDL 1.2, not using any of the exotic new 2D drawing stuff in SDL 2.0.
And this makes sense… if you were unable to choose a resolution for your fullscreen app, what would be the point in looping through the display modes with SDL_GetDisplayMode() to store the widths and heights for multiple resolutions in an SDL_DisplayMode structure?
Anyway, I’ve discovered on my MacBook Pro that I need to first request a resolution with SDL_CreateWindow, then check for what resolution I actually got by calling SDL_GL_GetDrawableSize(WINDOW,&w,&h). This is the only way to make it behave sanely.
Hope this helps someone.


#7

SDL_WINDOW_FULLSCREEN is exclusive fullscreen and will potentially change your monitor’s display mode (as you’ve observed). SDL_WINDOW_FULLSCREEN_DESKTOP won’t, and will use the existing resolution of the display.

Most modern operating systems behave much better with desktop-fullscreen compared to exclusive fullscreen. For example in macOS you can’t switch apps or use exposé in exclusive fullscreen whereas you can in desktop-fullscreen. (So desktop-fullscreen is generally more user friendly.)


#8

Yeah, there is a documentation issue at least; I can reproduce that SDL_CreateWindow is using the width/height when called with SDL_WINDOW_FULLSCREEN when the docs say it shouldn’t use them. It’s extra confusing in a highdpi scenario, because the window width/height passed to SDL_CreateWindow are in points, but it only makes sense to talk about the pixel dimensions of fullscreen modes.

Normally, the way you specify the mode for SDL_WINDOW_FULLSCREEN is by calling SDL_SetWindowDisplayMode. So if you wanted to really get a 2880x1800 pixel fullscreen mode, you’d create a non-fullscreen window with some placeholder size like 640x480 and the SDL_WINDOW_HIDDEN flag, then call SDL_SetWindowDisplayMode to choose a 2880x1800 mode, then finally call SDL_SetWindowFullscreen and SDL_ShowWindow (not sure about the correct order or if it matters.)


#9

Hi Eric and slime.
Thanks for the extra info, it was really helpful for me.
I realise that typically an app should be a “good citizen” and allow switching to other apps. The thing is, I’m writing a clone of Blitz BASIC… games written in this language always took complete control of the hardware so I’m somewhat inclined to reproduce that behaviour.
Eric, thanks so much. I managed to fix (or so I thought) the Mac version of my game, only to find that in Windows 10 (installed on the same Mac with BOOTCAMP) the problem resurfaced (you could only see the upper-left quarter of the game).
I followed the steps you outlined exactly to the letter and now my test/example game looks the same on MacOS and Windows.
Thanks again!