vlc | branch: master | Alexandre Janniaux <aja...@videolabs.io> | Thu Feb 18 15:01:12 2021 +0100| [b4c7561cadc93293fde611363379f847d3ad07a7] | committer: Alexandre Janniaux
VLCOpenGLES2VideoView: use dedicated CFRunLoop mode The vlc_runloop mode is designed to be executed even when an event is being reported by the vout_window used, ie when there is a call to CFRunLoopInMode(CFRunLoopGetMain(), CFSTR("vlc_runloop"), ..). By adding the default mode too, it ensures it would run in the normal CFRunLoop too. Async tasks can still be dispatched without the "vlc_runloop" mode but every sync task in the display must be done under this mode to prevent deadlock from happening between the main thread and the vout_thread. Fixes #23571 > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b4c7561cadc93293fde611363379f847d3ad07a7 --- modules/video_output/apple/VLCOpenGLES2VideoView.m | 37 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/modules/video_output/apple/VLCOpenGLES2VideoView.m b/modules/video_output/apple/VLCOpenGLES2VideoView.m index fb452bba81..fc6ba8e274 100644 --- a/modules/video_output/apple/VLCOpenGLES2VideoView.m +++ b/modules/video_output/apple/VLCOpenGLES2VideoView.m @@ -79,6 +79,35 @@ - (void)detachFromWindow; @end +static void vlc_dispatch_sync(void (^block_function)()) +{ + CFRunLoopRef runloop = CFRunLoopGetMain(); + + __block vlc_sem_t performed; + vlc_sem_init(&performed, 0); + + CFStringRef modes_cfstrings[] = { + kCFRunLoopDefaultMode, + CFSTR("org.videolan.vlccore.window"), + }; + + CFArrayRef modes = CFArrayCreate(NULL, (const void **)modes_cfstrings, + ARRAY_SIZE(modes_cfstrings), + &kCFTypeArrayCallBacks); + + /* NOTE: we're using CFRunLoopPerformBlock with a custom mode tag + * to avoid deadlocks between the window module (main thread) and the + * display module, which would happen when using dispatch_sycn here. */ + CFRunLoopPerformBlock(runloop, modes, ^{ + (block_function)(); + vlc_sem_post(&performed); + }); + CFRunLoopWakeUp(runloop); + + vlc_sem_wait(&performed); + CFRelease(modes); +} + /***************************************************************************** * vlc_gl_t callbacks *****************************************************************************/ @@ -466,9 +495,11 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height) if (wnd->type != VOUT_WINDOW_TYPE_NSOBJECT) return VLC_EGENERIC; - @autoreleasepool { - /* setup the actual OpenGL ES view */ - dispatch_sync(dispatch_get_main_queue(), ^{ + @autoreleasepool { + /* NOTE: we're using CFRunLoopPerformBlock with the "vlc_runloop" tag + * to avoid deadlocks between the window module (main thread) and the + * display module, which would happen when using dispatch_sycn here. */ + vlc_dispatch_sync(^{ gl->sys = (__bridge_retained void*)[[VLCOpenGLES2VideoView alloc] initWithFrame:CGRectMake(0.,0.,width,height) gl:gl]; }); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits