From c8ba31e8c600161645b46236092bcb7bb97b02dc Mon Sep 17 00:00:00 2001 From: Mousen Date: Wed, 10 Dec 2025 05:11:23 +0500 Subject: [PATCH] Switch frame loop from dispatch timer to CADisplayLink at 30fps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the high-priority dispatch timer with CADisplayLink for frame updates, reducing target framerate from 60 to 30 fps. This simplifies the frame loop implementation while providing better system integration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- screendump/FrameUpdater.m | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/screendump/FrameUpdater.m b/screendump/FrameUpdater.m index b12f40a..c3ff5f6 100644 --- a/screendump/FrameUpdater.m +++ b/screendump/FrameUpdater.m @@ -7,7 +7,6 @@ NSOperationQueue *_q; BOOL _updatingFrames; CADisplayLink *_displayLink; - dispatch_source_t _timer; // Shared from ScreenDumpVNC IOSurfaceRef _screenSurface; @@ -142,11 +141,6 @@ -(void)stopFrameLoop { _updatingFrames = NO; - if (_timer) { - dispatch_source_cancel(_timer); - _timer = nil; - } - if (_displayLink) { dispatch_async(dispatch_get_main_queue(), ^(void){ [_displayLink invalidate]; @@ -159,23 +153,11 @@ [self stopFrameLoop]; _updatingFrames = YES; - // Use high-priority dispatch timer instead of CADisplayLink - // CADisplayLink may be throttled for daemon processes - dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class( - DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0); - dispatch_queue_t timerQueue = dispatch_queue_create("com.mousen.screendump.frametimer", attr); - - _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, timerQueue); - - // 60 FPS = ~16.67ms interval - uint64_t interval = NSEC_PER_SEC / 60; - dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), interval, 0); - - dispatch_source_set_event_handler(_timer, ^{ - [self _updateFrame]; + dispatch_async(dispatch_get_main_queue(), ^{ + _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_updateFrame)]; + _displayLink.preferredFramesPerSecond = 30; + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; }); - - dispatch_resume(_timer); } -(void)dealloc {