From bd9c0a10e577e7f839aabc27af6e186a9ba0cdaa Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 20 Jul 2016 20:42:30 +0200 Subject: vo_opengl: allow backends to provide callbacks for custom event loops Until now, this has been either handled over vo.event_fd (which should go away), or by putting event handling on a separate thread. The backends which do the latter do it for a reason and won't need this, but X11 and Wayland will, in order to get rid of event_fd. --- video/out/opengl/context.h | 5 +++++ video/out/vo.c | 30 +++++++++++++++++++++--------- video/out/vo.h | 3 ++- video/out/vo_drm.c | 5 +---- video/out/vo_opengl.c | 21 +++++++++++++++++++++ video/out/vo_sdl.c | 4 +--- 6 files changed, 51 insertions(+), 17 deletions(-) (limited to 'video') diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h index df842bc8a1..a546e00be0 100644 --- a/video/out/opengl/context.h +++ b/video/out/opengl/context.h @@ -63,6 +63,11 @@ struct mpgl_driver { // This behaves exactly like vo_driver.control(). int (*control)(struct MPGLContext *ctx, int *events, int request, void *arg); + // These behave exactly like vo_driver.wakeup/wait_events. They are + // optional. + void (*wakeup)(struct MPGLContext *ctx); + void (*wait_events)(struct MPGLContext *ctx, int64_t until_time_us); + // Destroy the GL context and possibly the underlying VO backend. void (*uninit)(struct MPGLContext *ctx); }; diff --git a/video/out/vo.c b/video/out/vo.c index 07476ad7c3..97df1c1445 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -610,27 +610,39 @@ static void wait_event_fd(struct vo *vo, int64_t until_time){} static void wakeup_event_fd(struct vo *vo){} #endif +// VOs which have no special requirements on UI event loops etc. can set the +// vo_driver.wait_events callback to this (and leave vo_driver.wakeup unset). +// This function must not be used or called for other purposes. +void vo_wait_default(struct vo *vo, int64_t until_time) +{ + struct vo_internal *in = vo->in; + + pthread_mutex_lock(&in->lock); + if (!in->need_wakeup) { + struct timespec ts = mp_time_us_to_timespec(until_time); + pthread_cond_timedwait(&in->wakeup, &in->lock, &ts); + } + pthread_mutex_unlock(&in->lock); +} + // Called unlocked. static void wait_vo(struct vo *vo, int64_t until_time) { struct vo_internal *in = vo->in; if (vo->event_fd >= 0) { + // old/deprecated code path wait_event_fd(vo, until_time); pthread_mutex_lock(&in->lock); in->need_wakeup = false; pthread_mutex_unlock(&in->lock); - } else if (vo->driver->wait_events) { - vo->driver->wait_events(vo, until_time); - pthread_mutex_lock(&in->lock); - in->need_wakeup = false; - pthread_mutex_unlock(&in->lock); } else { - pthread_mutex_lock(&in->lock); - if (!in->need_wakeup) { - struct timespec ts = mp_time_us_to_timespec(until_time); - pthread_cond_timedwait(&in->wakeup, &in->lock, &ts); + if (vo->driver->wait_events) { + vo->driver->wait_events(vo, until_time); + } else { + vo_wait_default(vo, until_time); } + pthread_mutex_lock(&in->lock); in->need_wakeup = false; pthread_mutex_unlock(&in->lock); } diff --git a/video/out/vo.h b/video/out/vo.h index 9c29d5f2cc..96f926be0a 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -282,7 +282,7 @@ struct vo_driver { * immediately. */ void (*wakeup)(struct vo *vo); - int (*wait_events)(struct vo *vo, int64_t until_time_us); + void (*wait_events)(struct vo *vo, int64_t until_time_us); /* * Closes driver. Should restore the original state of the system. @@ -370,6 +370,7 @@ double vo_get_display_fps(struct vo *vo); double vo_get_delay(struct vo *vo); void vo_wakeup(struct vo *vo); +void vo_wait_default(struct vo *vo, int64_t until_time); struct mp_keymap { int from; diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c index 5a7c613cad..f03f50358d 100644 --- a/video/out/vo_drm.c +++ b/video/out/vo_drm.c @@ -253,9 +253,7 @@ static void acquire_vt(void *data) crtc_setup(vo); } - - -static int wait_events(struct vo *vo, int64_t until_time_us) +static void wait_events(struct vo *vo, int64_t until_time_us) { struct priv *p = vo->priv; if (p->vt_switcher_active) { @@ -263,7 +261,6 @@ static int wait_events(struct vo *vo, int64_t until_time_us) int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); vt_switcher_poll(&p->vt_switcher, timeout_ms); } - return 0; } static void wakeup(struct vo *vo) diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 095308f9b5..8c8da4affd 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -357,6 +357,23 @@ static int control(struct vo *vo, uint32_t request, void *data) return r; } +static void wakeup(struct vo *vo) +{ + struct gl_priv *p = vo->priv; + if (p->glctx->driver->wakeup) + p->glctx->driver->wakeup(p->glctx); +} + +static void wait_events(struct vo *vo, int64_t until_time_us) +{ + struct gl_priv *p = vo->priv; + if (p->glctx->driver->wait_events) { + p->glctx->driver->wait_events(p->glctx, until_time_us); + } else { + vo_wait_default(vo, until_time_us); + } +} + static void uninit(struct vo *vo) { struct gl_priv *p = vo->priv; @@ -466,6 +483,8 @@ const struct vo_driver video_out_opengl = { .control = control, .draw_frame = draw_frame, .flip_page = flip_page, + .wait_events = wait_events, + .wakeup = wakeup, .uninit = uninit, .priv_size = sizeof(struct gl_priv), .options = options, @@ -481,6 +500,8 @@ const struct vo_driver video_out_opengl_hq = { .control = control, .draw_frame = draw_frame, .flip_page = flip_page, + .wait_events = wait_events, + .wakeup = wakeup, .uninit = uninit, .priv_size = sizeof(struct gl_priv), .priv_defaults = &(const struct gl_priv){ diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index dd18f6e9c4..d33ace147a 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -533,7 +533,7 @@ static void wakeup(struct vo *vo) SDL_PushEvent(&event); } -static int wait_events(struct vo *vo, int64_t until_time_us) +static void wait_events(struct vo *vo, int64_t until_time_us) { int64_t wait_us = until_time_us - mp_time_us(); int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); @@ -619,8 +619,6 @@ static int wait_events(struct vo *vo, int64_t until_time_us) break; } } - - return 0; } static void uninit(struct vo *vo) -- cgit v1.2.3