diff options
author | Kristian Høgsberg <krh@redhat.com> | 2006-07-06 21:22:34 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2006-07-06 21:25:29 -0400 |
commit | 5416f90e9c939027005fc01fa3ce3df56919ae0d (patch) | |
tree | dabed6a7c920e6784530da99220833841ebbf38d /GL/glx | |
parent | b84374b2917a91a7732e780ffab6a29c807a3ecc (diff) |
Implement GLX_MESA_copy_sub_buffer.
Diffstat (limited to 'GL/glx')
-rw-r--r-- | GL/glx/glxcmds.c | 40 | ||||
-rw-r--r-- | GL/glx/glxdrawable.h | 2 | ||||
-rw-r--r-- | GL/glx/glxdri.c | 48 |
3 files changed, 84 insertions, 6 deletions
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 3ec796c0f..e2aaf3a71 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -1605,8 +1605,13 @@ int __glXReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) { xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXContextTag tag = req->contextTag; + __GLXcontext *glxc = NULL; + __GLXdrawable *pGlxDraw; + __GLXpixmap *pPixmap; ClientPtr client = cl->client; GLXDrawable drawId; + int error; int x, y, width, height; (void) client; @@ -1620,7 +1625,40 @@ int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) width = *((INT32 *) (pc + 12)); height = *((INT32 *) (pc + 16)); - return BadRequest; + if (tag) { + glxc = __glXLookupContextByTag(cl, tag); + if (!glxc) { + return __glXError(GLXBadContextTag); + } + /* + ** The calling thread is swapping its current drawable. In this case, + ** glxSwapBuffers is in both GL and X streams, in terms of + ** sequentiality. + */ + if (__glXForceCurrent(cl, tag, &error)) { + /* + ** Do whatever is needed to make sure that all preceding requests + ** in both streams are completed before the swap is executed. + */ + CALL_Finish( GET_DISPATCH(), () ); + __GLX_NOTE_FLUSHED_CMDS(glxc); + } else { + return error; + } + } + + error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client); + if (error != Success) + return error; + + if (pGlxDraw == NULL || + pGlxDraw->type != DRAWABLE_WINDOW || + pGlxDraw->copySubBuffer == NULL) + return __glXError(GLXBadDrawable); + + (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height); + + return Success; } /* diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h index 4514e263e..e6d2cd686 100644 --- a/GL/glx/glxdrawable.h +++ b/GL/glx/glxdrawable.h @@ -58,6 +58,8 @@ struct __GLXdrawable { void (*destroy)(__GLXdrawable *private); GLboolean (*resize)(__GLXdrawable *private); GLboolean (*swapBuffers)(__GLXdrawable *); + void (*copySubBuffer)(__GLXdrawable *drawable, + int x, int y, int w, int h); /* ** list of drawable private structs diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 423922966..6a1055439 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -112,12 +112,28 @@ struct __GLXDRIdrawable { * months ago. :( * 20050727 - Gut all the old interfaces. This breaks compatability with * any DRI driver built to any previous version. + * 20060314 - Added support for GLX_MESA_copy_sub_buffer. */ + #define INTERNAL_VERSION 20050727 static const char CREATE_NEW_SCREEN_FUNC[] = "__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION); +/* The DRI driver entry point version wasn't bumped when the + * copySubBuffer functionality was added to the DRI drivers, but the + * functionality is still conditional on the value of the + * internal_api_version passed to __driCreateNewScreen. However, the + * screen constructor doesn't fail for a DRI driver that's older than + * the passed in version number, so there's no way we can know for + * sure that we can actually use the copySubBuffer functionality. But + * since the earliest (and at this point only) released mesa version + * (6.5) that uses the 20050727 entry point does have copySubBuffer, + * we'll just settle for that. We still have to pass in a higher to + * the screen constructor to enable the functionality. + */ +#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314 + static void __glXDRIleaveServer(void) { @@ -178,6 +194,27 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate) } static void +__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, + int x, int y, int w, int h) +{ + __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + __GLXDRIscreen *screen; + + /* FIXME: We're jumping through hoops here to get the DRIdrawable + * which the dri driver tries to keep to it self... cf. FIXME in + * createDrawable. */ + + screen = (__GLXDRIscreen *) __glXgetActiveScreen(private->base.pDraw->pScreen->myNum); + private->driDrawable = (screen->driScreen.getDrawable)(NULL, + private->base.drawId, + screen->driScreen.private); + + (*private->driDrawable->copySubBuffer)(NULL, + private->driDrawable->private, + x, y, w, h); +} + +static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; @@ -474,10 +511,11 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, return NULL; } - private->base.destroy = __glXDRIdrawableDestroy; - private->base.resize = __glXDRIdrawableResize; - private->base.swapBuffers = __glXDRIdrawableSwapBuffers; - + private->base.destroy = __glXDRIdrawableDestroy; + private->base.resize = __glXDRIdrawableResize; + private->base.swapBuffers = __glXDRIdrawableSwapBuffers; + private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; + #if 0 /* FIXME: It would only be natural that we called * driScreen->createNewDrawable here but the DRI drivers manage @@ -770,7 +808,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __DRIframebuffer framebuffer; int fd = -1; int status; - int api_ver = INTERNAL_VERSION; + int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION; drm_magic_t magic; drmVersionPtr version; char *driverName; |