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;
}
static void
static GLboolean
CreateDRIDrawable(Display *dpy, struct glx_config *config,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
@@ -198,22 +198,24 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config,
psc = priv->screens[config->screen];
if (psc->driScreen == NULL)
return;
return GL_TRUE;
pdraw = psc->driScreen->createDrawable(psc, drawable,
glxdrawable, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n");
return;
return GL_FALSE;
}
if (__glxHashInsert(priv->drawHash, glxdrawable, 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->textureFormat = determineTextureFormat(attrib_list, num_attribs);
return GL_TRUE;
}
static void
@@ -234,11 +236,12 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
#else
static void
static GLboolean
CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
{
return GL_FALSE;
}
static void
@@ -364,6 +367,27 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
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.
*/
@@ -405,7 +429,14 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
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;
}
@@ -417,27 +448,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
static void
DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
{
xGLXDestroyPbufferReq *req;
CARD8 opcode;
if ((dpy == NULL) || (drawable == 0)) {
return;
}
opcode = __glXSetupForCommand(dpy);
if (!opcode)
return;
LockDisplay(dpy);
GetReq(GLXDestroyPbuffer, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->pbuffer = (GLXPbuffer) drawable;
UnlockDisplay(dpy);
SyncHandle();
protocolDestroyDrawable(dpy, drawable, glxCode);
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
@@ -466,6 +481,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
CARD8 opcode;
unsigned int i;
Pixmap pixmap;
GLboolean glx_1_3 = GL_FALSE;
i = 0;
if (attrib_list) {
@@ -484,6 +500,8 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
xGLXCreatePbufferReq *req;
unsigned int extra = (size_in_attribs) ? 0 : 2;
glx_1_3 = GL_TRUE;
GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
data = (CARD32 *) (req + 1);
@@ -528,7 +546,12 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
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;
}

View File

@@ -640,19 +640,33 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
psc = priv->screens[vis->screen];
if (psc->driScreen == NULL)
break;
return xid;
config = glx_config_find_visual(psc->visuals, vis->visualid);
pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create pixmap\n");
xid = None;
break;
}
if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
return None; /* FIXME: Check what we're supposed to do here... */
xid = None;
break;
}
} 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
return xid;