Mesa (gallium-mesa-7.4): dri2: support glXWaitX & glXWaitGL by using fake front buffer.

Alan Hourihane alanh at kemper.freedesktop.org
Mon Feb 16 11:45:13 UTC 2009


Module: Mesa
Branch: gallium-mesa-7.4
Commit: a5ba956a1ac731c841b73397d7ccc230c819d119
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a5ba956a1ac731c841b73397d7ccc230c819d119

Author: Alan Hourihane <alanh at vmware.com>
Date:   Mon Feb 16 11:44:40 2009 +0000

dri2: support glXWaitX & glXWaitGL by using fake front buffer.

---

 src/glx/x11/dri2_glx.c  |   59 +++++++++++++++++++++++++++++++++++++++++++++++
 src/glx/x11/dri_glx.c   |    2 +
 src/glx/x11/glxclient.h |    2 +
 src/glx/x11/glxcmds.c   |   24 ++++++++++++++----
 4 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index b4613a2..639aa19 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -77,6 +77,9 @@ struct __GLXDRIdrawablePrivateRec {
     int bufferCount;
     int width, height;
     unsigned long configureSeqno;
+    int have_back;
+    int have_front;
+    int have_fake_front;
 };
 
 static void dri2DestroyContext(__GLXDRIcontext *context,
@@ -195,6 +198,10 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
     XRectangle xrect;
     XserverRegion region;
 
+    /* Check we have the right attachments */
+    if (!(priv->have_front && priv->have_back))
+    	return;
+
     xrect.x = x;
     xrect.y = priv->height - y - height;
     xrect.width = width;
@@ -213,6 +220,47 @@ static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
     dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
 }
 
+static void dri2WaitX(__GLXDRIdrawable *pdraw)
+{
+    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+    XRectangle xrect;
+    XserverRegion region;
+
+    /* Check we have the right attachments */
+    if (!(priv->have_fake_front && priv->have_front))
+    	return;
+
+    xrect.x = 0;
+    xrect.y = 0;
+    xrect.width = priv->width;
+    xrect.height = priv->height;
+
+    region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+    DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
+		   DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+    XFixesDestroyRegion(pdraw->psc->dpy, region);
+}
+
+static void dri2WaitGL(__GLXDRIdrawable *pdraw)
+{
+    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+    XRectangle xrect;
+    XserverRegion region;
+
+    if (!(priv->have_fake_front && priv->have_front))
+    	return;
+
+    xrect.x = 0;
+    xrect.y = 0;
+    xrect.width = priv->width;
+    xrect.height = priv->height;
+
+    region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+    DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
+		   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+    XFixesDestroyRegion(pdraw->psc->dpy, region);
+}
+
 static void dri2DestroyScreen(__GLXscreenConfigs *psc)
 {
     /* Free the direct rendering per screen data */
@@ -260,6 +308,9 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     pdraw->width = *width;
     pdraw->height = *height;
     pdraw->bufferCount = *out_count;
+    pdraw->have_front = 0;
+    pdraw->have_fake_front = 0;
+    pdraw->have_back = 0;
 
     /* This assumes the DRI2 buffer attachment tokens matches the
      * __DRIbuffer tokens. */
@@ -269,6 +320,12 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 	pdraw->buffers[i].pitch = buffers[i].pitch;
 	pdraw->buffers[i].cpp = buffers[i].cpp;
 	pdraw->buffers[i].flags = buffers[i].flags;
+	if (pdraw->buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
+	    pdraw->have_front = 1;
+	if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
+	    pdraw->have_fake_front = 1;
+	if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
+	    pdraw->have_back = 1;
     }
 
     Xfree(buffers);
@@ -359,6 +416,8 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
     psp->createContext = dri2CreateContext;
     psp->createDrawable = dri2CreateDrawable;
     psp->swapBuffers = dri2SwapBuffers;
+    psp->waitGL = dri2WaitGL;
+    psp->waitX = dri2WaitX;
 
     /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
      * available.*/
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 44724d2..3089aa1 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -655,6 +655,8 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
     psp->createContext = driCreateContext;
     psp->createDrawable = driCreateDrawable;
     psp->swapBuffers = driSwapBuffers;
+    psp->waitX = NULL;
+    psp->waitGL = NULL;
 
     return psp;
 }
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 9332eb6..3e70759 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -139,6 +139,8 @@ struct __GLXDRIscreenRec {
     void (*swapBuffers)(__GLXDRIdrawable *pdraw);
     void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
 			  int x, int y, int width, int height);
+    void (*waitX)(__GLXDRIdrawable *pdraw);
+    void (*waitGL)(__GLXDRIdrawable *pdraw);
 };
 
 struct __GLXDRIcontextRec {
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index c68b6ac..fc0e593 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -611,11 +611,15 @@ PUBLIC void glXWaitGL(void)
 
 #ifdef GLX_DIRECT_RENDERING
     if (gc->driContext) {
-/* This bit of ugliness unwraps the glFinish function */
-#ifdef glFinish
-#undef glFinish
-#endif
-	glFinish();
+    	int screen;
+    	__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
+
+    	if ( pdraw != NULL ) {
+	    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+	    glFlush();
+	    if (psc->driScreen->waitGL != NULL)
+	    	(*psc->driScreen->waitGL)(pdraw);
+	}
 	return;
     }
 #endif
@@ -647,7 +651,15 @@ PUBLIC void glXWaitX(void)
 
 #ifdef GLX_DIRECT_RENDERING
     if (gc->driContext) {
-	XSync(dpy, False);
+    	int screen;
+    	__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
+
+    	if ( pdraw != NULL ) {
+	    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+	    if (psc->driScreen->waitX != NULL)
+	    	(*psc->driScreen->waitX)(pdraw);
+	} else
+	    XSync(dpy, False);
 	return;
     }
 #endif




More information about the mesa-commit mailing list