glx: Verify that drawable creation on the client side actually worked

... and clean up if it didn't.

Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Adam Jackson 2011-03-31 20:43:57 +00:00
parent 9e2bc5d4b0
commit 4833104718
2 changed files with 63 additions and 26 deletions

View file

@ -187,7 +187,7 @@ determineTextureFormat(const int *attribs, int numAttribs)
return 0; return 0;
} }
static void static GLboolean
CreateDRIDrawable(Display *dpy, struct glx_config *config, CreateDRIDrawable(Display *dpy, struct glx_config *config,
XID drawable, XID glxdrawable, XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs) const int *attrib_list, size_t num_attribs)
@ -198,22 +198,24 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config,
psc = priv->screens[config->screen]; psc = priv->screens[config->screen];
if (psc->driScreen == NULL) if (psc->driScreen == NULL)
return; return GL_TRUE;
pdraw = psc->driScreen->createDrawable(psc, drawable, pdraw = psc->driScreen->createDrawable(psc, drawable,
glxdrawable, config); glxdrawable, config);
if (pdraw == NULL) { if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n"); fprintf(stderr, "failed to create drawable\n");
return; return GL_FALSE;
} }
if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) { if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
(*pdraw->destroyDrawable) (pdraw); (*pdraw->destroyDrawable) (pdraw);
return; /* FIXME: Check what we're supposed to do here... */ return GL_FALSE;
} }
pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs); pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs); pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
return GL_TRUE;
} }
static void static void
@ -234,11 +236,12 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
#else #else
static void static GLboolean
CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig, CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
XID drawable, XID glxdrawable, XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs) const int *attrib_list, size_t num_attribs)
{ {
return GL_FALSE;
} }
static void static void
@ -364,6 +367,27 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
return 0; return 0;
} }
static void
protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
{
xGLXDestroyPbufferReq *req;
CARD8 opcode;
opcode = __glXSetupForCommand(dpy);
if (!opcode)
return;
LockDisplay(dpy);
GetReq(GLXDestroyPbuffer, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->pbuffer = (GLXPbuffer) drawable;
UnlockDisplay(dpy);
SyncHandle();
}
/** /**
* Create a non-pbuffer GLX drawable. * Create a non-pbuffer GLX drawable.
*/ */
@ -405,7 +429,14 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy); UnlockDisplay(dpy);
SyncHandle(); SyncHandle();
CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i); if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
if (glxCode == X_GLXCreatePixmap)
glxCode = X_GLXDestroyPixmap;
else
glxCode = X_GLXDestroyWindow;
protocolDestroyDrawable(dpy, xid, glxCode);
xid = None;
}
return xid; return xid;
} }
@ -417,27 +448,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
static void static void
DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
{ {
xGLXDestroyPbufferReq *req;
CARD8 opcode;
if ((dpy == NULL) || (drawable == 0)) { if ((dpy == NULL) || (drawable == 0)) {
return; return;
} }
protocolDestroyDrawable(dpy, drawable, glxCode);
opcode = __glXSetupForCommand(dpy);
if (!opcode)
return;
LockDisplay(dpy);
GetReq(GLXDestroyPbuffer, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->pbuffer = (GLXPbuffer) drawable;
UnlockDisplay(dpy);
SyncHandle();
DestroyDRIDrawable(dpy, drawable, GL_FALSE); DestroyDRIDrawable(dpy, drawable, GL_FALSE);
@ -466,6 +481,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
CARD8 opcode; CARD8 opcode;
unsigned int i; unsigned int i;
Pixmap pixmap; Pixmap pixmap;
GLboolean glx_1_3 = GL_FALSE;
i = 0; i = 0;
if (attrib_list) { if (attrib_list) {
@ -484,6 +500,8 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
xGLXCreatePbufferReq *req; xGLXCreatePbufferReq *req;
unsigned int extra = (size_in_attribs) ? 0 : 2; unsigned int extra = (size_in_attribs) ? 0 : 2;
glx_1_3 = GL_TRUE;
GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
data = (CARD32 *) (req + 1); data = (CARD32 *) (req + 1);
@ -528,7 +546,12 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
width, height, config->rgbBits); width, height, config->rgbBits);
CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i); if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) {
CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX;
XFreePixmap(dpy, pixmap);
protocolDestroyDrawable(dpy, id, o);
id = None;
}
return id; return id;
} }

View file

@ -640,19 +640,33 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
psc = priv->screens[vis->screen]; psc = priv->screens[vis->screen];
if (psc->driScreen == NULL) if (psc->driScreen == NULL)
break; return xid;
config = glx_config_find_visual(psc->visuals, vis->visualid); config = glx_config_find_visual(psc->visuals, vis->visualid);
pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config); pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
if (pdraw == NULL) { if (pdraw == NULL) {
fprintf(stderr, "failed to create pixmap\n"); fprintf(stderr, "failed to create pixmap\n");
xid = None;
break; break;
} }
if (__glxHashInsert(priv->drawHash, xid, pdraw)) { if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
(*pdraw->destroyDrawable) (pdraw); (*pdraw->destroyDrawable) (pdraw);
return None; /* FIXME: Check what we're supposed to do here... */ xid = None;
break;
} }
} while (0); } while (0);
if (xid == None) {
xGLXDestroyGLXPixmapReq *dreq;
LockDisplay(dpy);
GetReq(GLXDestroyGLXPixmap, dreq);
dreq->reqType = opcode;
dreq->glxCode = X_GLXDestroyGLXPixmap;
dreq->glxpixmap = xid;
UnlockDisplay(dpy);
SyncHandle();
}
#endif #endif
return xid; return xid;