写给开发者

一个 Mac 应用要跟 DDC/CI 说话,得做对什么

DDC/CI 名声不好,说它不可靠。其中一部分是硬件的问题, 另一部分是——把一根两线总线当成函数调用时发生的事。

地址,以及为什么 EDID 只能读浅层

DDC/CI 在 I2C 芯片 0x37、子地址 0x51。 EDID 在 0x50 应答。EDID 的偏移寄存器只有一个字节, 所以只有基块和第一个扩展块够得着——更深的必须拒绝,而不是猜。

显示器需要「一拍」

显示器需要一点时间才能把回复组好。发完请求立刻读回答案, 在相当多的面板上什么也拿不到。

一个请求,不是两个

写入和读取共用一个请求,这样驱动才能保持总线时序。 把它们拆成两个事务,代码看起来更整洁,真机上表现更糟。

别在一块不理你的面板上花掉十次超时

把每一个已知的 VCP 功能码都探一遍,听起来很周全。 但它也意味着:一块完全不支持 DDC/CI 的面板,要先花掉十次超时, 才能得到「读一次亮度」立刻就能告诉你的结论。用亮度做探路器。

绝不要硬链接一个你的 Mac 可能没有的符号

Intel 那条路需要一个 IOKit 伞形头文件并不导出的用户态 I2C API。 直接引用那个符号,会让 App 在 dyld 里就失败—— 在任何缺这个符号的 Mac 上,它根本起不来。 用 dlsym 解析它,就把这件事变成了优雅降级到「没有 DDC」, 而不是在第一个窗口出现之前崩溃。

两条总线,一个接口

Intel Mac 通过 IOFramebuffer 的 I2C 接口走到 DDC;Apple Silicon 走 AV service。 Intel 路径上的请求是同步的,所以不需要加锁——但上层代码不能假设这一点永远成立。

诚实的边界

相关