mirror of https://github.com/mpv-player/mpv
x11: avoid XPresent API calls when it's not needed
This commit kind of mixes several related things together. The main thing is to avoid calling any XPresent functions or internal functions related to presentation when the feature is not auto-whitelisted or enabled by the user. Internally rework this so it all works off of a use_present bool (have_present is eliminated because having a non-zero present_code covers exactly the same thing) and make sure it updates on runtime. Finally, put some actual logging in here whenever XPresent is enabled/disabled. Fixes #10326.
This commit is contained in:
parent
1ffdb9128d
commit
652f09a7a6
|
@ -206,14 +206,17 @@ static bool glx_check_visible(struct ra_ctx *ctx)
|
|||
static void glx_swap_buffers(struct ra_ctx *ctx)
|
||||
{
|
||||
glXSwapBuffers(ctx->vo->x11->display, ctx->vo->x11->window);
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
if (ctx->vo->x11->use_present) {
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
}
|
||||
}
|
||||
|
||||
static void glx_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_x11_state *x11 = ctx->vo->x11;
|
||||
present_sync_get_info(x11->present, info);
|
||||
if (ctx->vo->x11->use_present)
|
||||
present_sync_get_info(x11->present, info);
|
||||
}
|
||||
|
||||
static bool glx_init(struct ra_ctx *ctx)
|
||||
|
|
|
@ -82,14 +82,17 @@ static void mpegl_swap_buffers(struct ra_ctx *ctx)
|
|||
struct priv *p = ctx->priv;
|
||||
|
||||
eglSwapBuffers(p->egl_display, p->egl_surface);
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
if (ctx->vo->x11->use_present) {
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpegl_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_x11_state *x11 = ctx->vo->x11;
|
||||
present_sync_get_info(x11->present, info);
|
||||
if (ctx->vo->x11->use_present)
|
||||
present_sync_get_info(x11->present, info);
|
||||
}
|
||||
|
||||
static bool mpegl_init(struct ra_ctx *ctx)
|
||||
|
|
|
@ -308,14 +308,17 @@ 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;
|
||||
vo_x11_present(vo);
|
||||
present_sync_swap(vo->x11->present);
|
||||
if (vo->x11->use_present) {
|
||||
vo_x11_present(vo);
|
||||
present_sync_swap(vo->x11->present);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
present_sync_get_info(x11->present, info);
|
||||
if (x11->use_present)
|
||||
present_sync_get_info(x11->present, info);
|
||||
}
|
||||
|
||||
// Note: REDRAW_FRAME can call this with NULL.
|
||||
|
|
|
@ -691,14 +691,17 @@ static void flip_page(struct vo *vo)
|
|||
if (!ctx->Shmem_Flag)
|
||||
XSync(vo->x11->display, False);
|
||||
|
||||
vo_x11_present(vo);
|
||||
present_sync_swap(vo->x11->present);
|
||||
if (vo->x11->use_present) {
|
||||
vo_x11_present(vo);
|
||||
present_sync_swap(vo->x11->present);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
present_sync_get_info(x11->present, info);
|
||||
if (x11->use_present)
|
||||
present_sync_get_info(x11->present, info);
|
||||
}
|
||||
|
||||
// Note: REDRAW_FRAME can call this with NULL.
|
||||
|
|
|
@ -34,14 +34,17 @@ static bool xlib_check_visible(struct ra_ctx *ctx)
|
|||
|
||||
static void xlib_vk_swap_buffers(struct ra_ctx *ctx)
|
||||
{
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
if (ctx->vo->x11->use_present) {
|
||||
vo_x11_present(ctx->vo);
|
||||
present_sync_swap(ctx->vo->x11->present);
|
||||
}
|
||||
}
|
||||
|
||||
static void xlib_vk_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_x11_state *x11 = ctx->vo->x11;
|
||||
present_sync_get_info(x11->present, info);
|
||||
if (ctx->vo->x11->use_present)
|
||||
present_sync_get_info(x11->present, info);
|
||||
}
|
||||
|
||||
static void xlib_uninit(struct ra_ctx *ctx)
|
||||
|
|
|
@ -377,6 +377,19 @@ static int vo_wm_detect(struct vo *vo)
|
|||
return wm;
|
||||
}
|
||||
|
||||
static void xpresent_set(struct vo_x11_state *x11)
|
||||
{
|
||||
int present = x11->opts->x11_present;
|
||||
x11->use_present = x11->present_code &&
|
||||
((x11->has_mesa && !x11->has_nvidia && present) ||
|
||||
present == 2);
|
||||
if (x11->use_present) {
|
||||
MP_VERBOSE(x11, "XPresent enabled.\n");
|
||||
} else {
|
||||
MP_VERBOSE(x11, "XPresent disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void xrandr_read(struct vo_x11_state *x11)
|
||||
{
|
||||
for(int i = 0; i < x11->num_displays; i++)
|
||||
|
@ -427,6 +440,8 @@ static void xrandr_read(struct vo_x11_state *x11)
|
|||
nouveau >= 0 || radeon >= 0;
|
||||
x11->has_nvidia = x11->has_nvidia || nvidia >= 0;
|
||||
}
|
||||
if (x11->present_code)
|
||||
xpresent_set(x11);
|
||||
XRRFreeProviderResources(pr);
|
||||
}
|
||||
|
||||
|
@ -1286,13 +1301,10 @@ void vo_x11_check_events(struct vo *vo)
|
|||
break;
|
||||
case GenericEvent: {
|
||||
XGenericEventCookie *cookie = (XGenericEventCookie *)&Event.xcookie;
|
||||
if (cookie->extension == x11->present_code && x11->have_present)
|
||||
if (cookie->extension == x11->present_code && x11->use_present)
|
||||
{
|
||||
int present = x11->opts->x11_present;
|
||||
bool use_present = (x11->has_mesa && !x11->has_nvidia &&
|
||||
present) || present == 2;
|
||||
XGetEventData(x11->display, cookie);
|
||||
if (cookie->evtype == PresentCompleteNotify && use_present) {
|
||||
if (cookie->evtype == PresentCompleteNotify) {
|
||||
XPresentCompleteNotifyEvent *present_event;
|
||||
present_event = (XPresentCompleteNotifyEvent *)cookie->data;
|
||||
present_update_sync_values(x11->present, present_event->ust,
|
||||
|
@ -1530,11 +1542,11 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis,
|
|||
|
||||
if (!XPresentQueryExtension(x11->display, &x11->present_code, NULL, NULL)) {
|
||||
MP_VERBOSE(x11, "The XPresent extension is not supported.\n");
|
||||
x11->have_present = false;
|
||||
} else {
|
||||
x11->have_present = true;
|
||||
MP_VERBOSE(x11, "The XPresent extension was found.\n");
|
||||
XPresentSelectInput(x11->display, x11->window, PresentCompleteNotifyMask);
|
||||
}
|
||||
xpresent_set(x11);
|
||||
|
||||
x11->mouse_cursor_set = false;
|
||||
x11->mouse_cursor_visible = true;
|
||||
|
@ -1962,6 +1974,8 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
|
|||
vo_x11_minimize(vo);
|
||||
if (opt == &opts->window_maximized)
|
||||
vo_x11_maximize(vo);
|
||||
if (opt == &opts->x11_present)
|
||||
xpresent_set(x11);
|
||||
if (opt == &opts->geometry || opt == &opts->autofit ||
|
||||
opt == &opts->autofit_smaller || opt == &opts->autofit_larger)
|
||||
{
|
||||
|
|
|
@ -76,7 +76,7 @@ struct vo_x11_state {
|
|||
double screensaver_time_last;
|
||||
|
||||
struct mp_present *present;
|
||||
bool have_present;
|
||||
bool use_present;
|
||||
int present_code;
|
||||
|
||||
XIM xim;
|
||||
|
|
Loading…
Reference in New Issue