Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[macOS] Remove CVDisplayLink v-sync hack. #33783

Merged
merged 1 commit into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions platform/osx/os_osx.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,6 @@ class OS_OSX : public OS_Unix {
NSOpenGLContext *context;

bool layered_window;
bool waiting_for_vsync;
NSCondition *vsync_condition;
CVDisplayLinkRef displayLink;

CursorShape cursor_shape;
NSCursor *cursors[CURSOR_MAX];
Expand Down
54 changes: 2 additions & 52 deletions platform/osx/os_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,6 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
return Vector2(mouse_x, mouse_y);
}

// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before
// a screen update is required. We can use it to work around the broken vsync.
static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
OS_OSX *os = (OS_OSX *)displayLinkContext;

// Set flag so we know we can output our next frame and signal our conditional lock
// if we're not doing vsync this will be ignored
[os->vsync_condition lock];
os->waiting_for_vsync = false;
[os->vsync_condition signal];
[os->vsync_condition unlock];

return kCVReturnSuccess;
}

@interface GodotApplication : NSApplication
@end

Expand Down Expand Up @@ -1581,15 +1566,6 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay

[context makeCurrentContext];

// setup our display link, this will inform us when a refresh is needed
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this);
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj);
CVDisplayLinkStart(displayLink);

// initialise a conditional lock object
vsync_condition = [[NSCondition alloc] init];

set_use_vsync(p_desired.use_vsync);

[NSApp activateIgnoringOtherApps:YES];
Expand Down Expand Up @@ -1682,11 +1658,6 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay
midi_driver.close();
#endif

if (displayLink) {
CVDisplayLinkRelease(displayLink);
}
[vsync_condition release];

CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);

Expand Down Expand Up @@ -2258,18 +2229,6 @@ virtual void log_error(const char *p_function, const char *p_file, int p_line, c
}

void OS_OSX::swap_buffers() {
if (is_vsync_enabled()) {
// Wait until our DisplayLink callback unsets our flag...
[vsync_condition lock];
while (waiting_for_vsync)
[vsync_condition wait];

// Make sure we wait again next frame around
waiting_for_vsync = true;

[vsync_condition unlock];
}

[context flushBuffer];
}

Expand Down Expand Up @@ -3009,20 +2968,11 @@ static int get_screen_index(NSScreen *screen) {
}

void OS_OSX::_set_use_vsync(bool p_enable) {
// CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing
// it as OpenGL is now deprecated and Metal solves this differently.
// Following SDLs example we're working around this using DisplayLink
// When vsync is enabled we set a flag "waiting_for_vsync" to true.
// This flag is set to false when DisplayLink informs us our display is about to refresh.

/* CGLContextObj ctx = CGLGetCurrentContext();
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_enable ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
}*/

///TODO Maybe pause/unpause display link?
waiting_for_vsync = p_enable;
}
}

OS_OSX *OS_OSX::singleton = NULL;
Expand Down