From ebe30394f2dd2062c49411b9cecf9e9127adfb61 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 24 Jan 2023 11:21:08 +0800 Subject: [PATCH] Display (macOS): fix zero refresh rate on some monitors --- CHANGELOG.md | 1 + CMakeLists.txt | 1 + .../displayserver/displayserver_apple.c | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e4771a8c..05015dd38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Bugfixes: * Fix builds on s390x (@jonathanspw, #402) +* Fix zero refresh rate on some monitors (macOS) # 1.9.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index a64416d1b..072394f28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -666,6 +666,7 @@ if(APPLE) PRIVATE "-framework OpenCL" PRIVATE "-framework Cocoa" PRIVATE "-framework CoreWLAN" + PRIVATE "-framework CoreVideo" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks" ) diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 065e218b7..bbc03aedf 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -6,6 +6,7 @@ #include #include #include +#include static void detectDisplays(FFDisplayServerResult* ds) { @@ -20,10 +21,25 @@ static void detectDisplays(FFDisplayServerResult* ds) CGDisplayModeRef mode = CGDisplayCopyDisplayMode(screen); if(mode) { + //https://github.com/glfw/glfw/commit/aab08712dd8142b642e2042e7b7ba563acd07a45 + double refreshRate = CGDisplayModeGetRefreshRate(mode); + + if (refreshRate == 0) + { + CVDisplayLinkRef link; + if(CVDisplayLinkCreateWithCGDisplay(screen, &link) == kCVReturnSuccess) + { + const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); + if (!(time.flags & kCVTimeIsIndefinite)) + refreshRate = time.timeScale / (double) time.timeValue + 0.5; //59.97... + CVDisplayLinkRelease(link); + } + } + ffdsAppendDisplay(ds, (uint32_t)CGDisplayModeGetPixelWidth(mode), (uint32_t)CGDisplayModeGetPixelHeight(mode), - (uint32_t)CGDisplayModeGetRefreshRate(mode), + (uint32_t)refreshRate, (uint32_t)CGDisplayModeGetWidth(mode), (uint32_t)CGDisplayModeGetHeight(mode) );