--- ./GL/glx/glxdrawable.h.mesa-copy-sub-buffer 2006-07-06 21:40:41.000000000 -0400 +++ ./GL/glx/glxdrawable.h 2006-07-06 21:56:33.000000000 -0400 @@ -58,6 +58,8 @@ 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 --- ./GL/glx/glxcmds.c.mesa-copy-sub-buffer 2006-07-06 21:40:41.000000000 -0400 +++ ./GL/glx/glxcmds.c 2006-07-06 22:30:01.000000000 -0400 @@ -1331,21 +1331,14 @@ /*****************************************************************************/ -/* -** NOTE: There is no portable implementation for swap buffers as of -** this time that is of value. Consequently, this code must be -** implemented by somebody other than SGI. -*/ -int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) +static __GLXdrawable * +SyncContextGetDrawable (__GLXclientState *cl, GLXContextTag tag, + XID drawId, int *status) { ClientPtr client = cl->client; DrawablePtr pDraw; - xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; - GLXContextTag tag = req->contextTag; - XID drawId = req->drawable; __GLXpixmap *pGlxPixmap; __GLXcontext *glxc = NULL; - int error; /* ** Check that the GLX drawable is valid. @@ -1361,11 +1354,11 @@ ** Drawable is an X pixmap, which is not allowed. */ client->errorValue = drawId; - return __glXBadDrawable; + *status = __glXBadDrawable; + return NULL; } } else { - pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, - __glXPixmapRes); + pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes); if (pGlxPixmap) { /* ** Drawable is a GLX pixmap. @@ -1375,21 +1368,23 @@ ** Drawable is neither a X window nor a GLX pixmap. */ client->errorValue = drawId; - return __glXBadDrawable; + *status = __glXBadDrawable; + return NULL; } } if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) { - return __glXBadContextTag; + *status = __glXBadContextTag; + return NULL; } /* ** 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)) { + if (__glXForceCurrent(cl, tag, status)) { /* ** Do whatever is needed to make sure that all preceding requests ** in both streams are completed before the swap is executed. @@ -1397,33 +1392,53 @@ CALL_Finish( GET_DISPATCH(), () ); __GLX_NOTE_FLUSHED_CMDS(glxc); } else { - return error; + return NULL; } } + *status = Success; if (pDraw) { - __GLXdrawable *glxPriv; + __GLXdrawable *glxPriv; if (glxc) { glxPriv = __glXGetDrawable(glxc, pDraw, drawId); if (glxPriv == NULL) { - return __glXBadDrawable; + *status = __glXBadDrawable; + return NULL; } } else { glxPriv = __glXFindDrawable(drawId); if (glxPriv == NULL) { /* This is a window we've never seen before, do nothing */ - return Success; + return NULL; } } - if ((*glxPriv->swapBuffers)(glxPriv) == GL_FALSE) { - return __glXBadDrawable; - } + return glxPriv; } - return Success; + return NULL; +} + +/* +** NOTE: There is no portable implementation for swap buffers as of +** this time that is of value. Consequently, this code must be +** implemented by somebody other than SGI. +*/ +int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) +{ + xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; + GLXContextTag tag = req->contextTag; + __GLXdrawable *glxPriv; + int status; + + glxPriv = SyncContextGetDrawable (cl, tag, req->drawable, &status); + if (glxPriv && (*glxPriv->swapBuffers)(glxPriv) == GL_FALSE) { + return __glXBadDrawable; + } + + return status; } @@ -1544,6 +1559,30 @@ pGlxPixmap); } +int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXContextTag tag = req->contextTag; + __GLXdrawable *glxPriv; + GLXDrawable drawId; + int x, y, width, height; + int status; + + pc += __GLX_VENDPRIV_HDR_SIZE; + + drawId = *((CARD32 *) (pc)); + x = *((INT32 *) (pc + 4)); + y = *((INT32 *) (pc + 8)); + width = *((INT32 *) (pc + 12)); + height = *((INT32 *) (pc + 16)); + + glxPriv = SyncContextGetDrawable (cl, tag, drawId, &status); + if (glxPriv) + (*glxPriv->copySubBuffer)(glxPriv, x, y, width, height); + + return status; +} + /* ** Get drawable attributes */ @@ -2173,7 +2212,9 @@ case X_GLXvop_BindTexImageEXT: return __glXBindTexImageEXT(cl, pc); case X_GLXvop_ReleaseTexImageEXT: - return __glXReleaseTexImageEXT(cl, pc); + return __glXReleaseTexImageEXT(cl, pc); + case X_GLXvop_CopySubBufferMESA: + return __glXCopySubBufferMESA(cl, pc); } #endif --- ./GL/glx/glxdri.c.mesa-copy-sub-buffer 2006-07-06 21:40:41.000000000 -0400 +++ ./GL/glx/glxdri.c 2006-07-06 21:59:38.000000000 -0400 @@ -112,12 +112,28 @@ * 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) { @@ -177,6 +193,27 @@ return TRUE; } +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 __GLXdrawable * __glXDRIcontextCreateDrawable(__GLXcontext *context, DrawablePtr pDraw, @@ -195,10 +232,11 @@ 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 @@ -218,7 +256,6 @@ return &private->base; } - static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { @@ -770,7 +807,7 @@ __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; --- ./GL/glx/g_disptab.h.mesa-copy-sub-buffer 2006-03-11 19:11:33.000000000 -0500 +++ ./GL/glx/g_disptab.h 2006-07-06 21:56:33.000000000 -0400 @@ -48,6 +48,7 @@ extern int __glXSwapBuffers(__GLXclientState*, GLbyte*); extern int __glXBindTexImageEXT(__GLXclientState *cl, GLbyte *pc); extern int __glXReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc); +extern int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc); extern int __glXGetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc); extern int __glXUseXFont(__GLXclientState*, GLbyte*); extern int __glXCreateGLXPixmap(__GLXclientState*, GLbyte*); @@ -76,6 +77,7 @@ extern int __glXSwapSwapBuffers(__GLXclientState*, GLbyte*); extern int __glXSwapBindTexImageEXT(__GLXclientState *cl, GLbyte *pc); extern int __glXSwapReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc); +extern int __glXSwapReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc); extern int __glXSwapGetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc); extern int __glXSwapUseXFont(__GLXclientState*, GLbyte*); extern int __glXSwapCreateGLXPixmap(__GLXclientState*, GLbyte*); @@ -105,4 +107,11 @@ extern __GLXdispatchSingleProcPtr __glXSingleTable[__GLX_SINGLE_TABLE_SIZE]; extern __GLXdispatchRenderProcPtr __glXSwapRenderTable[__GLX_RENDER_TABLE_SIZE]; extern __GLXdispatchSingleProcPtr __glXSwapSingleTable[__GLX_SINGLE_TABLE_SIZE]; + +/* Copied from mesa src/glx/x11/glxcmds.c + * + * Apparently there's no standardized opcode for this extension. + */ +#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */ + #endif /* _GLX_g_disptab_h_ */ --- ./GL/glx/glxscreens.c.mesa-copy-sub-buffer 2006-03-20 15:10:29.000000000 -0500 +++ ./GL/glx/glxscreens.c 2006-07-06 21:56:33.000000000 -0400 @@ -139,6 +139,7 @@ "GLX_SGIX_swap_barrier " #endif "GLX_SGIX_fbconfig " + "GLX_MESA_copy_sub_buffer " ; __GLXscreen **__glXActiveScreens; --- ./GL/glx/glxcmdsswap.c.mesa-copy-sub-buffer 2006-04-02 22:09:15.000000000 -0400 +++ ./GL/glx/glxcmdsswap.c 2006-07-06 21:56:33.000000000 -0400 @@ -432,6 +432,31 @@ return __glXReleaseTexImageEXT(cl, (GLbyte *)pc); } +int __glXSwapCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) +{ + xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; + GLXDrawable *drawId; + int *buffer; + + (void) drawId; + (void) buffer; + + __GLX_DECLARE_SWAP_VARIABLES; + + pc += __GLX_VENDPRIV_HDR_SIZE; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->contextTag); + __GLX_SWAP_INT(pc); + __GLX_SWAP_INT(pc + 4); + __GLX_SWAP_INT(pc + 8); + __GLX_SWAP_INT(pc + 12); + __GLX_SWAP_INT(pc + 16); + + return __glXCopySubBufferMESA(cl, pc); + +} + int __glXSwapGetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc; @@ -899,7 +924,9 @@ case X_GLXvop_BindTexImageEXT: return __glXSwapBindTexImageEXT(cl, pc); case X_GLXvop_ReleaseTexImageEXT: - return __glXSwapReleaseTexImageEXT(cl, pc); + return __glXSwapReleaseTexImageEXT(cl, pc); + case X_GLXvop_CopySubBufferMESA: + return __glXSwapCopySubBufferMESA(cl, pc); } #endif