[vlc-devel] [PATCH 1/3] VLCVidewUIView: report event in another thread
Alexandre Janniaux
ajanni at videolabs.io
Thu Feb 18 18:34:52 UTC 2021
A few updates:
- we should probably use a better name for the mode, like
org.videolan.vlccore.window
- maybe have the name somewhere global? it's a bit annoying
to expose it though. Maybe behind a private API header for
queuing blocks?
- use another thread provider than dispatch_get_global_queue?
Regards,
--
Alexandre Janniaux
Videolabs
On Thu, Feb 18, 2021 at 04:23:54PM +0100, Alexandre Janniaux wrote:
> Report events from a different thread than the main thread, and continue
> to execute the main CFRunLoop, but filter the events to only executes
> the ones queued by potential display, ie. those tagged with the mode
> "vlc_runloop".
>
> 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"), ..).
>
> Clients should ensure they also tag their blocks with the default mode
> too. Otherwise, they are likely to never be executed.
>
> Async tasks can still be dispatched without the "vlc_runloop" mode but
> every sync tasks in the display must be done under this mode to prevent
> deadlock from happening between the main thread and the vout_thread,
> typically with the following code:
>
> /* The main loop to run the block into */
> CFRunLoopRef runloop = CFRunLoopGetMain();
>
> /* The modes to execute the block in */
> CFStringRef modes_cfstrings[] = { kCFRunLoopDefaultMode, CFSTR("vlc_runloop") };
> CFArrayRef modes = CFArrayCreate(NULL, (const void **)modes_cfstrings,
> ARRAY_SIZE(modes_cfstrings), &kCFTypeArrayCallBacks);
>
> CFRunLoopPerformBlock(runloop, modes, ^{
> /* The block content to execute */
> });
>
> /* Don't forget to signal the runloop
> CFRunLoopWakeUp(runloop);
> CFRelease(modes);
>
> To achieve a blocking/sync behaviour, clients can share a binary
> semaphore between the block and the outside of the block. When using a
> vlc_sem_t object, it must be qualified with __block to be modified
> inside of the block.
>
> Refs #23571
> ---
> modules/video_output/apple/VLCVideoUIView.m | 46 ++++++++++++++++-----
> 1 file changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/modules/video_output/apple/VLCVideoUIView.m b/modules/video_output/apple/VLCVideoUIView.m
> index 3a4c749816..69993013b3 100644
> --- a/modules/video_output/apple/VLCVideoUIView.m
> +++ b/modules/video_output/apple/VLCVideoUIView.m
> @@ -161,6 +161,20 @@
> }
> }
>
> +- (void)reportEvent:(void(^)())eventBlock
> +{
> + CFStringRef mode = CFSTR("vlc_runloop");
> + CFRunLoopRef runloop = CFRunLoopGetCurrent();
> + CFRunLoopPerformBlock(runloop, mode, ^{
> + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
> + (eventBlock)();
> + CFRunLoopStop(runloop);
> + });
> + });
> + CFRunLoopWakeUp(runloop);
> + CFRunLoopRunInMode(mode, 0, NO);
> +}
> +
> - (void)detachFromParent
> {
> /* We need to lock because we consider that _wnd might be destroyed
> @@ -263,11 +277,16 @@
> /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
> vlc_mutex_lock(&_mutex);
> if (_wnd == NULL)
> - goto end;
> - vout_window_ReportSize(_wnd,
> - viewSize.width * scaleFactor,
> - viewSize.height * scaleFactor);
> -end:
> + {
> + vlc_mutex_unlock(&_mutex);
> + return;
> + }
> +
> + [self reportEvent:^{
> + vout_window_ReportSize(_wnd,
> + viewSize.width * scaleFactor,
> + viewSize.height * scaleFactor);
> + }];
> vlc_mutex_unlock(&_mutex);
> }
>
> @@ -280,12 +299,17 @@ end:
> /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
> vlc_mutex_lock(&_mutex);
> if (_wnd == NULL)
> - goto end;
> - vout_window_ReportMouseMoved(_wnd,
> - (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor);
> - vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
> - vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
> -end:
> + {
> + vlc_mutex_unlock(&_mutex);
> + return;
> + }
> +
> + [self reportEvent:^{
> + vout_window_ReportMouseMoved(_wnd,
> + (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor);
> + vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
> + vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
> + }];
> vlc_mutex_unlock(&_mutex);
> }
>
> --
> 2.30.1
>
More information about the vlc-devel
mailing list