summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@vmware.com>2009-02-16 11:44:40 +0000
committerAlan Hourihane <alanh@vmware.com>2009-02-16 11:47:05 +0000
commit63b51b5cf17ddde09b72a2811296f37b9a4c5ad2 (patch)
treeac07afe3c9362241940ce2c901d24a7155893479
parent18f20b70b15f5daed28eb9f4fce1eccd46cf82d3 (diff)
dri2: support glXWaitX & glXWaitGL by using fake front buffer.
-rw-r--r--src/glx/x11/dri2_glx.c59
-rw-r--r--src/glx/x11/dri_glx.c2
-rw-r--r--src/glx/x11/glxclient.h2
-rw-r--r--src/glx/x11/glxcmds.c24
4 files changed, 81 insertions, 6 deletions
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index b878f05dda..776a14f614 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,
@@ -196,6 +199,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;
@@ -214,6 +221,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 */
@@ -261,6 +309,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. */
@@ -270,6 +321,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);
@@ -366,6 +423,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 44724d2c7d..3089aa1728 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 9332eb64d3..3e70759a6c 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 c68b6ac4ef..fc0e593cb3 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