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 ...@@ -24,6 +24,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
NSScreen *_displayLinkScreen; NSScreen *_displayLinkScreen;
CVDisplayLinkRef _displayLink; CVDisplayLinkRef _displayLink;
NSConditionLock *_vsyncConditionLock; NSConditionLock *_vsyncConditionLock;
BOOL _isSleeping;
} }
- (instancetype)init { - (instancetype)init {
...@@ -33,11 +34,34 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt ...@@ -33,11 +34,34 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
_displayLinkScreen = nil; _displayLinkScreen = nil;
_displayLink = nil; _displayLink = nil;
_vsyncConditionLock = [[NSConditionLock alloc] initWithCondition: 1]; _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; return self;
} }
- (void)systemWillSleep:(NSNotification *)notification {
_isSleeping = YES;
[self invalidateDisplayLink];
[self onVSync];
}
- (void)systemDidWake:(NSNotification *)notification {
_isSleeping = NO;
}
- (void)onVSync { - (void)onVSync {
/// Lock condition lock and immediately unlock setting condition variable to 1 (can render now) /// Lock condition lock and immediately unlock setting condition variable to 1 (can render now)
[_vsyncConditionLock lock]; [_vsyncConditionLock lock];
...@@ -45,7 +69,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt ...@@ -45,7 +69,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
} }
- (void)waitVSync { - (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) { if (!_displayLink) {
return; return;
} }
...@@ -65,6 +89,11 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt ...@@ -65,6 +89,11 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
} }
- (void)setupDisplayLinkForWindow:(NSWindow *)window { - (void)setupDisplayLinkForWindow:(NSWindow *)window {
if (_isSleeping) {
/// System is sleeping, don't setup display link
return;
}
NSScreen *screen = window.screen; NSScreen *screen = window.screen;
if (!screen) { if (!screen) {
...@@ -136,6 +165,8 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_DisplayLinkThrottler_wa ...@@ -136,6 +165,8 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_DisplayLinkThrottler_wa
DisplayLinkThrottler *throttler = (__bridge DisplayLinkThrottler *) (void *) throttlerPtr; DisplayLinkThrottler *throttler = (__bridge DisplayLinkThrottler *) (void *) throttlerPtr;
NSWindow *window = (__bridge NSWindow *) (void *) windowPtr; 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 setupDisplayLinkForWindow:window];
[throttler waitVSync]; [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