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().
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);
};

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){}
#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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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){

View File

@ -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)