From 2a8b8077d8f6001eb57deba60e1009fc99c28668 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Mon, 16 Feb 2009 11:39:34 +0000 Subject: dri2: support glXWaitGL & glXWaitX by copying fake front to front and vice-versa. --- glx/glxcmds.c | 39 ++++++++++++++++++++++++++++----------- glx/glxdrawable.h | 2 ++ glx/glxdri.c | 2 ++ glx/glxdri2.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) (limited to 'glx') diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 33954ee64..8b6dfbc84 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -760,29 +760,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 45000bfb7..259b11e17 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 fb9578243..b3b3e279b 100644 --- a/glx/glxdri.c +++ b/glx/glxdri.c @@ -704,6 +704,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 87c39595a..66e08895c 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -139,6 +139,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, ®ion, &box, 0); + + DRI2CopyRegion(drawable->pDraw, ®ion, + 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, ®ion, &box, 0); + + DRI2CopyRegion(drawable->pDraw, ®ion, + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); +} static int __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) @@ -337,6 +370,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); -- cgit v1.2.3