mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 01:15:35 +00:00
app/internal/window: [macOS,iOS] reduce display link starting and stopping
Recent changes to the macOS threading exposed a problem where a window's display link may fail to start after being started and stopped in rapid succession. Introduce a displayLink type that waits a while after the last stop request before stopping its display link. That seems to be the way other projects are using display links. As a bonus, the new implementation avoids the potentially expensive overhead of frequent starting and stopping the underlying OS thread. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -19,39 +19,14 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
||||
gio_onMouse((__bridge CFTypeRef)view, typ, [NSEvent pressedMouseButtons], p.x, p.y, dx, dy, [event timestamp], [event modifierFlags]);
|
||||
}
|
||||
|
||||
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
|
||||
CFTypeRef view = (CFTypeRef *)displayLinkContext;
|
||||
gio_onFrameCallback(view);
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
@interface GioView : NSOpenGLView
|
||||
@end
|
||||
|
||||
@implementation GioView {
|
||||
CVDisplayLinkRef displayLink;
|
||||
}
|
||||
- (instancetype)initWithFrame:(NSRect)frameRect
|
||||
pixelFormat:(NSOpenGLPixelFormat *)format {
|
||||
self = [super initWithFrame:frameRect pixelFormat:format];
|
||||
if (self) {
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
|
||||
CVDisplayLinkSetOutputCallback(displayLink, displayLinkCallback, (__bridge void*)self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)dealloc {
|
||||
CVDisplayLinkRelease(displayLink);
|
||||
}
|
||||
- (void)setAnimating:(BOOL)anim {
|
||||
if (anim) {
|
||||
CVDisplayLinkStart(displayLink);
|
||||
} else {
|
||||
CVDisplayLinkStop(displayLink);
|
||||
}
|
||||
}
|
||||
- (void)updateDisplay:(CGDirectDisplayID)dispID {
|
||||
CVDisplayLinkSetCurrentCGDisplay(displayLink, dispID);
|
||||
return [super initWithFrame:frameRect pixelFormat:format];
|
||||
}
|
||||
- (void)prepareOpenGL {
|
||||
[super prepareOpenGL];
|
||||
@@ -139,16 +114,6 @@ CFTypeRef gio_createGLView(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void gio_updateDisplayLink(CFTypeRef viewRef, CGDirectDisplayID dispID) {
|
||||
GioView *view = (__bridge GioView *)viewRef;
|
||||
[view updateDisplay:dispID];
|
||||
}
|
||||
|
||||
void gio_setAnimating(CFTypeRef viewRef, BOOL anim) {
|
||||
GioView *view = (__bridge GioView *)viewRef;
|
||||
[view setAnimating:anim];
|
||||
}
|
||||
|
||||
CFTypeRef gio_contextForView(CFTypeRef viewRef) {
|
||||
NSOpenGLView *view = (__bridge NSOpenGLView *)viewRef;
|
||||
return (__bridge CFTypeRef)view.openGLContext;
|
||||
|
||||
Reference in New Issue
Block a user