summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2015-03-22 02:47:27 +0200
committerwm4 <wm4@nowhere>2015-03-23 21:53:32 +0100
commit3714430cdf0c1515da5dea9e3c098f02802a45ee (patch)
treed8b2c6071e959d3374cf4d1b68fc268dad14a161
parentdd08aa7364e061132b795f6e55aaeeb2e4854b8e (diff)
downloadmpv-3714430cdf0c1515da5dea9e3c098f02802a45ee.tar.bz2
mpv-3714430cdf0c1515da5dea9e3c098f02802a45ee.tar.xz
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.
-rw-r--r--video/out/gl_wayland.c5
-rw-r--r--video/out/vo_wayland.c57
-rw-r--r--video/out/wayland_common.c30
-rw-r--r--video/out/wayland_common.h5
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;