diff options
Diffstat (limited to 'src/glx')
-rw-r--r-- | src/glx/Makefile | 6 | ||||
-rw-r--r-- | src/glx/dri2.c | 10 | ||||
-rw-r--r-- | src/glx/dri2_glx.c | 16 | ||||
-rw-r--r-- | src/glx/dri_common.c | 25 | ||||
-rw-r--r-- | src/glx/dri_common.h | 3 | ||||
-rw-r--r-- | src/glx/dri_glx.c | 4 | ||||
-rw-r--r-- | src/glx/drisw_glx.c | 4 | ||||
-rw-r--r-- | src/glx/glx_pbuffer.c | 14 | ||||
-rw-r--r-- | src/glx/glxclient.h | 10 | ||||
-rw-r--r-- | src/glx/glxcmds.c | 64 | ||||
-rw-r--r-- | src/glx/glxcurrent.c | 24 | ||||
-rw-r--r-- | src/glx/glxext.c | 14 | ||||
-rw-r--r-- | src/glx/indirect.c | 6 | ||||
-rw-r--r-- | src/glx/indirect.h | 2 | ||||
-rw-r--r-- | src/glx/indirect_glx.c | 16 | ||||
-rw-r--r-- | src/glx/indirect_init.c | 2 | ||||
-rw-r--r-- | src/glx/indirect_vertex_array.c | 4 |
17 files changed, 113 insertions, 111 deletions
diff --git a/src/glx/Makefile b/src/glx/Makefile index ba5708ffed..2c94ef1cd4 100644 --- a/src/glx/Makefile +++ b/src/glx/Makefile @@ -1,7 +1,11 @@ TOP = ../.. include $(TOP)/configs/current -EXTRA_DEFINES = -DXF86VIDMODE -D_REENTRANT \ +ifeq ($(HAVE_XF86VIDMODE),yes) +EXTRA_DEFINES_XF86VIDMODE = -DXF86VIDMODE +endif + +EXTRA_DEFINES = $(EXTRA_DEFINES_XF86VIDMODE) -D_REENTRANT \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" SOURCES = \ diff --git a/src/glx/dri2.c b/src/glx/dri2.c index d70ec5a3ec..30999c899a 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -103,7 +103,7 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) /* Ignore swap events if we're not looking for them */ pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable); - if (!(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) + if (!pdraw || !(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) return False; aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); @@ -175,6 +175,14 @@ DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) err->minorCode == X_DRI2CopyRegion) return True; + /* If the X drawable was destroyed before the GLX drawable, the + * DRI2 drawble will be gone by the time we call + * DRI2DestroyDrawable. So just ignore BadDrawable here. */ + if (err->majorCode == codes->major_opcode && + err->errorCode == BadDrawable && + err->minorCode == X_DRI2DestroyDrawable) + return True; + return False; } diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index ff48c79c27..8247588e76 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -124,8 +124,6 @@ dri2_destroy_context(struct glx_context *context) if (context->extensions) XFree((char *) context->extensions); - GarbageCollectDRIDrawables(context->psc); - (*psc->core->destroyContext) (pcp->driContext); Xfree(pcp); @@ -159,6 +157,8 @@ dri2_unbind_context(struct glx_context *context, struct glx_context *new) struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); + + driReleaseDrawables(&pcp->base); } static struct glx_context * @@ -210,7 +210,17 @@ dri2DestroyDrawable(__GLXDRIdrawable *base) __glxHashDelete(pdp->dri2Hash, pdraw->base.xDrawable); (*psc->core->destroyDrawable) (pdraw->driDrawable); - DRI2DestroyDrawable(psc->base.dpy, pdraw->base.xDrawable); + + /* If it's a GLX 1.3 drawables, we can destroy the DRI2 drawable + * now, as the application explicitly asked to destroy the GLX + * drawable. Otherwise, for legacy drawables, we let the DRI2 + * drawable linger on the server, since there's no good way of + * knowing when the application is done with it. The server will + * destroy the DRI2 drawable when it destroys the X drawable or the + * client exits anyway. */ + if (pdraw->base.xDrawable != pdraw->base.drawable) + DRI2DestroyDrawable(psc->base.dpy, pdraw->base.xDrawable); + Xfree(pdraw); } diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index a7fb4c6424..5fb5255416 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -380,4 +380,29 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable) return pdraw; } +_X_HIDDEN void +driReleaseDrawables(struct glx_context *gc) +{ + struct glx_display *const priv = __glXInitialize(gc->psc->dpy); + __GLXDRIdrawable *pdraw; + + if (priv == NULL) + return; + + if (__glxHashLookup(priv->drawHash, + gc->currentDrawable, (void *) &pdraw) == 0) { + if (pdraw->drawable == pdraw->xDrawable) + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(priv->drawHash, gc->currentDrawable); + } + + if (gc->currentDrawable != gc->currentReadable && + __glxHashLookup(priv->drawHash, + gc->currentReadable, (void *) &pdraw) == 0) { + if (pdraw->drawable == pdraw->xDrawable) + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(priv->drawHash, gc->currentReadable); + } +} + #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h index 846a905a88..13b5ae471d 100644 --- a/src/glx/dri_common.h +++ b/src/glx/dri_common.h @@ -55,6 +55,9 @@ extern void driDestroyConfigs(const __DRIconfig **configs); extern __GLXDRIdrawable * driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable); +extern void +driReleaseDrawables(struct glx_context *gc); + extern const __DRIsystemTimeExtension systemTimeExtension; extern void InfoMessageF(const char *f, ...); diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 43a2aa495a..42b263c637 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -509,8 +509,6 @@ dri_destroy_context(struct glx_context * context) if (context->extensions) XFree((char *) context->extensions); - GarbageCollectDRIDrawables(context->psc); - (*psc->core->destroyContext) (pcp->driContext); XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); @@ -545,6 +543,8 @@ dri_unbind_context(struct glx_context *context, struct glx_context *new) struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); + + driReleaseDrawables(&pcp->base); } static const struct glx_context_vtable dri_context_vtable = { diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index c5b179157b..237ce17617 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -250,8 +250,6 @@ drisw_destroy_context(struct glx_context *context) if (context->extensions) XFree((char *) context->extensions); - GarbageCollectDRIDrawables(context->psc); - (*psc->core->destroyContext) (pcp->driContext); Xfree(pcp); @@ -285,6 +283,8 @@ drisw_unbind_context(struct glx_context *context, struct glx_context *new) struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); + + driReleaseDrawables(&pcp->base); } static const struct glx_context_vtable drisw_context_vtable = { diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 15bfb15919..34892e8b1a 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -86,7 +86,9 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { struct glx_display *priv = __glXInitialize(dpy); +#ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; +#endif CARD32 *output; CARD8 opcode; int i; @@ -95,8 +97,6 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, return; } - pdraw = GetGLXDRIDrawable(dpy, drawable); - opcode = __glXSetupForCommand(dpy); if (!opcode) return; @@ -133,6 +133,9 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + pdraw = GetGLXDRIDrawable(dpy, drawable); + for (i = 0; i < num_attribs; i++) { switch(attribs[i * 2]) { case GLX_EVENT_MASK: @@ -141,6 +144,7 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, break; } } +#endif return; } @@ -216,12 +220,14 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) { struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); + XID xid; if (pdraw != NULL) { - if (destroy_xdrawable) - XFreePixmap(pdraw->psc->dpy, pdraw->xDrawable); + xid = pdraw->xDrawable; (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(priv->drawHash, drawable); + if (destroy_xdrawable) + XFreePixmap(priv->dpy, xid); } } diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 81c9a26669..b453e6dbd0 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -260,6 +260,8 @@ struct glx_context GLint bufSize; /*@} */ + const struct glx_context_vtable *vtable; + /** * The XID of this rendering context. When the context is created a * new XID is allocated. This is set to None when the context is @@ -423,8 +425,6 @@ struct glx_context unsigned long thread_id; char gl_extension_bits[__GL_EXT_BYTES]; - - const struct glx_context_vtable *vtable; }; extern Bool @@ -494,13 +494,13 @@ struct glx_screen struct glx_display *display; + Display *dpy; + int scr; + #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /** * Per screen direct rendering interface functions and data. */ - Display *dpy; - int scr; - __GLXDRIscreen *driScreen; #endif diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index d4aa8b5866..4f7e84ef5f 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -44,7 +44,9 @@ #include "glx_error.h" #else #include <sys/time.h> +#ifdef XF86VIDMODE #include <X11/extensions/xf86vmode.h> +#endif #include "xf86dri.h" #endif #else @@ -61,56 +63,6 @@ static const char __glXGLXClientVersion[] = "1.4"; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) -static Bool windowExistsFlag; -static int -windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr) -{ - (void) dpy; - - if (xerr->error_code == BadWindow) { - windowExistsFlag = GL_FALSE; - } - return 0; -} - -/** - * Find drawables in the local hash that have been destroyed on the - * server. - * - * \param dpy Display to destroy drawables for - * \param screen Screen number to destroy drawables for - */ -_X_HIDDEN void -GarbageCollectDRIDrawables(struct glx_screen * sc) -{ - XID draw; - __GLXDRIdrawable *pdraw; - struct glx_display *priv = sc->display; - XWindowAttributes xwa; - int (*oldXErrorHandler) (Display *, XErrorEvent *); - - /* Set no-op error handler so Xlib doesn't bail out if the windows - * has alreay been destroyed on the server. */ - XSync(priv->dpy, GL_FALSE); - oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); - - if (__glxHashFirst(priv->drawHash, &draw, (void *) &pdraw) == 1) { - do { - windowExistsFlag = GL_TRUE; - XGetWindowAttributes(priv->dpy, draw, &xwa); /* dummy request */ - if (!windowExistsFlag) { - /* Destroy the local drawable data, if the drawable no - longer exists in the Xserver */ - (*pdraw->destroyDrawable) (pdraw); - __glxHashDelete(priv->drawHash, draw); - } - } while (__glxHashNext(priv->drawHash, &draw, (void *) &pdraw) == 1); - } - - XSync(priv->dpy, GL_FALSE); - XSetErrorHandler(oldXErrorHandler); -} - /** * Get the __DRIdrawable for the drawable associated with a GLXContext * @@ -2063,15 +2015,9 @@ __glxGetMscRate(__GLXDRIdrawable *glxDraw, return True; } else - return False; -#else - (void) draw; - (void) numerator; - (void) denominator; - (void) private; +#endif return False; -#endif } #endif @@ -2161,9 +2107,9 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, { #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); -#endif struct glx_screen *psc = pdraw ? pdraw->psc : NULL; int ret; +#endif /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2193,9 +2139,9 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, { #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); -#endif struct glx_screen *psc = pdraw ? pdraw->psc : NULL; int ret; +#endif /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE * error", but the return type in the spec is Bool. diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index e2569974c2..3631738354 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -53,7 +53,7 @@ */ static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE]; - +static struct glx_context_vtable dummyVtable; /* ** Dummy context used by small commands when there is no current context. ** All the @@ -66,6 +66,7 @@ struct glx_context dummyContext = { &dummyBuffer[0], &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE], sizeof(dummyBuffer), + &dummyVtable }; /* @@ -241,31 +242,36 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, return False; } - if (oldGC != &dummyContext && oldGC != gc) { + if (oldGC == gc && + gc->currentDrawable == draw && gc->currentReadable == read) + return True; + + if (oldGC != &dummyContext) { oldGC->vtable->unbind(oldGC, gc); oldGC->currentDpy = 0; oldGC->currentDrawable = None; oldGC->currentReadable = None; oldGC->thread_id = 0; - if (oldGC->xid == None) - /* We are switching away from a context that was - * previously destroyed, so we need to free the memory - * for the old handle. - */ - oldGC->vtable->destroy(oldGC); } if (gc) { - ret = gc->vtable->bind(gc, oldGC, draw, read); gc->currentDpy = dpy; gc->currentDrawable = draw; gc->currentReadable = read; gc->thread_id = _glthread_GetID(); __glXSetCurrentContext(gc); + ret = gc->vtable->bind(gc, oldGC, draw, read); } else { __glXSetCurrentContextNull(); } + if (oldGC != &dummyContext && oldGC->xid == None && oldGC != gc) { + /* We are switching away from a context that was + * previously destroyed, so we need to free the memory + * for the old handle. */ + oldGC->vtable->destroy(oldGC); + } + if (ret) { __glXGenerateError(dpy, gc, None, ret, X_GLXMakeContextCurrent); return GL_FALSE; diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 9e42d83c4d..c5e9d0510b 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -41,7 +41,6 @@ #include "glxclient.h" #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> -#include <X11/extensions/dri2proto.h> #ifdef GLX_USE_APPLEGL #include "apple_glx.h" #include "apple_visual.h" @@ -131,16 +130,6 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) aevent->count = awire->count; return True; } - /* No easy symbol to test for this, as GLX_BufferSwapComplete is - * defined in the local glx.h header, but the - * xGLXBufferSwapComplete typedef is only available in new versions - * of the external glxproto.h header, which doesn't have any - * testable versioning define. - * - * I'll use the related DRI2 define, in the hope that we won't - * receive these events unless we know how to ask for them: - */ -#ifdef X_DRI2SwapBuffers case GLX_BufferSwapComplete: { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; @@ -152,7 +141,6 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; return True; } -#endif default: /* client doesn't support server event */ break; @@ -249,9 +237,9 @@ glx_display_free(struct glx_display *priv) if (priv->serverGLXversion) Xfree((char *) priv->serverGLXversion); +#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) __glxHashDestroy(priv->drawHash); -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /* Free the direct rendering per display data */ if (priv->driswDisplay) (*priv->driswDisplay->destroyDisplay) (priv->driswDisplay); diff --git a/src/glx/indirect.c b/src/glx/indirect.c index c0fff6c4dc..2b09c1c3b5 100644 --- a/src/glx/indirect.c +++ b/src/glx/indirect.c @@ -91,7 +91,7 @@ __glXReadReply(Display * dpy, size_t size, void *dest, } NOINLINE void -__glXReadPixelReply(Display * dpy, struct glx_context * gc, unsigned max_dim, +__glXReadPixelReply(Display * dpy, struct glx_context *gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void *dest, GLboolean dimensions_in_reply) { @@ -138,7 +138,7 @@ __glXReadPixelReply(Display * dpy, struct glx_context * gc, unsigned max_dim, #define X_GLXSingle 0 NOINLINE FASTCALL GLubyte * -__glXSetupSingleRequest(struct glx_context * gc, GLint sop, GLint cmdlen) +__glXSetupSingleRequest(struct glx_context *gc, GLint sop, GLint cmdlen) { xGLXSingleReq *req; Display *const dpy = gc->currentDpy; @@ -153,7 +153,7 @@ __glXSetupSingleRequest(struct glx_context * gc, GLint sop, GLint cmdlen) } NOINLINE FASTCALL GLubyte * -__glXSetupVendorRequest(struct glx_context * gc, GLint code, GLint vop, +__glXSetupVendorRequest(struct glx_context *gc, GLint code, GLint vop, GLint cmdlen) { xGLXVendorPrivateReq *req; diff --git a/src/glx/indirect.h b/src/glx/indirect.h index 36d68b066c..282de75c40 100644 --- a/src/glx/indirect.h +++ b/src/glx/indirect.h @@ -600,7 +600,7 @@ extern HIDDEN void __indirect_glSecondaryColor3uivEXT(const GLuint * v); extern HIDDEN void __indirect_glSecondaryColor3usEXT(GLushort red, GLushort green, GLushort blue); extern HIDDEN void __indirect_glSecondaryColor3usvEXT(const GLushort * v); extern HIDDEN void __indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); -extern HIDDEN void __indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); +extern HIDDEN void __indirect_glMultiDrawArraysEXT(GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); extern HIDDEN void __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount); extern HIDDEN void __indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer); extern HIDDEN void __indirect_glFogCoorddEXT(GLdouble coord); diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c index f0598409cd..1870edee37 100644 --- a/src/glx/indirect_glx.c +++ b/src/glx/indirect_glx.c @@ -137,10 +137,12 @@ indirect_bind_context(struct glx_context *gc, struct glx_context *old, Display *dpy = gc->psc->dpy; int opcode = __glXSetupForCommand(dpy); - if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) + if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) { tag = old->currentContextTag; - else - tag = None; + old->currentContextTag = 0; + } else { + tag = 0; + } SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply); @@ -166,14 +168,18 @@ indirect_unbind_context(struct glx_context *gc, struct glx_context *new) int opcode = __glXSetupForCommand(dpy); xGLXMakeCurrentReply reply; + if (gc == new) + return; + /* We are either switching to no context, away from a indirect * context to a direct context or from one dpy to another and have * to send a request to the dpy to unbind the previous context. */ - if (!new || new->isDirect || new->psc->dpy != dpy) + if (!new || new->isDirect || new->psc->dpy != dpy) { SendMakeCurrentRequest(dpy, opcode, None, gc->currentContextTag, None, None, &reply); - gc->currentContextTag = 0; + gc->currentContextTag = 0; + } } static void diff --git a/src/glx/indirect_init.c b/src/glx/indirect_init.c index ea05188398..9f1ee5930f 100644 --- a/src/glx/indirect_init.c +++ b/src/glx/indirect_init.c @@ -53,7 +53,7 @@ static int NoOp(void) * Create and initialize a new GL dispatch table. The table is initialized * with GLX indirect rendering protocol functions. */ -struct _glapi_table *__glXNewIndirectAPI( void ) +struct _glapi_table * __glXNewIndirectAPI( void ) { struct _glapi_table *glAPI; GLuint entries; diff --git a/src/glx/indirect_vertex_array.c b/src/glx/indirect_vertex_array.c index 372618de4f..115f755bb7 100644 --- a/src/glx/indirect_vertex_array.c +++ b/src/glx/indirect_vertex_array.c @@ -1034,8 +1034,8 @@ __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, void -__indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, - GLsizei primcount) +__indirect_glMultiDrawArraysEXT(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei primcount) { struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = |