[PATCH] dri2: support glXWaitGL & glXWaitX by copying fake front to front and vice-versa.

Hamilton, Howard S howard.s.hamilton at intel.com
Fri Jul 3 14:59:25 PDT 2009


This is a port to the server-1.6-branch from master branch 20090216, by Alan Hourihane.  This change is needed to enable glxpixmap with DRI2

Signed-off-by: Howard S. Hamilton <howard.s.hamilton at intel.com>
---
 glx/glxcmds.c     |   40 +++++++++++++++++++++++++++++-----------
 glx/glxdrawable.h |    2 ++
 glx/glxdri.c      |    3 +++
 glx/glxdri2.c     |   35 +++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 71f1544..4dbdadd 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -748,29 +748,47 @@ int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc)
 int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
+    GLXContextTag tag = req->contextTag;
+     __GLXcontext *glxc = NULL;
     int error;
-
-    if (!__glXForceCurrent(cl, req->contextTag, &error)) {
-       return error;
+
+    if (tag) {
+        glxc = __glXLookupContextByTag(cl, tag);
+        if (!glxc)
+            return __glXError(GLXBadContextTag);
+
+        if (!__glXForceCurrent(cl, req->contextTag, &error))
+            return error;
+
+        CALL_Finish( GET_DISPATCH(), () );
     }
     CALL_Finish( GET_DISPATCH(), () );
+
+    if (glxc && glxc->drawPriv->waitGL)
+        (*glxc->drawPriv->waitGL)(glxc->drawPriv);
+
     return Success;
 }

 int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
+    GLXContextTag tag = req->contextTag;
+    __GLXcontext *glxc = NULL;
     int error;

-    if (!__glXForceCurrent(cl, req->contextTag, &error)) {
-       return error;
+    if (tag) {
+        glxc = __glXLookupContextByTag(cl, tag);
+        if (!glxc)
+            return __glXError(GLXBadContextTag);
+
+        if (!__glXForceCurrent(cl, req->contextTag, &error))
+            return error;
     }
-    /*
-    ** In a multithreaded server that had separate X and GL threads, we would
-    ** have to wait for the X thread to finish before returning.  As it stands,
-    ** this sample implementation only supports singlethreaded servers, and
-    ** nothing needs to be done here.
-    */
+
+    if (glxc && glxc->drawPriv->waitGL)
+        (*glxc->drawPriv->waitGL)(glxc->drawPriv);
+
     return Success;
 }

diff --git a/glx/glxdrawable.h b/glx/glxdrawable.h
index 4f61f8b..5a7094a 100644
--- a/glx/glxdrawable.h
+++ b/glx/glxdrawable.h
@@ -49,6 +49,8 @@ struct __GLXdrawable {
     GLboolean (*swapBuffers)(__GLXdrawable *);
     void      (*copySubBuffer)(__GLXdrawable *drawable,
                               int x, int y, int w, int h);
+    void (*waitX)(__GLXdrawable *);
+    void (*waitGL)(__GLXdrawable *);

     DrawablePtr pDraw;
     XID drawId;
diff --git a/glx/glxdri.c b/glx/glxdri.c
index 8d614d0..3c53afe 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -707,6 +707,9 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
     private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;

+    private->base.waitX = NULL;
+    private->base.waitGL = NULL;
+
     __glXenterServer(GL_FALSE);
     retval = DRICreateDrawable(screen->pScreen, serverClient,
                               pDraw, &hwDrawable);
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 836fea4..aa3862c 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -143,6 +143,39 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
     return TRUE;
 }

+static void
+__glXDRIdrawableWaitX(__GLXdrawable *drawable)
+{
+   __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+   BoxRec box;
+   RegionRec region;
+
+   box.x1 = 0;
+   box.y1 = 0;
+   box.x2 = private->width;
+   box.y2 = private->height;
+   REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+
+   DRI2CopyRegion(drawable->pDraw, &region,
+                 DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+}
+
+static void
+__glXDRIdrawableWaitGL(__GLXdrawable *drawable)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    BoxRec box;
+    RegionRec region;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = private->width;
+    box.y2 = private->height;
+    REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+
+    DRI2CopyRegion(drawable->pDraw, &region,
+                  DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+}

 static int
 __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
@@ -351,6 +384,8 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     private->base.destroy       = __glXDRIdrawableDestroy;
     private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
     private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+    private->base.waitGL = __glXDRIdrawableWaitGL;
+    private->base.waitX = __glXDRIdrawableWaitX;

     if (DRI2CreateDrawable(pDraw)) {
            xfree(private);
--
1.6.2.5



More information about the xorg mailing list