diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 4b58c35b46b..ae082f60fbf 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -262,10 +262,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, if (double_buffer) { surface_type &= ~EGL_PIXMAP_BIT; - if (dri2_dpy->swap_available) { - conf->base.MinSwapInterval = 0; - conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */ - } + conf->base.MinSwapInterval = dri2_dpy->min_swap_interval; + conf->base.MaxSwapInterval = dri2_dpy->max_swap_interval; } conf->base.SurfaceType |= surface_type; @@ -533,6 +531,9 @@ dri2_create_screen(_EGLDisplay *disp) if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; } + if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { + dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; + } } } else { assert(dri2_dpy->swrast); diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 81c1354b794..85c0745a354 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -100,11 +100,15 @@ struct dri2_egl_display __DRItexBufferExtension *tex_buffer; __DRIimageExtension *image; __DRIrobustnessExtension *robustness; + __DRI2configQueryExtension *config; int fd; int own_device; int swap_available; int invalidate_available; + int min_swap_interval; + int max_swap_interval; + int default_swap_interval; #ifdef HAVE_DRM_PLATFORM struct gbm_dri_device *gbm_dri; #endif diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index a56fc781880..4757ccfca4f 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -39,6 +39,12 @@ #include "egl_dri2.h" +/* From xmlpool/options.h, user exposed so should be stable */ +#define DRI_CONF_VBLANK_NEVER 0 +#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 +#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 +#define DRI_CONF_VBLANK_ALWAYS_SYNC 3 + static void swrastCreateDrawable(struct dri2_egl_display * dri2_dpy, struct dri2_egl_surface * dri2_surf, @@ -273,8 +279,21 @@ dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { - return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf, - window, attrib_list); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + _EGLSurface *surf; + + surf = dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf, + window, attrib_list); + + /* When we first create the DRI2 drawable, its swap interval on the server + * side is 1. + */ + surf->SwapInterval = 1; + + /* Override that with a driconf-set value. */ + drv->API.SwapInterval(drv, disp, surf, dri2_dpy->default_swap_interval); + + return surf; } static _EGLSurface * @@ -794,8 +813,6 @@ dri2_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); - /* XXX Check vblank_mode here? */ - if (interval > surf->Config->MaxSwapInterval) interval = surf->Config->MaxSwapInterval; else if (interval < surf->Config->MinSwapInterval) @@ -1017,6 +1034,51 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp) return EGL_FALSE; } +static void +dri2_setup_swap_interval(struct dri2_egl_display *dri2_dpy) +{ + GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; + int arbitrary_max_interval = 1000; + + /* default behavior for no SwapBuffers support: no vblank syncing + * either. + */ + dri2_dpy->min_swap_interval = 0; + dri2_dpy->max_swap_interval = 0; + + if (!dri2_dpy->swap_available) + return; + + /* If we do have swapbuffers, then we can support pretty much any swap + * interval, but we allow driconf to override applications. + */ + if (dri2_dpy->config) + dri2_dpy->config->configQueryi(dri2_dpy->dri_screen, + "vblank_mode", &vblank_mode); + switch (vblank_mode) { + case DRI_CONF_VBLANK_NEVER: + dri2_dpy->min_swap_interval = 0; + dri2_dpy->max_swap_interval = 0; + dri2_dpy->default_swap_interval = 0; + break; + case DRI_CONF_VBLANK_ALWAYS_SYNC: + dri2_dpy->min_swap_interval = 1; + dri2_dpy->max_swap_interval = arbitrary_max_interval; + dri2_dpy->default_swap_interval = 1; + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_0: + dri2_dpy->min_swap_interval = 0; + dri2_dpy->max_swap_interval = arbitrary_max_interval; + dri2_dpy->default_swap_interval = 0; + break; + default: + case DRI_CONF_VBLANK_DEF_INTERVAL_1: + dri2_dpy->min_swap_interval = 0; + dri2_dpy->max_swap_interval = arbitrary_max_interval; + dri2_dpy->default_swap_interval = 1; + break; + } +} static EGLBoolean dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) @@ -1124,6 +1186,8 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) disp->VersionMajor = 1; disp->VersionMinor = 4; + dri2_setup_swap_interval(dri2_dpy); + return EGL_TRUE; cleanup_configs: