Search code examples
macoscocoaretinahidpi

HiDPI / backingScaleFactor on MacOS, how to get actual value?


I'm trying to get the display scaling setting for the current screen so that I can correctly scale inside my OpenGL and/or Vulkan window to match the setting that the OS has. The documentation says to use

float dpi = [window backingScaleFactor];

However this will return 1.0f for no scaling at all, and 2.0f for some scaling.

float dpi = [[window screen] backingScaleFactor];

does the same.

NSRect resolution = [[window screen] frame];

will give you the virtual resolution of the current screen. In System Preferences -> Display -> Scaled, this is the "Looks like" value. For a 3840x2160 screen I have, the possible values are 1920x1080, 2560x1440, 3008x1692, 3360x1890, 3830x2160, depending on the Scaled setting you have chosen. On my MBP's built in screen, which has a native resolution of 2880x1440, the "Looks Like" values can be 1024x640, 1280x800, 1440x900, 1680x1050, 1920x1200. the docs say to use

NSRect test = {0, 0, 1000, 1000};
NSRect dpi = [NSView convertRectToBacking:test];

However this just multiplies the supplied NSRect by the backingScaleFactor.

This is someone trying to get the real resolution of the screen.

So, I want either the real backingScaleFactor, or the native screen resolution for a given NSScreen. Any ideas?


Solution

  • The -backingScaleFactor is giving you the real backing scale factor. The backing store is not the same size as the physical pixel dimensions. Your app renders to the backing store and that is displayed to screen, but that often involves another scaling operation. The right thing for an OpenGL or Vulkan app to do is to render to the backing store resolution, not the physical pixel resolution.