Unverified Commit 5058bbc1 authored by Elijah Semyonov's avatar Elijah Semyonov Committed by GitHub

Turn off vsync throttling when macOS hardware sleeps (#927)

Speculative fix for [a freeze
issue](https://youtrack.jetbrains.com/issue/COMPOSE-1441/Desktop-skiko-freeze-after-sleep-on-Mac-with-multiple-external-monitors).
parent d599c03b
......@@ -24,6 +24,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
NSScreen *_displayLinkScreen;
CVDisplayLinkRef _displayLink;
NSConditionLock *_vsyncConditionLock;
BOOL _isSleeping;
}
- (instancetype)init {
......@@ -33,11 +34,34 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
_displayLinkScreen = nil;
_displayLink = nil;
_vsyncConditionLock = [[NSConditionLock alloc] initWithCondition: 1];
_isSleeping = NO;
NSNotificationCenter *notificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
[notificationCenter addObserver:self
selector:@selector(systemWillSleep:)
name:NSWorkspaceWillSleepNotification
object:nil];
[notificationCenter addObserver:self
selector:@selector(systemDidWake:)
name:NSWorkspaceDidWakeNotification
object:nil];
}
return self;
}
- (void)systemWillSleep:(NSNotification *)notification {
_isSleeping = YES;
[self invalidateDisplayLink];
[self onVSync];
}
- (void)systemDidWake:(NSNotification *)notification {
_isSleeping = NO;
}
- (void)onVSync {
/// Lock condition lock and immediately unlock setting condition variable to 1 (can render now)
[_vsyncConditionLock lock];
......@@ -45,7 +69,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
}
- (void)waitVSync {
/// If display link construction was corrupted, don't perform any waiting
/// If display link is not constructed (due to failure or explicit opt-out), don't perform any waiting
if (!_displayLink) {
return;
}
......@@ -65,6 +89,11 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
}
- (void)setupDisplayLinkForWindow:(NSWindow *)window {
if (_isSleeping) {
/// System is sleeping, don't setup display link
return;
}
NSScreen *screen = window.screen;
if (!screen) {
......@@ -136,6 +165,8 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_DisplayLinkThrottler_wa
DisplayLinkThrottler *throttler = (__bridge DisplayLinkThrottler *) (void *) throttlerPtr;
NSWindow *window = (__bridge NSWindow *) (void *) windowPtr;
// CVDisplayLink is conditionally set up on each draw request to track window.screen change to match throttling
// with the refresh rate of the actual screen the window is shown on.
[throttler setupDisplayLinkForWindow:window];
[throttler waitVSync];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment