diff options
Diffstat (limited to 'video/out/vo_x11.c')
-rw-r--r-- | video/out/vo_x11.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 67fac3c9a7..b637b59e23 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -24,7 +24,6 @@ #include <libswscale/swscale.h> -#include "config.h" #include "vo.h" #include "video/csputils.h" #include "video/mp_image.h" @@ -34,6 +33,7 @@ #include <errno.h> +#include "present_sync.h" #include "x11_common.h" #include <sys/ipc.h> @@ -133,12 +133,14 @@ shmemerror: p->myximage[foo] = XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, 0, NULL, p->image_width, p->image_height, 8, 0); - if (!p->myximage[foo]) { + if (p->myximage[foo]) { + p->myximage[foo]->data = + calloc(1, p->myximage[foo]->bytes_per_line * p->image_height + 32); + } + if (!p->myximage[foo] || !p->myximage[foo]->data) { MP_WARN(vo, "could not allocate image"); return false; } - p->myximage[foo]->data = - calloc(1, p->myximage[foo]->bytes_per_line * p->image_height + 32); } return true; } @@ -151,8 +153,13 @@ static void freeMyXImage(struct priv *p, int foo) XDestroyImage(p->myximage[foo]); shmdt(p->Shminfo[foo].shmaddr); } else { - if (p->myximage[foo]) + if (p->myximage[foo]) { + // XDestroyImage() would free the data too since XFree() just calls + // free(), but do it ourselves for portability reasons + free(p->myximage[foo]->data); + p->myximage[foo]->data = NULL; XDestroyImage(p->myximage[foo]); + } } p->myximage[foo] = NULL; } @@ -161,10 +168,6 @@ static void freeMyXImage(struct priv *p, int foo) static int reconfig(struct vo *vo, struct mp_image_params *fmt) { - struct priv *p = vo->priv; - - mp_image_unrefp(&p->original_image); - vo_x11_config_vo_window(vo); if (!resize(vo)) @@ -263,6 +266,10 @@ static bool resize(struct vo *vo) if (mp_sws_reinit(p->sws) < 0) return false; + + mp_mutex_lock(&vo->params_mutex); + vo->target_params = &p->sws->dst; + mp_mutex_unlock(&vo->params_mutex); } vo->want_redraw = true; @@ -296,7 +303,7 @@ static void wait_for_completion(struct vo *vo, int max_outstanding) " for XShm completion events...\n"); ctx->Shm_Warned_Slow = 1; } - mp_sleep_us(1000); + mp_sleep_ns(MP_TIME_MS_TO_NS(1)); vo_x11_check_events(vo); } } @@ -307,40 +314,51 @@ static void flip_page(struct vo *vo) struct priv *p = vo->priv; Display_Image(p, p->myximage[p->current_buf]); p->current_buf = (p->current_buf + 1) % 2; + if (vo->x11->use_present) { + vo_x11_present(vo); + present_sync_swap(vo->x11->present); + } } -// Note: REDRAW_FRAME can call this with NULL. -static void draw_image(struct vo *vo, mp_image_t *mpi) +static void get_vsync(struct vo *vo, struct vo_vsync_info *info) +{ + struct vo_x11_state *x11 = vo->x11; + if (x11->use_present) + present_sync_get_info(x11->present, info); +} + +static void draw_frame(struct vo *vo, struct vo_frame *frame) { struct priv *p = vo->priv; wait_for_completion(vo, 1); + bool render = vo_x11_check_visible(vo); + if (!render) + return; struct mp_image *img = &p->mp_ximages[p->current_buf]; - if (mpi) { + if (frame->current) { mp_image_clear_rc_inv(img, p->dst); - struct mp_image src = *mpi; + struct mp_image *src = frame->current; struct mp_rect src_rc = p->src; - src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src.fmt.align_x); - src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src.fmt.align_y); - mp_image_crop_rc(&src, src_rc); + src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src->fmt.align_x); + src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src->fmt.align_y); + mp_image_crop_rc(src, src_rc); struct mp_image dst = *img; mp_image_crop_rc(&dst, p->dst); - mp_sws_scale(p->sws, &dst, &src); + mp_sws_scale(p->sws, &dst, src); } else { mp_image_clear(img, 0, 0, img->w, img->h); } - osd_draw_on_image(vo->osd, p->osd, mpi ? mpi->pts : 0, 0, img); + osd_draw_on_image(vo->osd, p->osd, frame->current ? frame->current->pts : 0, 0, img); - if (mpi != p->original_image) { - talloc_free(p->original_image); - p->original_image = mpi; - } + if (frame->current != p->original_image) + p->original_image = frame->current; } static int query_format(struct vo *vo, int format) @@ -361,8 +379,6 @@ static void uninit(struct vo *vo) if (p->gc) XFreeGC(vo->x11->display, p->gc); - talloc_free(p->original_image); - vo_x11_uninit(vo); } @@ -403,15 +419,11 @@ error: static int control(struct vo *vo, uint32_t request, void *data) { - struct priv *p = vo->priv; switch (request) { case VOCTRL_SET_PANSCAN: if (vo->config_ok) resize(vo); return VO_TRUE; - case VOCTRL_REDRAW_FRAME: - draw_image(vo, p->original_image); - return true; } int events = 0; @@ -430,8 +442,9 @@ const struct vo_driver video_out_x11 = { .query_format = query_format, .reconfig = reconfig, .control = control, - .draw_image = draw_image, + .draw_frame = draw_frame, .flip_page = flip_page, + .get_vsync = get_vsync, .wakeup = vo_x11_wakeup, .wait_events = vo_x11_wait_events, .uninit = uninit, |