cocoa: Update CVDisplayLink timing when screen changes. This handles both the window moving to a new display and changing the current display's refresh rate in System Preferences Reference Issue #4918.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
diff --git a/src/video/cocoa/SDL_cocoaopengl.h b/src/video/cocoa/SDL_cocoaopengl.h
index a483ac0..7b900de 100644
--- a/src/video/cocoa/SDL_cocoaopengl.h
+++ b/src/video/cocoa/SDL_cocoaopengl.h
@@ -53,6 +53,7 @@ struct SDL_GLDriverData
shareContext:(NSOpenGLContext *)share;
- (void)scheduleUpdate;
- (void)updateIfNeeded;
+- (void)movedToNewScreen;
- (void)setWindow:(SDL_Window *)window;
- (SDL_Window*)window;
- (void)explicitUpdate;
diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m
index af17ae2..607f307 100644
--- a/src/video/cocoa/SDL_cocoaopengl.m
+++ b/src/video/cocoa/SDL_cocoaopengl.m
@@ -97,6 +97,13 @@ DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const
return self;
}
+- (void)movedToNewScreen
+{
+ if (self->displayLink) {
+ CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [[self pixelFormat] CGLPixelFormatObj]);
+ }
+}
+
- (void)scheduleUpdate
{
SDL_AtomicAdd(&self->dirty, 1);
@@ -483,6 +490,8 @@ Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
SDL_UnlockMutex(nscontext->swapIntervalMutex);
}
+ /*{ static Uint64 prev = 0; const Uint64 now = SDL_GetTicks64(); const unsigned int diff = (unsigned int) (now - prev); prev = now; printf("GLSWAPBUFFERS TICKS %u\n", diff); }*/
+
/* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
threads try to swap at the same time, so put a mutex around it. */
SDL_LockMutex(videodata.swaplock);
diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h
index cd76b0c..18f7d85 100644
--- a/src/video/cocoa/SDL_cocoawindow.h
+++ b/src/video/cocoa/SDL_cocoawindow.h
@@ -85,6 +85,7 @@ typedef enum
-(void) windowDidResignKey:(NSNotification *) aNotification;
-(void) windowDidChangeBackingProperties:(NSNotification *) aNotification;
-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification;
+-(void) windowDidChangeScreen:(NSNotification *) aNotification;
-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index eea7f98..05cdcbc 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -500,6 +500,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
[center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
[center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window];
+ [center addObserver:self selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification object:window];
[center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
[center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
[center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
@@ -632,6 +633,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
[center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
[center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window];
+ [center removeObserver:self name:NSWindowDidChangeScreenNotification object:window];
[center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
[center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
[center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
@@ -920,6 +922,16 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
}
+- (void)windowDidChangeScreen:(NSNotification *)aNotification
+{
+ /*printf("WINDOWDIDCHANGESCREEN\n");*/
+ if (_data && _data.nscontexts) {
+ for (SDLOpenGLContext *context in _data.nscontexts) {
+ [context movedToNewScreen];
+ }
+ }
+}
+
- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
{
SDL_Window *window = _data.window;