summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@vmware.com>2009-02-16 11:39:34 +0000
committerKeith Packard <keithp@keithp.com>2009-07-06 13:23:29 -0700
commit6f82ca0f8bfc074474407cb5ffe782c3c128f838 (patch)
tree1f95af71e1e9bcf351875c34c28add13be1f76f7
parentd478bc948838d11b3abcf6d2cdd3a00dccb344c4 (diff)
dri2: support glXWaitGL & glXWaitX by copying fake front to front and
vice-versa. (cherry picked from commit 2a8b8077d8f6001eb57deba60e1009fc99c28668) Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--glx/glxcmds.c39
-rw-r--r--glx/glxdrawable.h2
-rw-r--r--glx/glxdri.c2
-rw-r--r--glx/glxdri2.c35
4 files changed, 67 insertions, 11 deletions
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 71f15442a..ff8b126be 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -748,29 +748,46 @@ 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 (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc)
+ return __glXError(GLXBadContextTag);
- if (!__glXForceCurrent(cl, req->contextTag, &error)) {
- return error;
+ 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 (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc)
+ return __glXError(GLXBadContextTag);
- if (!__glXForceCurrent(cl, req->contextTag, &error)) {
- return error;
+ 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 4f61f8b97..f5a040359 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 8d614d08a..64606ab5a 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -706,6 +706,8 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
private->base.destroy = __glXDRIdrawableDestroy;
private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+ private->base.waitX = NULL;
+ private->base.waitGL = NULL;
__glXenterServer(GL_FALSE);
retval = DRICreateDrawable(screen->pScreen, serverClient,
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 836fea4d8..146ea828f 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);