CopySubBufferMESA support

This commit is contained in:
David Reveman 2006-03-13 15:53:26 +00:00
parent ba679a269e
commit 5339591e28
8 changed files with 286 additions and 7 deletions

View file

@ -1,3 +1,12 @@
2006-03-13 David Reveman <davidr@novell.com>
* GL/mesa/X/xf86glx.c:
* GL/glx/glxscreens.c:
* GL/glx/glxdri.c:
* GL/glx/glxdrawable.h:
* GL/glx/glxcmdsswap.c:
* GL/glx/glxcmds.c: CopySubBufferMESA support.
2006-03-13 Matthias Hopf <mhopf@suse.de>
Needed for 'make distcheck':

View file

@ -1363,7 +1363,7 @@ int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
if (!glxc) {
return __glXBadContextTag;
}
#if 0 //XGL
#if 0 /*XGL */
/*
** The calling thread is swapping its current drawable. In this case,
** glxSwapBuffers is in both GL and X streams, in terms of
@ -1407,6 +1407,107 @@ int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
return Success;
}
int __glXCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client;
GLXContextTag tag = req->contextTag;
GLXDrawable drawId;
DrawablePtr pDraw;
__GLXpixmap *pGlxPixmap;
__GLXcontext *glxc = NULL;
int x, y, w, h;
int error;
pc += __GLX_VENDPRIV_HDR_SIZE;
drawId = *((CARD32 *) (pc));
x = *((INT32 *) (pc + 4));
y = *((INT32 *) (pc + 8));
w = *((INT32 *) (pc + 12));
h = *((INT32 *) (pc + 16));
/*
** Check that the GLX drawable is valid.
*/
pDraw = (DrawablePtr) LookupDrawable(drawId, client);
if (pDraw) {
if (pDraw->type == DRAWABLE_WINDOW) {
/*
** Drawable is an X window.
*/
} else {
/*
** Drawable is an X pixmap, which is not allowed.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
} else {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
/*
** Drawable is a GLX pixmap.
*/
} else {
/*
** Drawable is neither a X window nor a GLX pixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (tag) {
glxc = __glXLookupContextByTag(cl, tag);
if (!glxc) {
return __glXBadContextTag;
}
#if 0 /*XGL */
/*
** 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.
*
(*__glRenderTable->Finish)();
__GLX_NOTE_FLUSHED_CMDS(glxc);
} else {
return error;
}
*/
#endif
}
if (pDraw) {
__GLXdrawable *glxPriv;
if (glxc) {
glxPriv = __glXGetDrawable(glxc, pDraw, drawId);
if (glxPriv == NULL) {
return __glXBadDrawable;
}
}
else {
glxPriv = __glXFindDrawable(drawId);
if (glxPriv == NULL) {
/* This is a window we've never seen before, do nothing */
return Success;
}
}
if ((*glxPriv->copySubBuffer)(glxPriv, x, y, w, h) == GL_FALSE) {
return __glXBadDrawable;
}
}
return Success;
}
int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
{
@ -2329,6 +2430,8 @@ static int __glxHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
** allocating the entry points in the dispatch table.
*/
#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req;
@ -2352,6 +2455,8 @@ int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
return __glXBindTexImageEXT(cl, pc);
case X_GLXvop_ReleaseTexImageEXT:
return __glXReleaseTexImageEXT(cl, pc);
case X_GLXvop_CopySubBufferMESA:
return __glXCopySubBufferMESA(cl, pc);
}
#endif

View file

@ -327,6 +327,36 @@ int __glXSwapSwapBuffers(__GLXclientState *cl, GLbyte *pc)
return __glXSwapBuffers(cl, pc);
}
int __glXSwapCopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
CARD32 *drawId;
INT32 *x;
INT32 *y;
INT32 *w;
INT32 *h;
__GLX_DECLARE_SWAP_VARIABLES;
pc += __GLX_VENDPRIV_HDR_SIZE;
drawId = ((CARD32 *) (pc));
x = ((INT32 *) (pc + 4));
y = ((INT32 *) (pc + 8));
w = ((INT32 *) (pc + 12));
h = ((INT32 *) (pc + 16));
__GLX_SWAP_SHORT(&req->length);
__GLX_SWAP_INT(&req->contextTag);
__GLX_SWAP_INT(drawId);
__GLX_SWAP_INT(x);
__GLX_SWAP_INT(y);
__GLX_SWAP_INT(w);
__GLX_SWAP_INT(h);
return __glXCopySubBufferMESA(cl, (GLbyte *)pc);
}
int __glXSwapUseXFont(__GLXclientState *cl, GLbyte *pc)
{
xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
@ -1058,6 +1088,8 @@ int __glXSwapRenderLarge(__GLXclientState *cl, GLbyte *pc)
** allocating these entry points in the dispatch table.
*/
#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req;
@ -1087,6 +1119,8 @@ int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc)
return __glXSwapBindTexImageEXT(cl, pc);
case X_GLXvop_ReleaseTexImageEXT:
return __glXSwapReleaseTexImageEXT(cl, pc);
case X_GLXvop_CopySubBufferMESA:
return __glXSwapCopySubBufferMESA(cl, pc);
}
#endif

View file

@ -56,6 +56,7 @@ struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private);
GLboolean (*resize)(__GLXdrawable *private);
GLboolean (*swapBuffers)(__GLXdrawable *);
GLboolean (*copySubBuffer)(__GLXdrawable *, int, int, int, int);
/*
** list of drawable private structs

View file

@ -177,6 +177,32 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
return TRUE;
}
static GLboolean
__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
int x,
int y,
int width,
int height)
{
__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, width, height);
return TRUE;
}
static __GLXdrawable *
__glXDRIcontextCreateDrawable(__GLXcontext *context,
DrawablePtr pDraw,
@ -195,9 +221,10 @@ __glXDRIcontextCreateDrawable(__GLXcontext *context,
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

View file

@ -141,6 +141,7 @@ static char GLXServerExtensions[] =
"GLX_SGIX_swap_barrier "
#endif
"GLX_SGIX_fbconfig "
"GLX_MESA_copy_sub_buffer "
;
__GLXscreen **__glXActiveScreens;

View file

@ -137,6 +137,23 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
return GL_TRUE;
}
static GLboolean
__glXMesaDrawableCopySubBuffer(__GLXdrawable *base,
int x,
int y,
int width,
int height)
{
__GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
__glXenterServer();
XMesaCopySubBuffer (glxPriv->xm_buf, x, y, width, height);
__glXleaveServer();
return GL_TRUE;
}
static __GLXdrawable *
__glXMesaContextCreateDrawable(__GLXcontext *context,
@ -161,6 +178,7 @@ __glXMesaContextCreateDrawable(__GLXcontext *context,
glxPriv->base.destroy = __glXMesaDrawableDestroy;
glxPriv->base.resize = __glXMesaDrawableResize;
glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers;
glxPriv->base.copySubBuffer = __glXMesaDrawableCopySubBuffer;
pGlxScreen = context->pGlxScreen;

View file

@ -55,6 +55,7 @@ extern __GLXprovider *__xglMesaProvider;
typedef struct _xglGLScreen {
__GLXscreen base;
__GLXscreen *mesaScreen;
char *GLXextensions;
} xglGLScreenRec, *xglGLScreenPtr;
typedef struct _xglGLBuffer {
@ -5219,6 +5220,60 @@ xglSwapBuffers (__GLXdrawable *drawable)
return status;
}
static GLboolean
xglCopySubBuffer (__GLXdrawable *drawable,
int x,
int y,
int width,
int height)
{
xglGLBufferPtr pBufferPriv = (xglGLBufferPtr) drawable;
__GLXdrawable *mesaDrawable = pBufferPriv->mesaDrawable;
DrawablePtr pDrawable = pBufferPriv->pDrawable;
GLboolean status = GL_TRUE;
if (pDrawable)
{
glitz_surface_t *surface;
int xOff, yOff;
GCPtr pGC = pBufferPriv->pGC;
RegionRec region;
BoxRec box;
XGL_SCREEN_PRIV (pGC->pScreen);
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
box.x1 = pDrawable->x + x;
box.y2 = pDrawable->height - y;
box.x2 = box.x1 + width;
box.y1 = box.y2 - height;
REGION_INIT (pGC->pScreen, &region, &box, 1);
REGION_INTERSECT (pDrawable->pScreen, &region,
pGC->pCompositeClip, &region);
glitz_drawable_swap_buffer_region (pBufferPriv->drawable,
xOff, yOff, (glitz_box_t *)
REGION_RECTS (&region),
REGION_NUM_RECTS (&region));
xglAddBitDamage (pDrawable, &region);
DamageDamageRegion (pDrawable, &region);
REGION_SUBTRACT (pGC->pScreen, &pBufferPriv->damage,
&pBufferPriv->damage, &region);
REGION_UNINIT (pGC->pScreen, &region);
}
else if (mesaDrawable)
{
status = (*mesaDrawable->copySubBuffer) (mesaDrawable,
x, y, width, height);
}
return status;
}
static GLboolean
xglResizeDrawable (__GLXdrawable *drawable)
{
@ -5425,9 +5480,10 @@ xglCreateDrawable (__GLXcontext *context,
pBufferPriv->pPixmap = NULL;
pBufferPriv->pGC = NULL;
pBufferPriv->base.destroy = xglDestroyDrawable;
pBufferPriv->base.resize = xglResizeDrawable;
pBufferPriv->base.swapBuffers = xglSwapBuffers;
pBufferPriv->base.destroy = xglDestroyDrawable;
pBufferPriv->base.resize = xglResizeDrawable;
pBufferPriv->base.swapBuffers = xglSwapBuffers;
pBufferPriv->base.copySubBuffer = xglCopySubBuffer;
pBufferPriv->drawable = NULL;
pBufferPriv->backSurface = NULL;
@ -6157,6 +6213,9 @@ xglScreenDestroy (__GLXscreen *screen)
if (mesaScreen)
GlxScreenDestroy (mesaScreen);
if (pScreen->GLXextensions)
xfree (pScreen->GLXextensions);
xfree (pScreen);
}
@ -6190,6 +6249,31 @@ xglScreenProbe (ScreenPtr pScreen)
screen->base.GLXversion = screen->mesaScreen->GLXversion;
screen->base.GLXextensions = screen->mesaScreen->GLXextensions;
/* Remove GLX_MESA_copy_sub_buffer from GLX extension string if
glitz can't efficiently support it */
if (!(glitz_drawable_get_features (pScreenPriv->drawable) &
GLITZ_FEATURE_COPY_SUB_BUFFER_MASK))
{
screen->GLXextensions = strdup (screen->mesaScreen->GLXextensions);
if (screen->GLXextensions)
{
char *s;
s = strstr (screen->GLXextensions, "GLX_MESA_copy_sub_buffer ");
if (s)
{
int n, n2;
n = strlen ("GLX_MESA_copy_sub_buffer ");
n2 = strlen (s);
memmove (s, s + n, n2 - n + 1);
}
screen->base.GLXextensions = screen->GLXextensions;
}
}
screen->base.WrappedPositionWindow =
screen->mesaScreen->WrappedPositionWindow;