Monitor (macOS): test HDR support for external monitors

This commit is contained in:
李通洲 2023-08-11 22:04:26 +08:00
parent 045d7052d1
commit 519f3bfd50
No known key found for this signature in database
GPG Key ID: 269AD4F5325A22A3
3 changed files with 34 additions and 2 deletions

View File

@ -106,11 +106,13 @@ static const char* detectWithDdcci(FFlist* results)
if (IOAVServiceCopyEDID(service, &edid) != KERN_SUCCESS)
continue;
if (CFDataGetLength(edid) < 128)
uint32_t edidLength = (uint32_t) CFDataGetLength(edid);
if (edidLength == 0 || edidLength % 128 != 0)
continue;
uint32_t width, height;
const uint8_t* edidData = CFDataGetBytePtr(edid);
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width == 0 || height == 0) continue;
@ -120,7 +122,7 @@ static const char* detectWithDdcci(FFlist* results)
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
display->hdrCompatible = false;
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength);
}
return NULL;
}

View File

@ -49,3 +49,32 @@ void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* h
*width = (((uint32_t) edid[68] & 0xF0) << 4) + edid[66];
*height = (((uint32_t) edid[68] & 0x0F) << 8) + edid[67];
}
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length)
{
if (length <= 128) return false;
for (const uint8_t* cta = &edid[128]; cta < &edid[length]; cta += 128)
{
// https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#CTA_EDID_Timing_Extension_Block
if (cta[0] != 0x02 /* CTA EDID */) continue;
if (cta[1] < 0x03 /* Version 3 */) continue;
const uint8_t offset = cta[2];
if (offset <= 4) continue;
for (uint8_t i = 4; i < offset;)
{
uint8_t blkLen = cta[i] & 0x1f;
if (blkLen > 0)
{
uint8_t blkTag = (cta[i] & 0xe0) >> 5;
if (blkTag == 0x07 /* Extended Block Type Tag */)
{
uint8_t extendedTag = cta[i + 1];
if (extendedTag == 6 /* HDR SMDB */ || extendedTag == 7 /* HDR DMDB */)
return true;
}
}
i += blkLen + 1;
}
}
return false;
}

View File

@ -10,5 +10,6 @@ void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height);
void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height); // in mm
bool ffEdidGetHdrCompatible(const uint8_t edid[128], uint32_t length);
#endif