Skip to content

Commit 519f3bf

Browse files
committed
Monitor (macOS): test HDR support for external monitors
1 parent 045d705 commit 519f3bf

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/detection/monitor/monitor_apple.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,13 @@
106106
if (IOAVServiceCopyEDID(service, &edid) != KERN_SUCCESS)
107107
continue;
108108

109-
if (CFDataGetLength(edid) < 128)
109+
uint32_t edidLength = (uint32_t) CFDataGetLength(edid);
110+
if (edidLength == 0 || edidLength % 128 != 0)
110111
continue;
111112

112113
uint32_t width, height;
113114
const uint8_t* edidData = CFDataGetBytePtr(edid);
115+
114116
ffEdidGetPhysicalResolution(edidData, &width, &height);
115117
if (width == 0 || height == 0) continue;
116118

@@ -120,7 +122,7 @@
120122
ffStrbufInit(&display->name);
121123
ffEdidGetName(edidData, &display->name);
122124
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
123-
display->hdrCompatible = false;
125+
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength);
124126
}
125127
return NULL;
126128
}

src/util/edidHelper.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,32 @@ void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* h
4949
*width = (((uint32_t) edid[68] & 0xF0) << 4) + edid[66];
5050
*height = (((uint32_t) edid[68] & 0x0F) << 8) + edid[67];
5151
}
52+
53+
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length)
54+
{
55+
if (length <= 128) return false;
56+
for (const uint8_t* cta = &edid[128]; cta < &edid[length]; cta += 128)
57+
{
58+
// https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#CTA_EDID_Timing_Extension_Block
59+
if (cta[0] != 0x02 /* CTA EDID */) continue;
60+
if (cta[1] < 0x03 /* Version 3 */) continue;
61+
const uint8_t offset = cta[2];
62+
if (offset <= 4) continue;
63+
for (uint8_t i = 4; i < offset;)
64+
{
65+
uint8_t blkLen = cta[i] & 0x1f;
66+
if (blkLen > 0)
67+
{
68+
uint8_t blkTag = (cta[i] & 0xe0) >> 5;
69+
if (blkTag == 0x07 /* Extended Block Type Tag */)
70+
{
71+
uint8_t extendedTag = cta[i + 1];
72+
if (extendedTag == 6 /* HDR SMDB */ || extendedTag == 7 /* HDR DMDB */)
73+
return true;
74+
}
75+
}
76+
i += blkLen + 1;
77+
}
78+
}
79+
return false;
80+
}

src/util/edidHelper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
1010
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
1111
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height);
1212
void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height); // in mm
13+
bool ffEdidGetHdrCompatible(const uint8_t edid[128], uint32_t length);
1314

1415
#endif

0 commit comments

Comments
 (0)