DRI2: add SwapInterval support
authorJesse Barnes <jbarnes@jbarnes-desktop.localdomain>
Tue, 10 Nov 2009 21:28:01 +0000 (13:28 -0800)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 8 Jan 2010 17:33:32 +0000 (12:33 -0500)
Add support for the DRI2SwapInterval protocol request.  This allows
direct rendered clients to control their swap interval per the
SGI_swap_control extension.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
src/glx/x11/dri2.c
src/glx/x11/dri2.h
src/glx/x11/dri2_glx.c
src/glx/x11/dri_common.c
src/glx/x11/glxclient.h
src/glx/x11/glxcmds.c

index 922edbdcf52c3e144208c7e94812ef97638127f7..9ce633c40d486b60298e023e3a9d161ea26cfab0 100644 (file)
@@ -537,4 +537,21 @@ Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
     return True;
 }
 
+void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2SwapIntervalReq *req;
+
+    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+    LockDisplay(dpy);
+    GetReq(DRI2SwapInterval, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2SwapInterval;
+    req->drawable = drawable;
+    req->interval = interval;
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
 #endif /* GLX_DIRECT_RENDERING */
index ae6030842cb8d47e8f898cd0c24038d3856b7213..114e9f8f965824dddefbc50f41ebcb4896761189 100644 (file)
@@ -100,4 +100,7 @@ extern Bool
 DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
            CARD64 *msc, CARD64 *sbc);
 
+extern void
+DRI2SwapInterval(Display *dpy, XID drawable, int interval);
+
 #endif
index 86bfe46a855386f7d0df1c6d094df14b3719b9c5..83149062f3158e18bd2de3a3fcbae1f6a6f3e063 100644 (file)
@@ -47,6 +47,7 @@
 #include "xf86drm.h"
 #include "dri2.h"
 #include "dri_common.h"
+#include "../../mesa/drivers/dri/common/dri_util.h"
 
 #undef DRI2_MINOR
 #define DRI2_MINOR 1
@@ -83,6 +84,7 @@ struct __GLXDRIdrawablePrivateRec
    int width, height;
    int have_back;
    int have_fake_front;
+   int swap_interval;
 };
 
 static void dri2WaitX(__GLXDRIdrawable * pdraw);
@@ -438,6 +440,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
    return pdraw->buffers;
 }
 
+static void
+dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
+{
+   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+
+   DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval);
+   priv->swap_interval = interval;
+}
+
+static unsigned int
+dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
+{
+   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+
+  return priv->swap_interval;
+}
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
    {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
    dri2GetBuffers,
@@ -559,6 +578,8 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
    psp->getDrawableMSC = dri2DrawableGetMSC;
    psp->waitForMSC = dri2WaitForMSC;
    psp->waitForSBC = dri2WaitForSBC;
+   psp->setSwapInterval = dri2SetSwapInterval;
+   psp->getSwapInterval = dri2GetSwapInterval;
 
    /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
     * available.*/
index a94c752194a9f0208bf366ea0b0749a62a02f707..d1b77f308ddd42e1d99630fe2ba75366ba137392 100644 (file)
@@ -390,12 +390,9 @@ dri2BindExtensions(__GLXscreenConfigs *psc)
       }
 #endif
 
-#ifdef __DRI2_MEDIA_STREAM_COUNTER
-      if (strcmp(extensions[i]->name, __DRI2_MEDIA_STREAM_COUNTER) == 0) {
-        psc->msc = (__DRI2mediaStreamCounterExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
-      }
-#endif
+      __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
+      __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
+      __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
 
 #ifdef __DRI2_FLUSH
       if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
index 2b835a0a9ca0417d292d38f9c5efca952e59f352..ded4f5a434a189dc650e83d38f4c754ff490470f 100644 (file)
@@ -148,6 +148,8 @@ struct __GLXDRIscreenRec {
                     int64_t *msc, int64_t *sbc);
    int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
                     int64_t *msc, int64_t *sbc);
+   void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval);
+   int (*getSwapInterval)(__GLXDRIdrawable *pdraw);
 };
 
 struct __GLXDRIcontextRec
index c7ccaaa0b5fb7d83fd267d03f22460dc1c84b5e9..fefdd99f559a66e04fb3e85396b9c4af01493c95 100644 (file)
@@ -1884,6 +1884,7 @@ __glXSwapIntervalSGI(int interval)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
+   __GLXscreenConfigs *psc;
    Display *dpy;
    CARD32 *interval_ptr;
    CARD8 opcode;
@@ -1912,6 +1913,16 @@ __glXSwapIntervalSGI(int interval)
       }
    }
 #endif
+   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+
+   if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) {
+      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+                                                 gc->currentDrawable,
+                                                 NULL);
+      psc->driScreen->setSwapInterval(pdraw, interval);
+      return 0;
+   }
+
    dpy = gc->currentDpy;
    opcode = __glXSetupForCommand(dpy);
    if (!opcode) {
@@ -1943,13 +1954,13 @@ __glXSwapIntervalSGI(int interval)
 static int
 __glXSwapIntervalMESA(unsigned int interval)
 {
-#ifdef __DRI_SWAP_CONTROL
    GLXContext gc = __glXGetCurrentContext();
 
    if (interval < 0) {
       return GLX_BAD_VALUE;
    }
 
+#ifdef __DRI_SWAP_CONTROL
    if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
                                                           gc->screen);
@@ -1963,10 +1974,20 @@ __glXSwapIntervalMESA(unsigned int interval)
          }
       }
    }
-#else
-   (void) interval;
 #endif
 
+   if (gc != NULL && gc->driContext) {
+      __GLXscreenConfigs *psc;
+
+      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+      if (psc->driScreen && psc->driScreen->setSwapInterval) {
+         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+                                                    gc->currentDrawable, NULL);
+        psc->driScreen->setSwapInterval(pdraw, interval);
+        return 0;
+      }
+   }
+
    return GLX_BAD_CONTEXT;
 }
 
@@ -1990,6 +2011,16 @@ __glXGetSwapIntervalMESA(void)
       }
    }
 #endif
+   if (gc != NULL && gc->driContext) {
+      __GLXscreenConfigs *psc;
+
+      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+      if (psc->driScreen && psc->driScreen->getSwapInterval) {
+         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+                                                    gc->currentDrawable, NULL);
+        return psc->driScreen->getSwapInterval(pdraw);
+      }
+   }
 
    return 0;
 }