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.
This commit is contained in:
wm4 2016-07-20 20:42:30 +02:00
parent e11a20a812
commit bd9c0a10e5
6 changed files with 51 additions and 17 deletions

View File

@ -63,6 +63,11 @@ struct mpgl_driver {
// This behaves exactly like vo_driver.control(). // This behaves exactly like vo_driver.control().
int (*control)(struct MPGLContext *ctx, int *events, int request, void *arg); 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. // Destroy the GL context and possibly the underlying VO backend.
void (*uninit)(struct MPGLContext *ctx); void (*uninit)(struct MPGLContext *ctx);
}; };

View File

@ -610,27 +610,39 @@ static void wait_event_fd(struct vo *vo, int64_t until_time){}
static void wakeup_event_fd(struct vo *vo){} static void wakeup_event_fd(struct vo *vo){}
#endif #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. // Called unlocked.
static void wait_vo(struct vo *vo, int64_t until_time) static void wait_vo(struct vo *vo, int64_t until_time)
{ {
struct vo_internal *in = vo->in; struct vo_internal *in = vo->in;
if (vo->event_fd >= 0) { if (vo->event_fd >= 0) {
// old/deprecated code path
wait_event_fd(vo, until_time); wait_event_fd(vo, until_time);
pthread_mutex_lock(&in->lock); pthread_mutex_lock(&in->lock);
in->need_wakeup = false; in->need_wakeup = false;
pthread_mutex_unlock(&in->lock); 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 { } else {
pthread_mutex_lock(&in->lock); if (vo->driver->wait_events) {
if (!in->need_wakeup) { vo->driver->wait_events(vo, until_time);
struct timespec ts = mp_time_us_to_timespec(until_time); } else {
pthread_cond_timedwait(&in->wakeup, &in->lock, &ts); vo_wait_default(vo, until_time);
} }
pthread_mutex_lock(&in->lock);
in->need_wakeup = false; in->need_wakeup = false;
pthread_mutex_unlock(&in->lock); pthread_mutex_unlock(&in->lock);
} }

View File

@ -282,7 +282,7 @@ struct vo_driver {
* immediately. * immediately.
*/ */
void (*wakeup)(struct vo *vo); 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. * 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); double vo_get_delay(struct vo *vo);
void vo_wakeup(struct vo *vo); void vo_wakeup(struct vo *vo);
void vo_wait_default(struct vo *vo, int64_t until_time);
struct mp_keymap { struct mp_keymap {
int from; int from;

View File

@ -253,9 +253,7 @@ static void acquire_vt(void *data)
crtc_setup(vo); crtc_setup(vo);
} }
static void wait_events(struct vo *vo, int64_t until_time_us)
static int wait_events(struct vo *vo, int64_t until_time_us)
{ {
struct priv *p = vo->priv; struct priv *p = vo->priv;
if (p->vt_switcher_active) { 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); int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000);
vt_switcher_poll(&p->vt_switcher, timeout_ms); vt_switcher_poll(&p->vt_switcher, timeout_ms);
} }
return 0;
} }
static void wakeup(struct vo *vo) static void wakeup(struct vo *vo)

View File

@ -357,6 +357,23 @@ static int control(struct vo *vo, uint32_t request, void *data)
return r; 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) static void uninit(struct vo *vo)
{ {
struct gl_priv *p = vo->priv; struct gl_priv *p = vo->priv;
@ -466,6 +483,8 @@ const struct vo_driver video_out_opengl = {
.control = control, .control = control,
.draw_frame = draw_frame, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.wait_events = wait_events,
.wakeup = wakeup,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(struct gl_priv), .priv_size = sizeof(struct gl_priv),
.options = options, .options = options,
@ -481,6 +500,8 @@ const struct vo_driver video_out_opengl_hq = {
.control = control, .control = control,
.draw_frame = draw_frame, .draw_frame = draw_frame,
.flip_page = flip_page, .flip_page = flip_page,
.wait_events = wait_events,
.wakeup = wakeup,
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(struct gl_priv), .priv_size = sizeof(struct gl_priv),
.priv_defaults = &(const struct gl_priv){ .priv_defaults = &(const struct gl_priv){

View File

@ -533,7 +533,7 @@ static void wakeup(struct vo *vo)
SDL_PushEvent(&event); 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(); int64_t wait_us = until_time_us - mp_time_us();
int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); 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; break;
} }
} }
return 0;
} }
static void uninit(struct vo *vo) static void uninit(struct vo *vo)