From 3714430cdf0c1515da5dea9e3c098f02802a45ee Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sun, 22 Mar 2015 02:47:27 +0200 Subject: vo_wayland: share frame callbacks. Define frame callback logic in wayland_common.c As this should be used by opengl renderer as well. Preferably drawing should be skipped entierly when no frame callbacks are received. However, for now only swap buffers is skipped. --- video/out/gl_wayland.c | 5 ++++ video/out/vo_wayland.c | 57 +++++++++++++++------------------------------- video/out/wayland_common.c | 30 ++++++++++++++++++++++++ video/out/wayland_common.h | 5 ++++ 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/video/out/gl_wayland.c b/video/out/gl_wayland.c index a1c04b199d..d86faa8d95 100644 --- a/video/out/gl_wayland.c +++ b/video/out/gl_wayland.c @@ -196,7 +196,12 @@ static void releaseGlContext_wayland(MPGLContext *ctx) static void swapGlBuffers_wayland(MPGLContext *ctx) { struct vo_wayland_state *wl = ctx->vo->wayland; + + if (!wl->frame.pending) + return; + eglSwapBuffers(wl->egl_context.egl.dpy, wl->egl_context.egl_surface); + wl->frame.pending = false; } static int control(struct vo *vo, int *events, int request, void *data) diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index 5fb4dc60bd..ab4ed8c9c3 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -41,7 +41,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi); static void draw_osd(struct vo *vo); -static const struct wl_callback_listener frame_listener; static const struct wl_buffer_listener buffer_listener; // TODO: pay attention to the reported subpixel order @@ -119,8 +118,6 @@ struct priv { struct mp_sws_context *sws; struct mp_image_params in_format; - struct wl_callback *redraw_callback; - struct buffer_pool video_bufpool; struct mp_image *original_image; @@ -359,34 +356,6 @@ static const struct wl_buffer_listener buffer_listener = { buffer_handle_release }; -static void frame_handle_redraw(void *data, - struct wl_callback *callback, - uint32_t time) -{ - struct priv *p = data; - struct vo_wayland_state *wl = p->wl; - shm_buffer_t *buf = buffer_pool_get_front(&p->video_bufpool); - - wl_surface_attach(wl->window.video_surface, buf->buffer, p->x, p->y); - wl_surface_damage(wl->window.video_surface, 0, 0, p->dst_w, p->dst_h); - - if (callback) - wl_callback_destroy(callback); - - p->redraw_callback = wl_surface_frame(wl->window.video_surface); - wl_callback_add_listener(p->redraw_callback, &frame_listener, p); - wl_surface_commit(wl->window.video_surface); - buffer_finalise_front(buf); - - p->x = 0; - p->y = 0; - p->recent_flip_time = mp_time_us(); -} - -static const struct wl_callback_listener frame_listener = { - frame_handle_redraw -}; - static void shm_handle_format(void *data, struct wl_shm *wl_shm, uint32_t format) @@ -414,13 +383,17 @@ static const struct wl_shm_listener shm_listener = { static void draw_image(struct vo *vo, mp_image_t *mpi) { struct priv *p = vo->priv; - shm_buffer_t *buf = buffer_pool_get_back(&p->video_bufpool); if (mpi) { talloc_free(p->original_image); p->original_image = mpi; } + if (!p->wl->frame.pending) + return; + + shm_buffer_t *buf = buffer_pool_get_back(&p->video_bufpool); + if (!buf) { // TODO: use similar handling of busy buffers as the osd buffers // if the need arises @@ -535,12 +508,21 @@ static void flip_page(struct vo *vo) { struct priv *p = vo->priv; + if (!p->wl->frame.pending) + return; + buffer_pool_swap(&p->video_bufpool); - if (!p->redraw_callback) { - MP_DBG(p->wl, "restart frame callback\n"); - frame_handle_redraw(p, NULL, 0); - } + shm_buffer_t *buf = buffer_pool_get_front(&p->video_bufpool); + wl_surface_attach(p->wl->window.video_surface, buf->buffer, p->x, p->y); + wl_surface_damage(p->wl->window.video_surface, 0, 0, p->dst_w, p->dst_h); + wl_surface_commit(p->wl->window.video_surface); + buffer_finalise_front(buf); + + p->x = 0; + p->y = 0; + p->recent_flip_time = mp_time_us(); + p->wl->frame.pending = false; } static int query_format(struct vo *vo, int format) @@ -612,9 +594,6 @@ static void uninit(struct vo *vo) struct priv *p = vo->priv; buffer_pool_destroy(&p->video_bufpool); - if (p->redraw_callback) - wl_callback_destroy(p->redraw_callback); - talloc_free(p->original_image); for (int i = 0; i < MAX_OSD_PARTS; ++i) { diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 224a60d1e0..5ddd1ad54c 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -59,6 +59,8 @@ static void schedule_resize(struct vo_wayland_state *wl, static void vo_wayland_fullscreen (struct vo *vo); +static const struct wl_callback_listener frame_listener; + static const struct mp_keymap keymap[] = { // special keys {XKB_KEY_Pause, MP_KEY_PAUSE}, {XKB_KEY_Escape, MP_KEY_ESC}, @@ -795,6 +797,30 @@ static void schedule_resize(struct vo_wayland_state *wl, wl->vo->dheight = height; } +static void frame_callback(void *data, + struct wl_callback *callback, + uint32_t time) +{ + struct vo_wayland_state *wl = data; + + if (callback) + wl_callback_destroy(callback); + + wl->frame.callback = wl_surface_frame(wl->window.video_surface); + + if (!wl->frame.callback) { + MP_ERR(wl, "wl_surface_frame failed\n"); + return; + } + + wl_callback_add_listener(wl->frame.callback, &frame_listener, wl); + wl->frame.pending = true; +} + +static const struct wl_callback_listener frame_listener = { + frame_callback +}; + static bool create_display (struct vo_wayland_state *wl) { if (wl->vo->probing && !getenv("XDG_RUNTIME_DIR")) @@ -878,6 +904,7 @@ static bool create_window (struct vo_wayland_state *wl) wl_shell_surface_set_class(wl->window.shell_surface, "mpv"); } + frame_callback(wl, NULL, 0); return true; } @@ -888,6 +915,9 @@ static void destroy_window (struct vo_wayland_state *wl) if (wl->window.video_surface) wl_surface_destroy(wl->window.video_surface); + + if (wl->frame.callback) + wl_callback_destroy(wl->frame.callback); } static bool create_cursor (struct vo_wayland_state *wl) diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 5f0947f47d..d7c505290a 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -52,6 +52,11 @@ struct vo_wayland_state { struct vo *vo; struct mp_log* log; + struct { + struct wl_callback *callback; + bool pending; + } frame; + #if HAVE_GL_WAYLAND struct { EGLSurface egl_surface; -- cgit v1.2.3