diff options
Diffstat (limited to 'glx')
-rw-r--r-- | glx/Makefile.am | 7 | ||||
-rw-r--r-- | glx/glapi.h | 28 | ||||
-rw-r--r-- | glx/glxcmds.c | 109 | ||||
-rw-r--r-- | glx/glxdri2.c | 1 | ||||
-rw-r--r-- | glx/glxdriswrast.c | 8 | ||||
-rw-r--r-- | glx/glxext.c | 55 | ||||
-rw-r--r-- | glx/glxserver.h | 7 |
7 files changed, 58 insertions, 157 deletions
diff --git a/glx/Makefile.am b/glx/Makefile.am index 2397d4a49..7fb28fb50 100644 --- a/glx/Makefile.am +++ b/glx/Makefile.am @@ -47,8 +47,11 @@ glapi_sources = \ glprocs.h \ glthread.h -libglxdri_la_SOURCES = \ - glxdri.c +libglxdri_la_SOURCES = + +if DRI +libglxdri_la_SOURCES += glxdri.c +endif if DRI2_AIGLX libglxdri_la_SOURCES += glxdri2.c diff --git a/glx/glapi.h b/glx/glapi.h index ab80f7e67..6521f3142 100644 --- a/glx/glapi.h +++ b/glx/glapi.h @@ -107,65 +107,37 @@ extern struct _glapi_table *_glapi_Dispatch; **/ extern void -_glapi_noop_enable_warnings(GLboolean enable); - -extern void -_glapi_set_warning_func(_glapi_warning_func func); - -extern void _glapi_check_multithread(void); - extern void _glapi_set_context(void *context); - extern void * _glapi_get_context(void); - extern void _glapi_set_dispatch(struct _glapi_table *dispatch); - extern struct _glapi_table * _glapi_get_dispatch(void); - extern int _glapi_begin_dispatch_override(struct _glapi_table *override); - extern void _glapi_end_dispatch_override(int layer); - struct _glapi_table * _glapi_get_override_dispatch(int layer); - extern GLuint _glapi_get_dispatch_table_size(void); - -extern void -_glapi_check_table(const struct _glapi_table *table); - - extern int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ); -extern GLint -_glapi_get_proc_offset(const char *funcName); - - extern _glapi_proc _glapi_get_proc_address(const char *funcName); - -extern const char * -_glapi_get_proc_name(GLuint offset); - - #endif diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 60c80737f..1753be4a3 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -136,9 +136,9 @@ validGlxContext(ClientPtr client, XID id, int access_mode, { *err = dixLookupResourceByType((pointer *) context, id, __glXContextRes, client, access_mode); - if (*err != Success) { + if (*err != Success || (*context)->idExists == GL_FALSE) { client->errorValue = id; - if (*err == BadValue) + if (*err == BadValue || *err == Success) *err = __glXError(GLXBadContext); return FALSE; } @@ -376,6 +376,7 @@ int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) return DoCreateContext(cl, req->context, req->shareList, config, pGlxScreen, req->isDirect); } + int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; @@ -389,77 +390,31 @@ int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) &glxc, &err)) return err; - FreeResourceByType(req->context, __glXContextRes, FALSE); - return Success; -} - -/*****************************************************************************/ - -/* -** For each client, the server keeps a table of all the contexts that are -** current for that client (each thread of a client may have its own current -** context). These routines add, change, and lookup contexts in the table. -*/ - -/* -** Add a current context, and return the tag that will be used to refer to it. -*/ -static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc) -{ - int i; - int num = cl->numCurrentContexts; - __GLXcontext **table = cl->currentContexts; - - if (!glxc) return -1; - - /* - ** Try to find an empty slot and use it. - */ - for (i=0; i < num; i++) { - if (!table[i]) { - table[i] = glxc; - return i+1; - } - } - /* - ** Didn't find a free slot, so we'll have to grow the table. - */ - if (!num) { - table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); - } else { - table = (__GLXcontext **) realloc(table, - (num+1)*sizeof(__GLXcontext *)); - } - table[num] = glxc; - cl->currentContexts = table; - cl->numCurrentContexts++; - return num+1; -} + glxc->idExists = GL_FALSE; + if (!glxc->isCurrent) + FreeResourceByType(req->context, __glXContextRes, FALSE); -/* -** Given a tag, change the current context for the corresponding entry. -*/ -static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, - GLXContextTag tag) -{ - __GLXcontext **table = cl->currentContexts; - table[tag-1] = glxc; + return Success; } /* -** For this implementation we have chosen to simply use the index of the -** context's entry in the table as the context tag. A tag must be greater -** than 0. -*/ + * This will return "deleted" contexts, ie, where idExists is GL_FALSE. + * Contrast validGlxContext, which will not. We're cheating here and + * using the XID as the context tag, which is fine as long as we defer + * actually destroying the context until it's no longer referenced, and + * block clients from trying to MakeCurrent on contexts that are on the + * way to destruction. Notice that DoMakeCurrent calls validGlxContext + * for new contexts but __glXLookupContextByTag for previous contexts. + */ __GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) { - int num = cl->numCurrentContexts; + __GLXcontext *ret; - if (tag < 1 || tag > num) { - return 0; - } else { - return cl->currentContexts[tag-1]; - } + if (dixLookupResourceByType((void **)&ret, tag, __glXContextRes, + cl->client, DixUseAccess) == Success) + return ret; + + return NULL; } /*****************************************************************************/ @@ -473,7 +428,7 @@ static void StopUsingContext(__GLXcontext *glxc) } glxc->isCurrent = GL_FALSE; if (!glxc->idExists) { - __glXFreeContext(glxc); + FreeResourceByType(glxc->id, __glXContextRes, FALSE); } } } @@ -676,16 +631,11 @@ DoMakeCurrent(__GLXclientState *cl, glxc->isCurrent = GL_TRUE; } - if (prevglxc) { - ChangeCurrentContext(cl, glxc, tag); - StopUsingContext(prevglxc); - } else { - tag = AddCurrentContext(cl, glxc); - } + StopUsingContext(prevglxc); if (glxc) { StartUsingContext(cl, glxc); - reply.contextTag = tag; + reply.contextTag = glxc->id; } else { reply.contextTag = 0; } @@ -1184,10 +1134,11 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, return BadAlloc; } - /* Add the glx drawable under the XID of the underlying X drawable - * too. That way we'll get a callback in DrawableGone and can - * clean up properly when the drawable is destroyed. */ - if (drawableId != glxDrawableId && + /* + * Windows aren't refcounted, so track both the X and the GLX window + * so we get called regardless of destruction order. + */ + if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW && !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { pGlxDraw->destroy (pGlxDraw); return BadAlloc; @@ -1218,6 +1169,8 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, glxDrawableId, GLX_DRAWABLE_PIXMAP); + ((PixmapPtr)pDraw)->refcnt++; + return err; } diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 8d21c937b..c4b7ba4c6 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -184,6 +184,7 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, break; default: /* unknown swap completion type */ + wire.event_type = 0; break; } wire.drawable = drawable->drawId; diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index f1211ee09..13752f868 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -201,6 +201,14 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, if (texBuffer == NULL) return Success; +#if __DRI_TEX_BUFFER_VERSION >= 2 + if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { + (*texBuffer->setTexBuffer2)(context->driContext, + glxPixmap->target, + glxPixmap->format, + drawable->driDrawable); + } else +#endif texBuffer->setTexBuffer(context->driContext, glxPixmap->target, drawable->driDrawable); diff --git a/glx/glxext.c b/glx/glxext.c index 1ee22fab3..625f8ee27 100644 --- a/glx/glxext.c +++ b/glx/glxext.c @@ -124,54 +124,37 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) { __GLXcontext *c, *next; - /* If this drawable was created using glx 1.3 drawable - * constructors, we added it as a glx drawable resource under both - * its glx drawable ID and it X drawable ID. Remove the other - * resource now so we don't a callback for freed memory. */ - if (glxPriv->drawId != glxPriv->pDraw->id) { - if (xid == glxPriv->drawId) - FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE); - else - FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); + if (glxPriv->type == GLX_DRAWABLE_WINDOW) { + /* If this was created by glXCreateWindow, free the matching resource */ + if (glxPriv->drawId != glxPriv->pDraw->id) { + if (xid == glxPriv->drawId) + FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE); + else + FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); + } + /* otherwise this window was implicitly created by MakeCurrent */ } for (c = glxAllContexts; c; c = next) { next = c->next; if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) { - int i; - FlushContext(c); (*c->loseCurrent)(c); c->isCurrent = GL_FALSE; if (c == __glXLastContext) __glXFlushContextCache(); - - if (!c->idExists) { - for (i = 1; i < currentMaxClients; i++) { - if (clients[i]) { - __GLXclientState *cl = glxGetClient(clients[i]); - - if (cl->inUse) { - int j; - - for (j = 0; j < cl->numCurrentContexts; j++) { - if (cl->currentContexts[j] == c) - cl->currentContexts[j] = NULL; - } - } - } - } - } } if (c->drawPriv == glxPriv) c->drawPriv = NULL; if (c->readPriv == glxPriv) c->readPriv = NULL; - if (!c->idExists && !c->isCurrent) - __glXFreeContext(c); } + /* drop our reference to any backing pixmap */ + if (glxPriv->type == GLX_DRAWABLE_PIXMAP) + glxPriv->pDraw->pScreen->DestroyPixmap((PixmapPtr)glxPriv->pDraw); + glxPriv->destroy(glxPriv); return True; @@ -287,8 +270,6 @@ glxClientCallback (CallbackListPtr *list, NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; ClientPtr pClient = clientinfo->client; __GLXclientState *cl = glxGetClient(pClient); - __GLXcontext *cx; - int i; switch (pClient->clientState) { case ClientStateRunning: @@ -302,18 +283,8 @@ glxClientCallback (CallbackListPtr *list, break; case ClientStateGone: - for (i = 0; i < cl->numCurrentContexts; i++) { - cx = cl->currentContexts[i]; - if (cx) { - cx->isCurrent = GL_FALSE; - if (!cx->idExists) - __glXFreeContext(cx); - } - } - free(cl->returnBuf); free(cl->largeCmdBuf); - free(cl->currentContexts); free(cl->GLClientextensions); break; diff --git a/glx/glxserver.h b/glx/glxserver.h index 1daf97758..f10c8fe12 100644 --- a/glx/glxserver.h +++ b/glx/glxserver.h @@ -158,13 +158,6 @@ struct __GLXclientStateRec { GLbyte *largeCmdBuf; GLint largeCmdBufSize; - /* - ** Keep a list of all the contexts that are current for this client's - ** threads. - */ - __GLXcontext **currentContexts; - GLint numCurrentContexts; - /* Back pointer to X client record */ ClientPtr client; |