Implment GLXPixmaps.

This commit is contained in:
Kristian Høgsberg 2007-08-23 19:07:52 -04:00
parent 2b0847c7aa
commit d7ded953c4
6 changed files with 187 additions and 364 deletions

View File

@ -425,108 +425,79 @@ int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
* *
* \param glxc Associated GLX context. * \param glxc Associated GLX context.
* \param drawId ID of the drawable. * \param drawId ID of the drawable.
* \param ppDraw Location to store the pointer to the drawable.
* \param ppPixmap Location to store the pointer to the pixmap.
* \param client Pointer to the client state. * \param client Pointer to the client state.
* \return Zero is returned on success. Otherwise a GLX / X11 protocol error * \return the __GLXdrawable is returned on success. Otherwise NULL.
* is returned.
* *
* \notes This function will need some modification when support pbuffers * \notes This function will need some modification when support pbuffers
* is added. * is added.
*/ */
static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId, static __GLXdrawable *
__GLXdrawable **ppGlxDraw, __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
__GLXpixmap **ppPixmap, int *error)
ClientPtr client )
{ {
DrawablePtr pDraw; DrawablePtr pDraw;
__GLcontextModes *modes; __GLcontextModes *modes;
__GLXdrawable *pGlxDraw; __GLXdrawable *pGlxDraw;
__GLXpixmap *drawPixmap = NULL; VisualID vid;
int rc; int rc;
/* This is the GLX 1.3 case - the client passes in a GLXWindow and /* This is the GLX 1.3 case - the client passes in a GLXWindow or
* we just return the __GLXdrawable. The first time a GLXPixmap * GLXPixmap and we just return the __GLXdrawable. */
* comes in, it doesn't have a corresponding __GLXdrawable, so it
* falls through to the else-case below, but after that it'll have
* a __GLXdrawable and we'll handle it here. */
pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes); pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes);
if (pGlxDraw != NULL) { if (pGlxDraw != NULL) {
if (glxc != NULL && pGlxDraw->modes != glxc->modes) { if (glxc != NULL && pGlxDraw->modes != glxc->modes) {
client->errorValue = drawId; client->errorValue = drawId;
return BadMatch; *error = BadMatch;
return NULL;
} }
*ppGlxDraw = pGlxDraw; return pGlxDraw;
*ppPixmap = pGlxDraw->pGlxPixmap;
return Success;
} }
/* The drawId wasn't a GLXWindow, so presumably it's a regular X /* The drawId wasn't a GLX drawable, so presumably it's a regular
* window. In that case, we create a shadow GLXWindow for it on * X window. In that case, we create a shadow GLXWindow for it on
* demand here for pre GLX 1.3 compatibility and use the X Window * demand here for pre GLX 1.3 compatibility and use the X Window
* XID as its GLXWindow XID. The client can't explicitly create a * XID as its GLXWindow XID. The client can't explicitly create a
* GLXWindow with the same XID as an X Window, so we wont get any * GLXWindow with the same XID as an X Window, so we wont get any
* resource ID clashes. Effectively, the X Window is now also a * resource ID clashes. Effectively, the X Window is now also a
* GLXWindow. */ * GLXWindow. */
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
if (pDraw->type == DRAWABLE_WINDOW) {
VisualID vid = wVisual((WindowPtr)pDraw);
modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
vid); if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
} else { client->errorValue = drawId;
/* *error = __glXError(GLXBadDrawable);
** An X Pixmap is not allowed as a parameter (a GLX Pixmap return NULL;
** is, but it must first be created with glxCreateGLXPixmap).
*/
client->errorValue = drawId;
return __glXError(GLXBadDrawable);
}
} else {
drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
if (drawPixmap) {
pDraw = drawPixmap->pDraw;
modes = drawPixmap->modes;
} else {
/*
** Drawable is neither a Window nor a GLXPixmap.
*/
client->errorValue = drawId;
return __glXError(GLXBadDrawable);
}
} }
/* If we're not given a context, don't create the __GLXdrawable */ /* If we're not given a context, don't create the __GLXdrawable */
if (glxc == NULL) { if (glxc == NULL) {
*ppPixmap = NULL; *error = __glXError(GLXBadDrawable);
*ppGlxDraw = NULL; return NULL;
return Success;
} }
/* We're binding an X Window or a GLX Pixmap for the first time vid = wVisual((WindowPtr)pDraw);
* and need to create a GLX drawable for it. First check that the modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid);
* drawable screen and fbconfig matches the context ditto. */
/* We're binding an X Window for the first time and need to create
* a GLX drawable for it. First check that the drawable screen
* and fbconfig matches the context ditto. */
if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) { if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) {
client->errorValue = drawId; client->errorValue = drawId;
return BadMatch; *error = BadMatch;
return NULL;
} }
pGlxDraw = pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pDraw, drawId, modes);
pDraw, drawId, modes);
/* since we are creating the drawablePrivate, drawId should be new */ /* since we are creating the drawablePrivate, drawId should be new */
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
pGlxDraw->destroy (pGlxDraw); pGlxDraw->destroy (pGlxDraw);
return BadAlloc; *error = BadAlloc;
return NULL;
} }
*ppPixmap = drawPixmap; return pGlxDraw;
*ppGlxDraw = pGlxDraw;
return 0;
} }
@ -536,8 +507,6 @@ int DoMakeCurrent( __GLXclientState *cl,
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
xGLXMakeCurrentReply reply; xGLXMakeCurrentReply reply;
__GLXpixmap *drawPixmap = NULL;
__GLXpixmap *readPixmap = NULL;
__GLXcontext *glxc, *prevglxc; __GLXcontext *glxc, *prevglxc;
__GLXdrawable *drawPriv = NULL; __GLXdrawable *drawPriv = NULL;
__GLXdrawable *readPriv = NULL; __GLXdrawable *readPriv = NULL;
@ -595,21 +564,13 @@ int DoMakeCurrent( __GLXclientState *cl,
assert( drawId != None ); assert( drawId != None );
assert( readId != None ); assert( readId != None );
status = GetDrawableOrPixmap(glxc, drawId, &drawPriv, &drawPixmap, drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
client); if (drawPriv == NULL)
if ( status != 0 ) {
return status; return status;
}
if ( readId != drawId ) { readPriv = __glXGetDrawable(glxc, readId, client, &status);
status = GetDrawableOrPixmap(glxc, readId, &readPriv, &readPixmap, if (readPriv == NULL)
client); return status;
if ( status != 0 ) {
return status;
}
} else {
readPriv = drawPriv;
}
} else { } else {
/* Switching to no context. Ignore new drawable. */ /* Switching to no context. Ignore new drawable. */
@ -671,42 +632,6 @@ int DoMakeCurrent( __GLXclientState *cl,
} }
if (prevglxc) { if (prevglxc) {
if (prevglxc->drawPixmap) {
if (prevglxc->readPixmap &&
prevglxc->drawPixmap != prevglxc->readPixmap) {
/*
** The previous drawable was a glx pixmap, release it.
*/
prevglxc->readPixmap->refcnt--;
if (!prevglxc->readPixmap->idExists &&
!prevglxc->readPixmap->refcnt) {
PixmapPtr pPixmap = (PixmapPtr) prevglxc->readPixmap->pDraw;
/*
** The DestroyPixmap routine should decrement the
** refcount of the X pixmap and free only if it's zero.
*/
(*prevglxc->readPixmap->pScreen->DestroyPixmap)(pPixmap);
xfree(prevglxc->readPixmap);
}
}
/*
** The previous drawable was a glx pixmap, release it.
*/
prevglxc->drawPixmap->refcnt--;
if (!prevglxc->drawPixmap->idExists &&
!prevglxc->drawPixmap->refcnt) {
PixmapPtr pPixmap = (PixmapPtr) prevglxc->drawPixmap->pDraw;
/*
** The DestroyPixmap routine should decrement the
** refcount of the X pixmap and free only if it's zero.
*/
(*prevglxc->drawPixmap->pScreen->DestroyPixmap)(pPixmap);
xfree(prevglxc->drawPixmap);
}
prevglxc->drawPixmap = NULL;
}
ChangeCurrentContext(cl, glxc, tag); ChangeCurrentContext(cl, glxc, tag);
StopUsingContext(prevglxc); StopUsingContext(prevglxc);
} else { } else {
@ -714,16 +639,6 @@ int DoMakeCurrent( __GLXclientState *cl,
} }
if (glxc) { if (glxc) {
if (drawPixmap) {
drawPixmap->refcnt++;
glxc->drawPixmap = drawPixmap;
}
if (readPixmap && (readPixmap != drawPixmap)) {
readPixmap->refcnt++;
glxc->readPixmap = readPixmap;
}
StartUsingContext(cl, glxc); StartUsingContext(cl, glxc);
reply.contextTag = tag; reply.contextTag = tag;
} else { } else {
@ -1210,31 +1125,30 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
return DoGetFBConfigs( cl, req->screen, GL_FALSE ); return DoGetFBConfigs( cl, req->screen, GL_FALSE );
} }
static int ValidateCreateDrawable(ClientPtr client, static int
int screenNum, XID fbconfigId, DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
XID drawablId, XID glxDrawableId, XID drawableId, XID glxDrawableId, int type)
int type, __GLcontextModes **modes,
DrawablePtr *ppDraw)
{ {
DrawablePtr pDraw; DrawablePtr pDraw;
ScreenPtr pScreen; ScreenPtr pScreen;
VisualPtr pVisual; VisualPtr pVisual;
__GLXscreen *pGlxScreen; __GLXscreen *pGlxScreen;
__GLXdrawable *pGlxDraw;
__GLcontextModes *modes;
int i, rc; int i, rc;
LEGAL_NEW_RESOURCE(glxDrawableId, client); LEGAL_NEW_RESOURCE(glxDrawableId, client);
rc = dixLookupDrawable(&pDraw, drawablId, client, 0, DixUnknownAccess); rc = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
if (rc != Success || pDraw->type != type) { if (rc != Success || pDraw->type != type) {
client->errorValue = drawablId; client->errorValue = drawableId;
return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap; return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap;
} }
/* Check if screen of the fbconfig matches screen of drawable. */ /* Check if screen of the fbconfig matches screen of drawable. */
pScreen = pDraw->pScreen; pScreen = pDraw->pScreen;
if (screenNum != pScreen->myNum) { if (screenNum != pScreen->myNum)
return BadMatch; return BadMatch;
}
/* If this fbconfig has a corresponding VisualRec the number of /* If this fbconfig has a corresponding VisualRec the number of
* planes must match the drawable depth. */ * planes must match the drawable depth. */
@ -1246,55 +1160,39 @@ static int ValidateCreateDrawable(ClientPtr client,
/* Get configuration of the visual. */ /* Get configuration of the visual. */
pGlxScreen = glxGetScreen(pScreen); pGlxScreen = glxGetScreen(pScreen);
*modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId); modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
if (*modes == NULL) { if (modes == NULL) {
/* Visual not support on this screen by this OpenGL implementation. */ /* Visual not support on this screen by this OpenGL implementation. */
client->errorValue = fbconfigId; client->errorValue = fbconfigId;
return BadValue; return BadValue;
} }
*ppDraw = pDraw; /* FIXME: We need to check that the window visual is compatible
* with the specified fbconfig. */
pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw,
glxDrawableId, modes);
if (pGlxDraw == NULL)
return BadAlloc;
if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
pGlxDraw->destroy (pGlxDraw);
return BadAlloc;
}
if (type == DRAWABLE_PIXMAP)
((PixmapPtr) pDraw)->refcnt++;
return Success; return Success;
} }
/* static void
** Create a GLX Pixmap from an X Pixmap. determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
*/
int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
GLuint screenNum, XID pixmapId, XID glxPixmapId,
CARD32 *attribs, CARD32 numAttribs)
{ {
ClientPtr client = cl->client;
DrawablePtr pDraw;
__GLXpixmap *pGlxPixmap;
__GLcontextModes *modes;
GLenum target = 0; GLenum target = 0;
int retval, i; int i;
__GLXdrawable *pGlxDraw;
retval = ValidateCreateDrawable (client, screenNum, fbconfigId, pGlxDraw = LookupIDByType(glxDrawableID, __glXDrawableRes);
pixmapId, glxPixmapId,
DRAWABLE_PIXMAP, &modes, &pDraw);
if (retval != Success)
return retval;
pGlxPixmap = (__GLXpixmap *) xalloc(sizeof(__GLXpixmap));
if (!pGlxPixmap) {
return BadAlloc;
}
if (!(AddResource(glxPixmapId, __glXPixmapRes, pGlxPixmap))) {
return BadAlloc;
}
pGlxPixmap->pDraw = pDraw;
pGlxPixmap->pGlxScreen = glxGetScreen(pDraw->pScreen);
pGlxPixmap->pScreen = pDraw->pScreen;
pGlxPixmap->idExists = True;
#ifdef XF86DRI
pGlxPixmap->pDamage = NULL;
#endif
pGlxPixmap->refcnt = 0;
pGlxPixmap->modes = modes;
for (i = 0; i < numAttribs; i++) { for (i = 0; i < numAttribs; i++) {
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
@ -1308,63 +1206,69 @@ int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
} }
} }
} }
if (!target) { if (!target) {
int w = pDraw->width, h = pDraw->height; int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
if (h & (h - 1) || w & (w - 1)) if (h & (h - 1) || w & (w - 1))
target = GL_TEXTURE_RECTANGLE_ARB; target = GL_TEXTURE_RECTANGLE_ARB;
else else
target = GL_TEXTURE_2D; target = GL_TEXTURE_2D;
} }
pGlxPixmap->target = target; pGlxDraw->target = target;
/*
** Bump the ref count on the X pixmap so it won't disappear.
*/
((PixmapPtr) pDraw)->refcnt++;
return Success;
} }
int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
return DoCreateGLXPixmap( cl, req->visual, req->screen,
req->pixmap, req->glxpixmap, NULL, 0 ); return DoCreateGLXDrawable(cl->client, req->screen, req->visual,
req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
} }
int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen, int err;
req->pixmap, req->glxpixmap,
(CARD32*)(req + 1), err = DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
req->numAttribs ); req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
if (err != Success)
return err;
determineTextureTarget(req->glxpixmap,
(CARD32*) (req + 1), req->numAttribs);
return Success;
} }
int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateGLXPixmapWithConfigSGIXReq *req = xGLXCreateGLXPixmapWithConfigSGIXReq *req =
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
req->pixmap, req->glxpixmap, NULL, 0 ); return DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
} }
int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmap) static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
__GLXdrawable *pGlxDraw;
int error;
/* /*
** Check if it's a valid GLX pixmap. ** Check it's the right type of drawable.
*/ */
if (!LookupIDByType(glxpixmap, __glXPixmapRes)) { pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
client->errorValue = glxpixmap; if (pGlxDraw == NULL || pGlxDraw->type != type) {
return __glXError(GLXBadPixmap); client->errorValue = glxdrawable;
error = type == DRAWABLE_WINDOW ? GLXBadWindow : GLXBadDrawable;
return __glXError(error);
} }
FreeResource(glxpixmap, FALSE); FreeResource(glxdrawable, FALSE);
return Success; return Success;
} }
@ -1373,14 +1277,14 @@ int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
return DoDestroyPixmap(cl, req->glxpixmap); return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
} }
int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
return DoDestroyPixmap(cl, req->glxpixmap); return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
} }
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
@ -1415,49 +1319,16 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
ClientPtr client = cl->client; ClientPtr client = cl->client;
DrawablePtr pDraw;
__GLXdrawable *glxPriv;
__GLXscreen *screen;
__GLcontextModes *modes;
int retval;
retval = ValidateCreateDrawable (client, req->screen, req->fbconfig, return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
req->window, req->glxwindow, req->window, req->glxwindow, DRAWABLE_WINDOW);
DRAWABLE_WINDOW, &modes, &pDraw);
if (retval != Success)
return retval;
/* FIXME: We need to check that the window visual is compatible
* with the specified fbconfig. */
screen = glxGetScreen(screenInfo.screens[req->screen]);
glxPriv = screen->createDrawable(screen, pDraw, req->glxwindow, modes);
if (glxPriv == NULL)
return BadAlloc;
if (!AddResource(req->glxwindow, __glXDrawableRes, glxPriv)) {
glxPriv->destroy (glxPriv);
return BadAlloc;
}
return Success;
} }
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
ClientPtr client = cl->client;
/* return DoDestroyDrawable(cl, req->glxwindow, DRAWABLE_WINDOW);
** Check if it's a valid GLX window.
*/
if (!LookupIDByType(req->glxwindow, __glXDrawableRes)) {
client->errorValue = req->glxwindow;
return __glXError(GLXBadWindow);
}
FreeResource(req->glxwindow, FALSE);
return Success;
} }
@ -1476,7 +1347,6 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
XID drawId = req->drawable; XID drawId = req->drawable;
__GLXcontext *glxc = NULL; __GLXcontext *glxc = NULL;
__GLXdrawable *pGlxDraw; __GLXdrawable *pGlxDraw;
__GLXpixmap *pPixmap;
int error; int error;
if (tag) { if (tag) {
@ -1501,11 +1371,11 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
} }
} }
error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client); pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
if (error != Success) if (pGlxDraw == NULL)
return error; return error;
if (pGlxDraw != NULL && pGlxDraw->type == DRAWABLE_WINDOW && if (pGlxDraw->type == DRAWABLE_WINDOW &&
(*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE) (*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
return __glXError(GLXBadDrawable); return __glXError(GLXBadDrawable);
@ -1576,8 +1446,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client; ClientPtr client = cl->client;
__GLXpixmap *pGlxPixmap;
__GLXcontext *context; __GLXcontext *context;
__GLXdrawable *pGlxDraw;
GLXDrawable drawId; GLXDrawable drawId;
int buffer; int buffer;
int error; int error;
@ -1594,8 +1464,8 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
if (!context) if (!context)
return error; return error;
pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes); pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
if (!pGlxPixmap) { if (!pGlxDraw || pGlxDraw->type != DRAWABLE_PIXMAP) {
client->errorValue = drawId; client->errorValue = drawId;
return __glXError(GLXBadPixmap); return __glXError(GLXBadPixmap);
} }
@ -1605,14 +1475,14 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return context->textureFromPixmap->bindTexImage(context, return context->textureFromPixmap->bindTexImage(context,
buffer, buffer,
pGlxPixmap); pGlxDraw);
} }
int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
ClientPtr client = cl->client; ClientPtr client = cl->client;
__GLXpixmap *pGlxPixmap; __GLXdrawable *pGlxDraw;
__GLXcontext *context; __GLXcontext *context;
GLXDrawable drawId; GLXDrawable drawId;
int buffer; int buffer;
@ -1627,10 +1497,10 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
if (!context) if (!context)
return error; return error;
pGlxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes); pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
if (!pGlxPixmap) { if (error != Success || pGlxDraw->type != DRAWABLE_PIXMAP) {
client->errorValue = drawId; client->errorValue = drawId;
return __glXError(GLXBadDrawable); return error;
} }
if (!context->textureFromPixmap) if (!context->textureFromPixmap)
@ -1638,7 +1508,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return context->textureFromPixmap->releaseTexImage(context, return context->textureFromPixmap->releaseTexImage(context,
buffer, buffer,
pGlxPixmap); pGlxDraw);
} }
int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
@ -1647,7 +1517,6 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
GLXContextTag tag = req->contextTag; GLXContextTag tag = req->contextTag;
__GLXcontext *glxc = NULL; __GLXcontext *glxc = NULL;
__GLXdrawable *pGlxDraw; __GLXdrawable *pGlxDraw;
__GLXpixmap *pPixmap;
ClientPtr client = cl->client; ClientPtr client = cl->client;
GLXDrawable drawId; GLXDrawable drawId;
int error; int error;
@ -1686,7 +1555,7 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
} }
} }
error = GetDrawableOrPixmap(glxc, drawId, &pGlxDraw, &pPixmap, client); pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
if (error != Success) if (error != Success)
return error; return error;
@ -1707,15 +1576,15 @@ static int
DoGetDrawableAttributes(__GLXclientState *cl, XID drawId) DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
__GLXpixmap *glxPixmap;
xGLXGetDrawableAttributesReply reply; xGLXGetDrawableAttributesReply reply;
__GLXdrawable *pGlxDraw;
CARD32 attributes[4]; CARD32 attributes[4];
int numAttribs; int numAttribs, error;
glxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes); pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
if (!glxPixmap) { if (!pGlxDraw) {
client->errorValue = drawId; client->errorValue = drawId;
return __glXError(GLXBadPixmap); return error;
} }
numAttribs = 2; numAttribs = 2;
@ -1725,7 +1594,7 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
reply.numAttribs = numAttribs; reply.numAttribs = numAttribs;
attributes[0] = GLX_TEXTURE_TARGET_EXT; attributes[0] = GLX_TEXTURE_TARGET_EXT;
attributes[1] = glxPixmap->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
GLX_TEXTURE_RECTANGLE_EXT; GLX_TEXTURE_RECTANGLE_EXT;
attributes[2] = GLX_Y_INVERTED_EXT; attributes[2] = GLX_Y_INVERTED_EXT;
attributes[3] = GL_FALSE; attributes[3] = GL_FALSE;

View File

@ -44,12 +44,12 @@
typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap; typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
struct __GLXtextureFromPixmap { struct __GLXtextureFromPixmap {
int (*bindTexImage) (__GLXcontext *baseContext, int (*bindTexImage) (__GLXcontext *baseContext,
int buffer, int buffer,
__GLXpixmap *pixmap); __GLXdrawable *pixmap);
int (*releaseTexImage) (__GLXcontext *baseContext, int (*releaseTexImage) (__GLXcontext *baseContext,
int buffer, int buffer,
__GLXpixmap *pixmap); __GLXdrawable *pixmap);
}; };
@ -151,12 +151,6 @@ struct __GLXcontext {
GLuint *selectBuf; GLuint *selectBuf;
GLint selectBufSize; /* number of elements allocated */ GLint selectBufSize; /* number of elements allocated */
/*
** Set only if current drawable is a glx pixmap.
*/
__GLXpixmap *drawPixmap;
__GLXpixmap *readPixmap;
/* /*
** The drawable private this context is bound to ** The drawable private this context is bound to
*/ */

View File

@ -46,23 +46,6 @@
#include <GL/internal/dri_interface.h> #include <GL/internal/dri_interface.h>
#endif #endif
typedef struct {
DrawablePtr pDraw;
__GLcontextModes *modes;
__GLXscreen *pGlxScreen;
ScreenPtr pScreen;
Bool idExists;
int refcnt;
GLenum target;
#ifdef XF86DRI
DamagePtr pDamage;
__DRIcontext *pDRICtx;
GLint texname;
unsigned long offset;
#endif
} __GLXpixmap;
struct __GLXdrawable { struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private); void (*destroy)(__GLXdrawable *private);
GLboolean (*resize)(__GLXdrawable *private); GLboolean (*resize)(__GLXdrawable *private);
@ -78,7 +61,6 @@ struct __GLXdrawable {
DrawablePtr pDraw; DrawablePtr pDraw;
XID drawId; XID drawId;
__GLXpixmap *pGlxPixmap;
/* /*
** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above. ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
@ -105,6 +87,8 @@ struct __GLXdrawable {
** reference count ** reference count
*/ */
int refCount; int refCount;
GLenum target;
}; };
#endif /* !__GLX_drawable_h__ */ #endif /* !__GLX_drawable_h__ */

View File

@ -59,6 +59,9 @@
#include "dispatch.h" #include "dispatch.h"
#include "extension_string.h" #include "extension_string.h"
#define containerOf(ptr, type, member) \
(type *)( (char *)ptr - offsetof(type,member) )
typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable; typedef struct __GLXDRIdrawable __GLXDRIdrawable;
@ -73,12 +76,14 @@ struct __GLXDRIscreen {
__DRIcopySubBufferExtension *copySubBuffer; __DRIcopySubBufferExtension *copySubBuffer;
__DRIswapControlExtension *swapControl; __DRIswapControlExtension *swapControl;
__DRItexOffsetExtension *texOffset;
#ifdef __DRI_TEX_OFFSET
__DRItexOffsetExtension *texOffset;
DRITexOffsetStartProcPtr texOffsetStart; DRITexOffsetStartProcPtr texOffsetStart;
DRITexOffsetFinishProcPtr texOffsetFinish; DRITexOffsetFinishProcPtr texOffsetFinish;
__GLXpixmap* texOffsetOverride[16]; __GLXDRIdrawable *texOffsetOverride[16];
GLuint lastTexOffsetOverride; GLuint lastTexOffsetOverride;
#endif
unsigned char glx_enable_bits[__GLX_EXT_BYTES]; unsigned char glx_enable_bits[__GLX_EXT_BYTES];
}; };
@ -92,6 +97,14 @@ struct __GLXDRIcontext {
struct __GLXDRIdrawable { struct __GLXDRIdrawable {
__GLXdrawable base; __GLXdrawable base;
__DRIdrawable driDrawable; __DRIdrawable driDrawable;
/* Pulled in from old __GLXpixmap */
#ifdef __DRI_TEX_OFFSET
GLint texname;
__GLXDRIcontext *ctx;
unsigned long offset;
DamagePtr pDamage;
#endif
}; };
static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING; static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING;
@ -107,15 +120,15 @@ __glXDRIleaveServer(GLboolean rendering)
GLuint lastOverride = screen->lastTexOffsetOverride; GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) { if (lastOverride) {
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride; __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int j; int j;
for (j = 0; j < lastOverride; j++) { for (j = 0; j < lastOverride; j++) {
__GLXpixmap *pGlxPix = texOffsetOverride[j]; __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
if (pGlxPix && pGlxPix->texname) { if (pGlxPix && pGlxPix->texname) {
pGlxPix->offset = pGlxPix->offset =
screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw); screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
} }
} }
} }
@ -129,18 +142,18 @@ __glXDRIleaveServer(GLboolean rendering)
GLuint lastOverride = screen->lastTexOffsetOverride; GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) { if (lastOverride) {
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride; __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int j; int j;
for (j = 0; j < lastOverride; j++) { for (j = 0; j < lastOverride; j++) {
__GLXpixmap *pGlxPix = texOffsetOverride[j]; __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
if (pGlxPix && pGlxPix->texname) { if (pGlxPix && pGlxPix->texname) {
screen->texOffset->setTexOffset(pGlxPix->pDRICtx, screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext,
pGlxPix->texname, pGlxPix->texname,
pGlxPix->offset, pGlxPix->offset,
pGlxPix->pDraw->depth, pGlxPix->base.pDraw->depth,
((PixmapPtr)pGlxPix->pDraw)->devKind); ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
} }
} }
} }
@ -321,14 +334,17 @@ glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
static int static int
__glXDRIbindTexImage(__GLXcontext *baseContext, __glXDRIbindTexImage(__GLXcontext *baseContext,
int buffer, int buffer,
__GLXpixmap *glxPixmap) __GLXdrawable *glxPixmap)
{ {
RegionPtr pRegion = NULL; RegionPtr pRegion = NULL;
PixmapPtr pixmap; PixmapPtr pixmap;
int bpp, override = 0, texname; int bpp, override = 0, texname;
GLenum format, type; GLenum format, type;
ScreenPtr pScreen = glxPixmap->pScreen; ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
__GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); __GLXDRIdrawable *driDraw =
containerOf(glxPixmap, __GLXDRIdrawable, base);
__GLXDRIscreen * const screen =
(__GLXDRIscreen *) glxGetScreen(pScreen);
CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_2D :
@ -341,11 +357,11 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
pixmap = (PixmapPtr) glxPixmap->pDraw; pixmap = (PixmapPtr) glxPixmap->pDraw;
if (screen->texOffsetStart && screen->texOffset) { if (screen->texOffsetStart && screen->texOffset) {
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride; __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int i, firstEmpty = 16; int i, firstEmpty = 16;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (texOffsetOverride[i] == glxPixmap) if (texOffsetOverride[i] == driDraw)
goto alreadyin; goto alreadyin;
if (firstEmpty == 16 && !texOffsetOverride[i]) if (firstEmpty == 16 && !texOffsetOverride[i])
@ -360,37 +376,37 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
if (firstEmpty >= screen->lastTexOffsetOverride) if (firstEmpty >= screen->lastTexOffsetOverride)
screen->lastTexOffsetOverride = firstEmpty + 1; screen->lastTexOffsetOverride = firstEmpty + 1;
texOffsetOverride[firstEmpty] = glxPixmap; texOffsetOverride[firstEmpty] = driDraw;
alreadyin: alreadyin:
override = 1; override = 1;
glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext; driDraw->ctx = (__GLXDRIcontext*)baseContext;
if (texname == glxPixmap->texname) if (texname == driDraw->texname)
return Success; return Success;
glxPixmap->texname = texname; driDraw->texname = texname;
screen->texOffset->setTexOffset(glxPixmap->pDRICtx, texname, 0, screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0,
pixmap->drawable.depth, pixmap->drawable.depth,
pixmap->devKind); pixmap->devKind);
} }
nooverride: nooverride:
if (!glxPixmap->pDamage) { if (!driDraw->pDamage) {
if (!override) { if (!override) {
glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
TRUE, pScreen, NULL); TRUE, pScreen, NULL);
if (!glxPixmap->pDamage) if (!driDraw->pDamage)
return BadAlloc; return BadAlloc;
DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage); DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
} }
pRegion = NULL; pRegion = NULL;
} else { } else {
pRegion = DamageRegion(glxPixmap->pDamage); pRegion = DamageRegion(driDraw->pDamage);
if (REGION_NIL(pRegion)) if (REGION_NIL(pRegion))
return Success; return Success;
} }
@ -469,7 +485,7 @@ nooverride:
} }
if (!override) if (!override)
DamageEmpty(glxPixmap->pDamage); DamageEmpty(driDraw->pDamage);
return Success; return Success;
} }
@ -477,19 +493,21 @@ nooverride:
static int static int
__glXDRIreleaseTexImage(__GLXcontext *baseContext, __glXDRIreleaseTexImage(__GLXcontext *baseContext,
int buffer, int buffer,
__GLXpixmap *pixmap) __GLXdrawable *pixmap)
{ {
ScreenPtr pScreen = pixmap->pScreen; ScreenPtr pScreen = pixmap->pDraw->pScreen;
__GLXDRIdrawable *driDraw =
containerOf(pixmap, __GLXDRIdrawable, base);
__GLXDRIscreen * const screen = __GLXDRIscreen * const screen =
(__GLXDRIscreen *) glxGetScreen(pScreen); (__GLXDRIscreen *) glxGetScreen(pScreen);
GLuint lastOverride = screen->lastTexOffsetOverride; GLuint lastOverride = screen->lastTexOffsetOverride;
if (lastOverride) { if (lastOverride) {
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride; __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
int i; int i;
for (i = 0; i < lastOverride; i++) { for (i = 0; i < lastOverride; i++) {
if (texOffsetOverride[i] == pixmap) { if (texOffsetOverride[i] == driDraw) {
if (screen->texOffsetFinish) if (screen->texOffsetFinish)
screen->texOffsetFinish((PixmapPtr)pixmap->pDraw); screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
@ -696,9 +714,6 @@ filter_modes(__GLcontextModes **server_modes,
} }
#define containerOf(ptr, type, member) \
(type *)( (char *)ptr - offsetof(type,member) )
static GLboolean static GLboolean
getDrawableInfo(__DRIdrawable *driDrawable, getDrawableInfo(__DRIdrawable *driDrawable,
unsigned int *index, unsigned int *stamp, unsigned int *index, unsigned int *stamp,

View File

@ -45,7 +45,6 @@ __GLXcontext *__glXLastContext;
** X resources. ** X resources.
*/ */
RESTYPE __glXContextRes; RESTYPE __glXContextRes;
RESTYPE __glXPixmapRes;
RESTYPE __glXDrawableRes; RESTYPE __glXDrawableRes;
RESTYPE __glXSwapBarrierRes; RESTYPE __glXSwapBarrierRes;
@ -101,32 +100,6 @@ static int ContextGone(__GLXcontext* cx, XID id)
return True; return True;
} }
/*
** Free a GLX Pixmap.
*/
static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
{
PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
pGlxPixmap->idExists = False;
if (!pGlxPixmap->refcnt) {
#ifdef XF86DRI
if (pGlxPixmap->pDamage) {
DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
DamageDestroy(pGlxPixmap->pDamage);
}
#endif
/*
** The DestroyPixmap routine should decrement the refcount and free
** only if it's zero.
*/
(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
xfree(pGlxPixmap);
}
return True;
}
/* /*
** Destroy routine that gets called when a drawable is freed. A drawable ** Destroy routine that gets called when a drawable is freed. A drawable
** contains the ancillary buffers needed for rendering. ** contains the ancillary buffers needed for rendering.
@ -136,24 +109,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
__GLXcontext *cx, *cx1; __GLXcontext *cx, *cx1;
/* /*
** Use glxPriv->type to figure out what kind of drawable this is. Don't ** When a drawable is destroyed, notify all context bound to
** use glxPriv->pDraw->type because by the time this routine is called, ** it, that there are no longer bound to anything.
** the pDraw might already have been freed.
*/ */
if (glxPriv->type == DRAWABLE_WINDOW) { for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
/* cx1 = cx->nextDrawPriv;
** When a window is destroyed, notify all context bound to cx->pendingState |= __GLX_PENDING_DESTROY;
** it, that there are no longer bound to anything. }
*/
for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
cx1 = cx->nextDrawPriv;
cx->pendingState |= __GLX_PENDING_DESTROY;
}
for (cx = glxPriv->readGlxc; cx; cx = cx1) { for (cx = glxPriv->readGlxc; cx; cx = cx1) {
cx1 = cx->nextReadPriv; cx1 = cx->nextReadPriv;
cx->pendingState |= __GLX_PENDING_DESTROY; cx->pendingState |= __GLX_PENDING_DESTROY;
}
} }
__glXUnrefDrawable(glxPriv); __glXUnrefDrawable(glxPriv);
@ -319,7 +285,6 @@ void GlxExtensionInit(void)
__GLXprovider *p; __GLXprovider *p;
__glXContextRes = CreateNewResourceType((DeleteType)ContextGone); __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
__glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
__glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone); __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
__glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone); __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);

View File

@ -148,9 +148,5 @@ __glXDrawableInit(__GLXdrawable *drawable,
drawable->refCount = 1; drawable->refCount = 1;
drawable->modes = modes; drawable->modes = modes;
/* if not a pixmap, lookup will fail, so pGlxPixmap will be NULL */
drawable->pGlxPixmap = (__GLXpixmap *)
LookupIDByType(drawId, __glXPixmapRes);
return GL_TRUE; return GL_TRUE;
} }