From fde784129f4b94b6fa8b2293127c41dc140b7d3a Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 20 Jul 2016 20:52:08 +0200 Subject: x11: stop using vo.event_fd Instead let it do its own event loop wakeup handling. --- video/out/opengl/context_x11.c | 14 ++++++++++++++ video/out/opengl/context_x11egl.c | 12 ++++++++++++ video/out/vo_vaapi.c | 2 ++ video/out/vo_vdpau.c | 2 ++ video/out/vo_x11.c | 2 ++ video/out/vo_xv.c | 2 ++ video/out/x11_common.c | 35 ++++++++++++++++++++++++++++++++++- video/out/x11_common.h | 4 ++++ 8 files changed, 72 insertions(+), 1 deletion(-) diff --git a/video/out/opengl/context_x11.c b/video/out/opengl/context_x11.c index 11700efdf4..48533fe701 100644 --- a/video/out/opengl/context_x11.c +++ b/video/out/opengl/context_x11.c @@ -308,6 +308,16 @@ static void glx_swap_buffers(struct MPGLContext *ctx) glXSwapBuffers(ctx->vo->x11->display, ctx->vo->x11->window); } +static void glx_wakeup(struct MPGLContext *ctx) +{ + vo_x11_wakeup(ctx->vo); +} + +static void glx_wait_events(struct MPGLContext *ctx, int64_t until_time_us) +{ + vo_x11_wait_events(ctx->vo, until_time_us); +} + const struct mpgl_driver mpgl_driver_x11 = { .name = "x11", .priv_size = sizeof(struct glx_context), @@ -315,6 +325,8 @@ const struct mpgl_driver mpgl_driver_x11 = { .reconfig = glx_reconfig, .swap_buffers = glx_swap_buffers, .control = glx_control, + .wakeup = glx_wakeup, + .wait_events = glx_wait_events, .uninit = glx_uninit, }; @@ -325,5 +337,7 @@ const struct mpgl_driver mpgl_driver_x11_probe = { .reconfig = glx_reconfig, .swap_buffers = glx_swap_buffers, .control = glx_control, + .wakeup = glx_wakeup, + .wait_events = glx_wait_events, .uninit = glx_uninit, }; diff --git a/video/out/opengl/context_x11egl.c b/video/out/opengl/context_x11egl.c index 2e4fd5fa90..aea388b9a2 100644 --- a/video/out/opengl/context_x11egl.c +++ b/video/out/opengl/context_x11egl.c @@ -191,6 +191,16 @@ static void mpegl_swap_buffers(MPGLContext *ctx) eglSwapBuffers(p->egl_display, p->egl_surface); } +static void mpegl_wakeup(struct MPGLContext *ctx) +{ + vo_x11_wakeup(ctx->vo); +} + +static void mpegl_wait_events(struct MPGLContext *ctx, int64_t until_time_us) +{ + vo_x11_wait_events(ctx->vo, until_time_us); +} + const struct mpgl_driver mpgl_driver_x11egl = { .name = "x11egl", .priv_size = sizeof(struct priv), @@ -198,5 +208,7 @@ const struct mpgl_driver mpgl_driver_x11egl = { .reconfig = mpegl_reconfig, .swap_buffers = mpegl_swap_buffers, .control = mpegl_control, + .wakeup = mpegl_wakeup, + .wait_events = mpegl_wait_events, .uninit = mpegl_uninit, }; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index 11bb469b24..612879321e 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -682,6 +682,8 @@ const struct vo_driver video_out_vaapi = { .control = control, .draw_image = draw_image, .flip_page = flip_page, + .wakeup = vo_x11_wakeup, + .wait_events = vo_x11_wait_events, .uninit = uninit, .priv_size = sizeof(struct priv), .priv_defaults = &(const struct priv) { diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 6dd31e9082..2a0566f6ef 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -1139,6 +1139,8 @@ const struct vo_driver video_out_vdpau = { .control = control, .draw_frame = draw_frame, .flip_page = flip_page, + .wakeup = vo_x11_wakeup, + .wait_events = vo_x11_wait_events, .uninit = uninit, .priv_size = sizeof(struct vdpctx), .options = (const struct m_option []){ diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 01928b7e0e..b06a231e5a 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -449,5 +449,7 @@ const struct vo_driver video_out_x11 = { .control = control, .draw_image = draw_image, .flip_page = flip_page, + .wakeup = vo_x11_wakeup, + .wait_events = vo_x11_wait_events, .uninit = uninit, }; diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 121dff0500..e15c12b3b6 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -905,6 +905,8 @@ const struct vo_driver video_out_xv = { .control = control, .draw_image = draw_image, .flip_page = flip_page, + .wakeup = vo_x11_wakeup, + .wait_events = vo_x11_wait_events, .uninit = uninit, .priv_size = sizeof(struct xvctx), .priv_defaults = &(const struct xvctx) { diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 33c588a808..2f35b6a4b8 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "config.h" #include "misc/bstr.h" @@ -38,6 +40,7 @@ #include "vo.h" #include "win_state.h" #include "osdep/atomics.h" +#include "osdep/io.h" #include "osdep/timer.h" #include "osdep/subprocess.h" @@ -593,7 +596,8 @@ int vo_x11_init(struct vo *vo) x11->wm_type = vo_wm_detect(vo); - vo->event_fd = ConnectionNumber(x11->display); + x11->event_fd = ConnectionNumber(x11->display); + mp_make_wakeup_pipe(x11->wakeup_pipe); xrandr_read(x11); @@ -761,6 +765,9 @@ void vo_x11_uninit(struct vo *vo) sem_destroy(&x11->screensaver_sem); } + for (int n = 0; n < 2; n++) + close(x11->wakeup_pipe[n]); + talloc_free(x11); vo->x11 = NULL; } @@ -1907,6 +1914,32 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg) return VO_NOTIMPL; } +void vo_x11_wakeup(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; + + (void)write(x11->wakeup_pipe[1], &(char){0}, 1); +} + +void vo_x11_wait_events(struct vo *vo, int64_t until_time_us) +{ + struct vo_x11_state *x11 = vo->x11; + + struct pollfd fds[2] = { + { .fd = x11->event_fd, .events = POLLIN }, + { .fd = x11->wakeup_pipe[0], .events = POLLIN }, + }; + int64_t wait_us = until_time_us - mp_time_us(); + int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); + + poll(fds, 2, timeout_ms); + + if (fds[1].revents & POLLIN) { + char buf[100]; + (void)read(x11->wakeup_pipe[0], buf, sizeof(buf)); // flush + } +} + static void xscreensaver_heartbeat(struct vo_x11_state *x11) { double time = mp_time_sec(); diff --git a/video/out/x11_common.h b/video/out/x11_common.h index 67e5ac1f0b..d861b32d1c 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -45,6 +45,8 @@ struct vo_x11_state { struct mp_log *log; struct input_ctx *input_ctx; Display *display; + int event_fd; + int wakeup_pipe[2]; Window window; Window rootwin; Window parent; // embedded in this foreign window @@ -132,6 +134,8 @@ bool vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, const char *classname); void vo_x11_config_vo_window(struct vo *vo); int vo_x11_control(struct vo *vo, int *events, int request, void *arg); +void vo_x11_wakeup(struct vo *vo); +void vo_x11_wait_events(struct vo *vo, int64_t until_time_us); void vo_x11_silence_xlib(int dir); -- cgit v1.2.3