summaryrefslogtreecommitdiffstats
path: root/video
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 /video
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.
Diffstat (limited to 'video')
-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;