There are various bad options.
First, if you log a display mode (i.e. cast to id
and pass to NSLog(@"%@", ...)
), you'll find that the real pixel encoding is in there. That's interesting, but you really don't want to parse that description.
If you pass (__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }
as the options parameter to CGDisplayCopyAllDisplayModes()
, you'll find that you get a bunch of additional display modes. This key is documented in the headers but not the reference documentation. For a Retina display, some of the extra modes are the 2x-scaled counterparts of unscaled display modes. Others are the 24-bit counterparts of the 30-bit-masquerading-as-24-bit modes. These are identical in every way you can query via the API, but the logging shows the difference. (By the way, attempting to switch to one of those modes will fail.)
I think, but you'd have to verify, that you don't get these pairs of seemingly-identical modes except for a 30-bit-color-capable display.
You may be able to get the information from IOKit. You'd have to use the deprecated function CGDisplayIOServicePort()
to get the service port of the IOFramebuffer
object representing the GPU-display pair. You could then use IORegistryEntrySearchCFProperty()
to search up the containment hierarchy in the Service plane to find an object which has a property like "display-bpc" or "display-pixel-component-bits" and get its value. At least, there's such an object and properties on a couple of systems I'm able to test, although they both use AMD GPUs and the property is on an AMD-specific object, so it may not be reliable.
Finally, you can launch a subprocess to run system_profiler -xml SPDisplaysDataType
and use the property-list-serialization API to build a property list object from the resulting XML. Then, you can find the information in there. You'd find the relevant display by matching _spdisplays_display-vendor-id
with CGDisplayVendorNumber()
, _spdisplays_display-product-id
with CGDisplayModelNumber()
, and _spdisplays_display-serial-number
with CGDisplaySerialNumber()
. Then, the depth is under the key spdisplays_depth
, where a value of CGSThirtyBitColor
means 30-bit color.
You should also file a bug report with Apple requesting a sane way to do this.