egl: Add support for driconf control of swapinterval.

This behavior mostly matches glx_dri2.  It's slightly complicated in
comparison because EGL exposes the implementation limits in the EGL config.

Note that platform_x11 was the only one setting swap_available, so the move of
the MaxSwapInterval into it is appropriate.

Acked-by: Chad Versace <chad.versace@linux.intel.com>
This commit is contained in:
Eric Anholt 2012-09-25 14:05:30 -07:00
parent 8c472b8f6a
commit 7e9bd2b2ed
3 changed files with 77 additions and 8 deletions

View File

@ -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);

View File

@ -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

View File

@ -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: