How to resolve CGDirectDisplayID changing issues on newer multi-GPU Apple laptops in Core Foundation/IO Kit?

后端 未结 3 1363
再見小時候
再見小時候 2021-02-04 10:14

In Mac OS X, every display gets a unique CGDirectDisplayID number assigned to it. You can use CGGetActiveDisplayList() or [NSScreen screens]

3条回答
  •  逝去的感伤
    2021-02-04 11:04

    I have found no conceputally better way than what you list as "Tried". But I found a solution for the ambiguity issue of comparing only vendor id and product id.

    oldInfoDict and newInfoDict in your code contain an additional entry for key kIODisplayEDIDKey (defined in IOGraphicsTypes.h) which contains the EDID of each connected display. My observations show that this data as a whole stays persistent between GPU switches. For example:

        CGDirectDisplayID displayId = [[[screen deviceDescription] valueForKey:@"NSScreenNumber"] unsignedIntValue];
        io_service_t displayPort = CGDisplayIOServicePort(displayId);
    
        if (displayPort == MACH_PORT_NULL)
            return nil;  // No physical device to get a name from.
    
        CFDictionaryRef infoDict = IODisplayCreateInfoDictionary(displayPort, kIODisplayOnlyPreferredName);
    
        NSData *displayEdid = (NSData *)CFDictionaryGetValue(infoDict, CFSTR(kIODisplayEDIDKey));
        NSLog(@"EDID: %@", displayEdid);
    
        CFRelease(infoDict);
    

    Looking at the data description of EDID in Wikipedia, this blob already contains manufacturer, product id and serial. So it's enough to compare displays by using the EDID data (or for example a hash of it if you only want to compare a shorter number).

提交回复
热议问题