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) { if (double_buffer) {
surface_type &= ~EGL_PIXMAP_BIT; surface_type &= ~EGL_PIXMAP_BIT;
if (dri2_dpy->swap_available) { conf->base.MinSwapInterval = dri2_dpy->min_swap_interval;
conf->base.MinSwapInterval = 0; conf->base.MaxSwapInterval = dri2_dpy->max_swap_interval;
conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */
}
} }
conf->base.SurfaceType |= surface_type; conf->base.SurfaceType |= surface_type;
@ -533,6 +531,9 @@ dri2_create_screen(_EGLDisplay *disp)
if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) {
dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i];
} }
if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) {
dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i];
}
} }
} else { } else {
assert(dri2_dpy->swrast); assert(dri2_dpy->swrast);

View File

@ -100,11 +100,15 @@ struct dri2_egl_display
__DRItexBufferExtension *tex_buffer; __DRItexBufferExtension *tex_buffer;
__DRIimageExtension *image; __DRIimageExtension *image;
__DRIrobustnessExtension *robustness; __DRIrobustnessExtension *robustness;
__DRI2configQueryExtension *config;
int fd; int fd;
int own_device; int own_device;
int swap_available; int swap_available;
int invalidate_available; int invalidate_available;
int min_swap_interval;
int max_swap_interval;
int default_swap_interval;
#ifdef HAVE_DRM_PLATFORM #ifdef HAVE_DRM_PLATFORM
struct gbm_dri_device *gbm_dri; struct gbm_dri_device *gbm_dri;
#endif #endif

View File

@ -39,6 +39,12 @@
#include "egl_dri2.h" #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 static void
swrastCreateDrawable(struct dri2_egl_display * dri2_dpy, swrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
struct dri2_egl_surface * dri2_surf, struct dri2_egl_surface * dri2_surf,
@ -273,8 +279,21 @@ dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
_EGLConfig *conf, EGLNativeWindowType window, _EGLConfig *conf, EGLNativeWindowType window,
const EGLint *attrib_list) const EGLint *attrib_list)
{ {
return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf, struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
window, attrib_list); _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 * 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_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
/* XXX Check vblank_mode here? */
if (interval > surf->Config->MaxSwapInterval) if (interval > surf->Config->MaxSwapInterval)
interval = surf->Config->MaxSwapInterval; interval = surf->Config->MaxSwapInterval;
else if (interval < surf->Config->MinSwapInterval) else if (interval < surf->Config->MinSwapInterval)
@ -1017,6 +1034,51 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
return EGL_FALSE; 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 static EGLBoolean
dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
@ -1124,6 +1186,8 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
disp->VersionMajor = 1; disp->VersionMajor = 1;
disp->VersionMinor = 4; disp->VersionMinor = 4;
dri2_setup_swap_interval(dri2_dpy);
return EGL_TRUE; return EGL_TRUE;
cleanup_configs: cleanup_configs: