Mesa (master): egl: Add support for driconf control of swapinterval.

Eric Anholt anholt at kemper.freedesktop.org
Tue Oct 9 21:34:06 UTC 2012


Module: Mesa
Branch: master
Commit: 7e9bd2b2ed35a440a96362417100a7e43715d606
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7e9bd2b2ed35a440a96362417100a7e43715d606

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 25 14:05:30 2012 -0700

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 at linux.intel.com>

---

 src/egl/drivers/dri2/egl_dri2.c     |    9 ++--
 src/egl/drivers/dri2/egl_dri2.h     |    4 ++
 src/egl/drivers/dri2/platform_x11.c |   72 +++++++++++++++++++++++++++++++++--
 3 files changed, 77 insertions(+), 8 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 4b58c35..ae082f6 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 81c1354..85c0745 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 a56fc78..4757ccf 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:




More information about the mesa-commit mailing list