Cocoa: Replace display link with IOKit query
This removes the final dependency on CoreVideo, using a display link to get the refresh rate of monitors where Core Graphics report a refresh rate of zero. Instead we now query the I/O registry directly, similarly to what the display link does at creation. Thanks to @OneSadCookie for pointers to this solution.
This commit is contained in:
parent
c3ca88055f
commit
4ec7daf3e9
@ -275,11 +275,10 @@ if (_GLFW_COCOA)
|
|||||||
list(APPEND glfw_LIBRARIES
|
list(APPEND glfw_LIBRARIES
|
||||||
"-framework Cocoa"
|
"-framework Cocoa"
|
||||||
"-framework IOKit"
|
"-framework IOKit"
|
||||||
"-framework CoreFoundation"
|
"-framework CoreFoundation")
|
||||||
"-framework CoreVideo")
|
|
||||||
|
|
||||||
set(glfw_PKG_DEPS "")
|
set(glfw_PKG_DEPS "")
|
||||||
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
|
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
@ -139,6 +139,7 @@ information on what to include when reporting a bug.
|
|||||||
event (#1490)
|
event (#1490)
|
||||||
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
|
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
|
||||||
window (#1499)
|
window (#1499)
|
||||||
|
- [Cocoa] Removed dependency on the CoreVideo framework
|
||||||
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
||||||
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
||||||
(#1412)
|
(#1412)
|
||||||
|
@ -344,8 +344,8 @@ If you are using the dynamic library version of GLFW, add it to the project
|
|||||||
dependencies.
|
dependencies.
|
||||||
|
|
||||||
If you are using the static library version of GLFW, add it and the Cocoa,
|
If you are using the static library version of GLFW, add it and the Cocoa,
|
||||||
OpenGL, IOKit and CoreVideo frameworks to the project as dependencies. They can
|
OpenGL and IOKit frameworks to the project as dependencies. They can all be
|
||||||
all be found in `/System/Library/Frameworks`.
|
found in `/System/Library/Frameworks`.
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_osx With command-line on macOS
|
@subsection build_link_osx With command-line on macOS
|
||||||
@ -359,7 +359,7 @@ the `-l` and `-framework` switches.
|
|||||||
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
|
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
|
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
||||||
|
@ -52,6 +52,12 @@ add_subdirectory(path/to/glfw)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection corevideo_34 CoreVideo dependency has been removed
|
||||||
|
|
||||||
|
GLFW no longer depends on the CoreVideo framework on macOS and it no longer
|
||||||
|
needs to be specified during compilation or linking.
|
||||||
|
|
||||||
|
|
||||||
@subsection deprecations_34 Deprecations in version 3.4
|
@subsection deprecations_34 Deprecations in version 3.4
|
||||||
|
|
||||||
@subsection removals_34 Removals in 3.4
|
@subsection removals_34 Removals in 3.4
|
||||||
|
@ -234,26 +234,65 @@ static GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a fallback refresh rate for when Core Graphics says it is zero
|
// Returns the display refresh rate queried from the I/O registry
|
||||||
//
|
//
|
||||||
static double getFallbackRefreshRate(_GLFWmonitor* monitor)
|
static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||||
{
|
{
|
||||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
double refreshRate = 60.0;
|
||||||
double refreshRate = CGDisplayModeGetRefreshRate(mode);
|
|
||||||
CGDisplayModeRelease(mode);
|
|
||||||
|
|
||||||
if (refreshRate == 0.0)
|
io_iterator_t it;
|
||||||
|
io_service_t service;
|
||||||
|
|
||||||
|
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||||
|
IOServiceMatching("IOFramebuffer"),
|
||||||
|
&it) != 0)
|
||||||
{
|
{
|
||||||
CVDisplayLinkRef link = NULL;
|
return refreshRate;
|
||||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
|
||||||
|
|
||||||
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
|
|
||||||
if (!(time.flags & kCVTimeIsIndefinite))
|
|
||||||
refreshRate = (int) (time.timeScale / (double) time.timeValue);
|
|
||||||
|
|
||||||
CVDisplayLinkRelease(link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
|
{
|
||||||
|
const CFNumberRef indexRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFramebufferOpenGLIndex"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
if (!indexRef)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
CFNumberGetValue(indexRef, kCFNumberIntType, &index);
|
||||||
|
CFRelease(indexRef);
|
||||||
|
|
||||||
|
if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CFNumberRef clockRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelClock"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
const CFNumberRef countRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelCount"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
if (!clockRef || !countRef)
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint32_t clock = 0, count = 0;
|
||||||
|
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
|
||||||
|
CFNumberGetValue(countRef, kCFNumberIntType, &count);
|
||||||
|
CFRelease(clockRef);
|
||||||
|
CFRelease(countRef);
|
||||||
|
|
||||||
|
if (clock > 0 && count > 0)
|
||||||
|
refreshRate = clock / (double) count;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(it);
|
||||||
return refreshRate;
|
return refreshRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,10 +349,14 @@ void _glfwPollMonitorsNS(void)
|
|||||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
monitor->ns.displayID = displays[i];
|
monitor->ns.displayID = displays[i];
|
||||||
monitor->ns.unitNumber = unitNumber;
|
monitor->ns.unitNumber = unitNumber;
|
||||||
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(monitor);
|
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
|
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
|
||||||
|
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
|
||||||
|
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
|
||||||
|
CGDisplayModeRelease(mode);
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
#include <CoreVideo/CVBase.h>
|
|
||||||
#include <CoreVideo/CVDisplayLink.h>
|
|
||||||
|
|
||||||
// NOTE: All of NSGL was deprecated in the 10.14 SDK
|
// NOTE: All of NSGL was deprecated in the 10.14 SDK
|
||||||
// This disables the pointless warnings for every symbol we use
|
// This disables the pointless warnings for every symbol we use
|
||||||
|
Loading…
Reference in New Issue
Block a user