diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 36ca7ab84b..684776dabc 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -154,6 +154,7 @@ struct vdpctx { int query_surface_num; VdpTime recent_vsync_time; float user_fps; + int composite_detect; unsigned int vsync_interval; uint64_t last_queue_time; uint64_t queue_time[MAX_OUTPUT_SURFACES]; @@ -545,7 +546,10 @@ static int win_x11_init_vdpau_flip_queue(struct vo *vo) vc->last_sync_update = GetTimer(); vc->vsync_interval = 1; - if (vc->user_fps > 0) { + if (vc->composite_detect && vo_x11_screen_is_composited(vo)) { + mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Compositing window manager " + "detected. Assuming timing info is inaccurate.\n"); + } else if (vc->user_fps > 0) { vc->vsync_interval = 1e9 / vc->user_fps; mp_msg(MSGT_VO, MSGL_INFO, "[vdpau] Assuming user-specified display " "refresh rate of %.3f Hz.\n", vc->user_fps); @@ -1315,7 +1319,7 @@ static void flip_page_timed(struct vo *vo, unsigned int pts_us, int duration) else duration *= 1000; - if (vc->user_fps < 0) + if (vc->vsync_interval == 1) duration = -1; // Make sure drop logic is disabled uint64_t now = sync_vdptime(vo); @@ -1858,6 +1862,7 @@ const struct vo_driver video_out_vdpau = { "instead.\n"), OPT_INTRANGE("hqscaling", hqscaling, 0, 0, 9), OPT_FLOAT("fps", user_fps, 0), + OPT_FLAG_ON("composite-detect", composite_detect, 0, OPTDEF_INT(1)), OPT_INT("queuetime_windowed", flip_offset_window, 0, OPTDEF_INT(50)), OPT_INT("queuetime_fs", flip_offset_fs, 0, OPTDEF_INT(50)), OPT_INTRANGE("output_surfaces", num_output_surfaces, 0, diff --git a/libvo/x11_common.c b/libvo/x11_common.c index ee50ba5575..cf8bb2dc4f 100644 --- a/libvo/x11_common.c +++ b/libvo/x11_common.c @@ -337,6 +337,9 @@ static void init_atoms(struct vo_x11_state *x11) XA_INIT(WM_PROTOCOLS); XA_INIT(WM_DELETE_WINDOW); XA_INIT(UTF8_STRING); + char buf[50]; + sprintf(buf, "_NET_WM_CM_S%d", x11->screen); + x11->XA_NET_WM_CM = XInternAtom(x11->display, buf, False); } void update_xinerama_info(struct vo *vo) { @@ -1941,6 +1944,12 @@ uint32_t vo_x11_get_equalizer(const char *name, int *value) return VO_TRUE; } +bool vo_x11_screen_is_composited(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; + return XGetSelectionOwner(x11->display, x11->XA_NET_WM_CM) != None; +} + #ifdef CONFIG_XV int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, const char *name, int value) { diff --git a/libvo/x11_common.h b/libvo/x11_common.h index 14c7e44549..bd340c822d 100644 --- a/libvo/x11_common.h +++ b/libvo/x11_common.h @@ -95,6 +95,7 @@ struct vo_x11_state { Atom XAWM_PROTOCOLS; Atom XAWM_DELETE_WINDOW; Atom XAUTF8_STRING; + Atom XA_NET_WM_CM; }; #if defined(CONFIG_GL) || defined(CONFIG_X11) || defined(CONFIG_XV) @@ -137,6 +138,7 @@ void vo_x11_uninit(struct vo *vo); Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo); uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value); uint32_t vo_x11_get_equalizer(const char *name, int *value); +bool vo_x11_screen_is_composited(struct vo *vo); void fstype_help(void); void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, unsigned int width, unsigned int height, int flags,