[Mesa-dev] [PATCH] dri2: add vblank_mode support

Jesse Barnes jbarnes at virtuousgeek.org
Thu Apr 22 12:24:12 PDT 2010


On Thu, 22 Apr 2010 11:28:55 -0700
Jesse Barnes <jbarnes at virtuousgeek.org> wrote:

> On Tue, 20 Apr 2010 11:35:11 -0700
> Jesse Barnes <jbarnes at virtuousgeek.org> wrote:
> 
> > This patch adds vblank_mode support to DRI2, for direct rendered
> > clients only.  It does this by adding some DRI options parsing at DRI2
> > screen creation time, and some checking for the current vblank mode to
> > dri2_glx.c.
> > 
> > Fixes fdo bug #27656.
> 
> This one fixes the layering violations, and makes things more generic.
> 
> any thoughts?

Third and final offer. :)

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index fa9b7c4..a952a1d 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -812,4 +812,18 @@ struct __DRIimageLookupExtensionRec {
 				  void *loaderPrivate);
 };
 
+/**
+ * This extension allows for common DRI2 options
+ */
+#define __DRI2_CONFIG_QUERY "DRI_CONFIG_QUERY"
+#define __DRI2_CONFIG_QUERY_VERSION 1
+
+typedef struct __DRI2configQueryExtensionRec __DRI2configQueryExtension;
+struct __DRI2configQueryExtensionRec {
+   __DRIextension base;
+
+   int (*configQueryb)(__DRIscreen *screen, const char *var, GLboolean *val);
+   int (*configQueryi)(__DRIscreen *screen, const char *var, GLint *val);
+   int (*configQueryf)(__DRIscreen *screen, const char *var, GLfloat *val);
+};
 #endif
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 3a53ce9..560615a 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -48,6 +48,7 @@
 #include "dri2.h"
 #include "dri_common.h"
 #include "../../mesa/drivers/dri/common/dri_util.h"
+#include "../../mesa/drivers/dri/common/xmlpool/options.h"
 
 #undef DRI2_MINOR
 #define DRI2_MINOR 1
@@ -177,6 +178,7 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
    __GLXdisplayPrivate *dpyPriv;
    __GLXDRIdisplayPrivate *pdp;
+   GLuint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
 
    pdraw = Xmalloc(sizeof(*pdraw));
    if (!pdraw)
@@ -189,6 +191,21 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
    pdraw->bufferCount = 0;
    pdraw->swap_interval = 1;
 
+   if (psc->config)
+      psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode);
+
+   switch (vblank_mode) {
+   case DRI_CONF_VBLANK_NEVER:
+   case DRI_CONF_VBLANK_DEF_INTERVAL_0:
+      pdraw->swap_interval = 0;
+      break;
+   case DRI_CONF_VBLANK_DEF_INTERVAL_1:
+   case DRI_CONF_VBLANK_ALWAYS_SYNC:
+   default:
+      pdraw->swap_interval = 1;
+      break;
+   }
+
    DRI2CreateDrawable(psc->dpy, xDrawable);
 
    dpyPriv = __glXInitialize(psc->dpy);
@@ -474,7 +491,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
 static void
 dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
 {
+   __GLXscreenConfigs *psc = pdraw->psc;
    __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
+
+   if (psc->config)
+      psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode);
+
+   switch (vblank_mode) {
+   case DRI_CONF_VBLANK_NEVER:
+      return;
+   case DRI_CONF_VBLANK_ALWAYS_SYNC:
+      if (interval <= 0)
+	 return;
+      break;
+   default:
+      break;
+   }
 
    DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval);
    priv->swap_interval = interval;
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index e403416..dbc6082 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -403,6 +403,11 @@ dri2BindExtensions(__GLXscreenConfigs *psc)
 	 /* internal driver extension, no GL extension exposed */
       }
 #endif
+
+#ifdef __DRI2_CONFIG_QUERY
+      if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0))
+	 psc->config = (__DRI2configQueryExtension *) extensions[i];
+#endif
    }
 }
 
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 8e5dc78..e4b2c63 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -549,6 +549,10 @@ struct __GLXscreenConfigsRec
    const __DRI2flushExtension *f;
 #endif
 
+#ifdef __DRI2_CONFIG_QUERY
+   const __DRI2configQueryExtension *config;
+#endif
+
 #endif
 
     /**
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index f1bbd38..160d291 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -31,6 +31,17 @@
 #include "dri_util.h"
 #include "drm_sarea.h"
 #include "utils.h"
+#include "vblank.h"
+#include "xmlpool.h"
+
+PUBLIC const char __dri2ConfigOptions[] =
+   DRI_CONF_BEGIN
+      DRI_CONF_SECTION_PERFORMANCE
+         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
+      DRI_CONF_SECTION_END
+   DRI_CONF_END;
+
+static const uint __dri2NConfigOptions = 1;
 
 #ifndef GLX_OML_sync_control
 typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
@@ -467,6 +478,31 @@ dri2CreateNewDrawable(__DRIscreen *screen,
     return pdraw;
 }
 
+static int
+dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
+{
+   *val = driQueryOptionb(&screen->optionCache, var);
+
+   return 0;
+}
+
+static int
+dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
+{
+    *val = driQueryOptioni(&screen->optionCache, var);
+
+    return 0;
+}
+
+static int
+dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
+{
+    *val = driQueryOptionf(&screen->optionCache, var);
+
+    return 0;
+}
+
+
 static void dri_get_drawable(__DRIdrawable *pdp)
 {
     pdp->refcount++;
@@ -739,6 +775,7 @@ dri2CreateNewScreen(int scrn, int fd,
     static const __DRIextension *emptyExtensionList[] = { NULL };
     __DRIscreen *psp;
     drmVersionPtr version;
+    driOptionCache options;
 
     if (driDriverAPI.InitScreen2 == NULL)
         return NULL;
@@ -771,6 +808,9 @@ dri2CreateNewScreen(int scrn, int fd,
 
     psp->DriverAPI = driDriverAPI;
 
+    driParseOptionInfo(&options, __dri2ConfigOptions, __dri2NConfigOptions);
+    driParseConfigFiles(&psp->optionCache, &options, psp->myNum, "dri2");
+
     return psp;
 }
 
@@ -813,6 +853,13 @@ const __DRIdri2Extension driDRI2Extension = {
     dri2CreateNewContext,
 };
 
+const __DRI2configQueryExtension dri2ConfigQueryExtension = {
+   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
+   dri2ConfigQueryb,
+   dri2ConfigQueryi,
+   dri2ConfigQueryf,
+};
+
 static int
 driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
 {
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 038a816..0fe6f1e 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -51,6 +51,7 @@
 #include <drm.h>
 #include <drm_sarea.h>
 #include <xf86drm.h>
+#include "xmlconfig.h"
 #include "main/glheader.h"
 #include "GL/internal/glcore.h"
 #include "GL/internal/dri_interface.h"
@@ -70,6 +71,7 @@ extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
 extern const __DRIswapControlExtension driSwapControlExtension;
 extern const __DRIframeTrackingExtension driFrameTrackingExtension;
 extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
+extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
 
 /**
  * Used by DRI_VALIDATE_DRAWABLE_INFO
@@ -527,6 +529,8 @@ struct __DRIscreenRec {
 
     /* The lock actually in use, old sarea or DRI2 */
     drmLock *lock;
+
+    driOptionCache optionCache;
 };
 
 extern void
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 5e3f408..ea739a4 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -225,6 +225,7 @@ static const __DRIextension *intelScreenExtensions[] = {
     &intelTexBufferExtension.base,
     &intelFlushExtension.base,
     &intelImageExtension.base,
+    &dri2ConfigQueryExtension.base,
     NULL
 };
 
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 18db12f..78987f6 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -236,6 +236,7 @@ static const struct __DRItexBufferExtensionRec nouveau_texbuffer_extension = {
 static const __DRIextension *nouveau_screen_extensions[] = {
     &nouveau_flush_extension.base,
     &nouveau_texbuffer_extension.base,
+    &dri2ConfigQueryExtension.base,
     NULL
 };
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index fca0f81..f8dc814 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -1235,6 +1235,8 @@ radeonCreateScreen( __DRIscreen *sPriv )
    screen->extensions[i++] = &r600texOffsetExtension.base;
 #endif
 
+   screen->extensions[i++] = &dri2ConfigQueryExtension.base;
+
    screen->extensions[i++] = NULL;
    sPriv->extensions = screen->extensions;
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index 5e6d432..0d7e335 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -105,7 +105,7 @@ typedef struct radeon_screen {
    /* Configuration cache with default values for all contexts */
    driOptionCache optionCache;
 
-   const __DRIextension *extensions[16];
+   const __DRIextension *extensions[17];
 
    int num_gb_pipes;
    int num_z_pipes;


More information about the mesa-dev mailing list