From 3a6ade7a848f5213525430d9049e96e642638fc8 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sun, 22 Mar 2015 02:32:03 +0200 Subject: [PATCH] vo_opengl: do not block on wayland When not receiving frame callbacks, we should not draw anything to avoid blocking the OpenGL renderer. We do this by extending gl context api, by introducing new optional function 'is_active', that indicates whether OpenGL renderers should draw or not. This fixes issue #249. --- video/out/gl_common.h | 4 ++++ video/out/gl_video.c | 7 +++++++ video/out/gl_video.h | 1 + video/out/gl_wayland.c | 7 +++++++ video/out/vo_opengl.c | 12 ++++++++++++ 5 files changed, 31 insertions(+) diff --git a/video/out/gl_common.h b/video/out/gl_common.h index 1cb3a5c441..1d33682f3e 100644 --- a/video/out/gl_common.h +++ b/video/out/gl_common.h @@ -109,6 +109,10 @@ typedef struct MPGLContext { void (*register_resize_callback)(struct vo *vo, void (*cb)(struct vo *vo, int w, int h)); + // Optional activity state of context. + // If false, OpenGL renderers should not draw anything. + bool (*is_active)(struct MPGLContext *); + // For free use by the backend. void *priv; } MPGLContext; diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 07b3b9ebb6..7b6976685f 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -1976,6 +1976,13 @@ static bool get_image(struct gl_video *p, struct mp_image *mpi) return true; } +void gl_video_skip_image(struct gl_video *p, struct mp_image *mpi) +{ + struct video_image *vimg = &p->image; + talloc_free(vimg->mpi); + vimg->mpi = mpi; +} + void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi) { GL *gl = p->gl; diff --git a/video/out/gl_video.h b/video/out/gl_video.h index 6ed39c71d3..d55486d34f 100644 --- a/video/out/gl_video.h +++ b/video/out/gl_video.h @@ -73,6 +73,7 @@ bool gl_video_check_format(struct gl_video *p, int mp_format); void gl_video_config(struct gl_video *p, struct mp_image_params *params); void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b); void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d); +void gl_video_skip_image(struct gl_video *p, struct mp_image *mpi); void gl_video_upload_image(struct gl_video *p, struct mp_image *img); void gl_video_render_frame(struct gl_video *p, int fbo, struct frame_timing *t); void gl_video_resize(struct gl_video *p, int vp_w, int vp_h, diff --git a/video/out/gl_wayland.c b/video/out/gl_wayland.c index d86faa8d95..0fcec82377 100644 --- a/video/out/gl_wayland.c +++ b/video/out/gl_wayland.c @@ -215,6 +215,12 @@ static int control(struct vo *vo, int *events, int request, void *data) return r; } +static bool is_active(struct MPGLContext *ctx) +{ + struct vo_wayland_state *wl = ctx->vo->wayland; + return wl->frame.pending; +} + void mpgl_set_backend_wayland(MPGLContext *ctx) { ctx->config_window = config_window_wayland; @@ -223,4 +229,5 @@ void mpgl_set_backend_wayland(MPGLContext *ctx) ctx->vo_control = control; ctx->vo_init = vo_wayland_init; ctx->vo_uninit = vo_wayland_uninit; + ctx->is_active = is_active; } diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 84381e42d1..25e25a2e9d 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -122,6 +122,9 @@ static void flip_page(struct vo *vo) struct gl_priv *p = vo->priv; GL *gl = p->gl; + if (p->glctx->is_active && !p->glctx->is_active(p->glctx)) + return; + mpgl_lock(p->glctx); p->glctx->swapGlBuffers(p->glctx); @@ -160,6 +163,12 @@ static void draw_image_timed(struct vo *vo, mp_image_t *mpi, struct gl_priv *p = vo->priv; GL *gl = p->gl; + if (p->glctx->is_active && !p->glctx->is_active(p->glctx)) { + if (mpi) + gl_video_skip_image(p->renderer, mpi); + return; + } + if (p->vo_flipped) mp_image_vflip(mpi); @@ -376,6 +385,9 @@ static int control(struct vo *vo, uint32_t request, void *data) request_hwdec_api(p, data); return true; case VOCTRL_REDRAW_FRAME: + if (p->glctx->is_active && !p->glctx->is_active(p->glctx)) + return true; + mpgl_lock(p->glctx); gl_video_render_frame(p->renderer, 0, NULL); mpgl_unlock(p->glctx);