[Mesa-dev] [PATCH] glx: Verify that drawable creation on the client side actually worked
Adam Jackson
ajax at redhat.com
Wed May 4 14:50:55 PDT 2011
... and clean up if it didn't.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
src/glx/glx_pbuffer.c | 76 ++++++++++++++++++++++++++++++++-----------------
src/glx/glxcmds.c | 74 +++++++++++++++++++++++++++++++-----------------
2 files changed, 98 insertions(+), 52 deletions(-)
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 5f91bc6..1d9c1e9 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -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; /* not a DRI screen, not an error */
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
@@ -367,6 +370,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.
*
@@ -378,6 +402,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
Drawable drawable, const int *attrib_list, CARD8 glxCode)
{
xGLXCreateWindowReq *req;
+ GLXDrawable ret;
CARD32 *data;
unsigned int i;
CARD8 opcode;
@@ -401,7 +426,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
req->screen = config->screen;
req->fbconfig = config->fbconfigID;
req->window = drawable;
- req->glxwindow = XAllocID(dpy);
+ req->glxwindow = ret = XAllocID(dpy);
req->numAttribs = i;
if (attrib_list)
@@ -410,9 +435,16 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
SyncHandle();
- CreateDRIDrawable(dpy, config, drawable, req->glxwindow, attrib_list, i);
+ if (!CreateDRIDrawable(dpy, config, drawable, ret, attrib_list, i)) {
+ if (glxCode == X_GLXCreatePixmap)
+ glxCode = X_GLXDestroyPixmap;
+ else
+ glxCode = X_GLXDestroyWindow;
+ protocolDestroyDrawable(dpy, ret, glxCode);
+ ret = None;
+ }
- return req->glxwindow;
+ return ret;
}
@@ -422,27 +454,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);
@@ -474,6 +490,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) {
@@ -492,6 +509,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);
@@ -536,7 +555,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;
}
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 22bebab..6baf7b3 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -599,6 +599,43 @@ glXIsDirect(Display * dpy, GLXContext gc_user)
#endif
}
+static GLXPixmap
+createDRIDrawableForPixmap(Display *dpy, XVisualInfo *vis, Pixmap pixmap,
+ GLXPixmap xid)
+{
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+ do {
+ /* FIXME: Maybe delay __DRIdrawable creation until the drawable
+ * is actually bound to a context... */
+
+ struct glx_display *const priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw;
+ struct glx_screen *psc;
+ struct glx_config *config;
+
+ psc = priv->screens[vis->screen];
+ if (psc->driScreen == NULL)
+ break; /* not a DRI screen, not an error */
+
+ 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);
+ xid = None;
+ break;
+ }
+ } while (0);
+#endif
+
+ return xid;
+}
+
_X_EXPORT GLXPixmap
glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
{
@@ -635,32 +672,17 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
UnlockDisplay(dpy);
SyncHandle();
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
- do {
- /* FIXME: Maybe delay __DRIdrawable creation until the drawable
- * is actually bound to a context... */
-
- struct glx_display *const priv = __glXInitialize(dpy);
- __GLXDRIdrawable *pdraw;
- struct glx_screen *psc;
- struct glx_config *config;
-
- psc = priv->screens[vis->screen];
- if (psc->driScreen == NULL)
- break;
- config = glx_config_find_visual(psc->visuals, vis->visualid);
- pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, config);
- if (pdraw == NULL) {
- fprintf(stderr, "failed to create pixmap\n");
- break;
- }
-
- if (__glxHashInsert(priv->drawHash, req->glxpixmap, pdraw)) {
- (*pdraw->destroyDrawable) (pdraw);
- return None; /* FIXME: Check what we're supposed to do here... */
- }
- } while (0);
-#endif
+ if (!createDRIDrawableForPixmap(dpy, vis, pixmap, xid)) {
+ xGLXDestroyGLXPixmapReq *dreq;
+ LockDisplay(dpy);
+ GetReq(GLXDestroyGLXPixmap, dreq);
+ dreq->reqType = opcode;
+ dreq->glxCode = X_GLXDestroyGLXPixmap;
+ dreq->glxpixmap = xid;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ xid = None;
+ }
return xid;
#endif
--
1.7.4.4
More information about the mesa-dev
mailing list