Module: Mesa Branch: gallium-mesa-7.4 Commit: a5ba956a1ac731c841b73397d7ccc230c819d119 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a5ba956a1ac731c841b73397d7ccc230c819d119
Author: Alan Hourihane <[email protected]> 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 _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
