From 31819830b66a49f1b62e09090cc65aefc657aeb8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 22 Jul 2010 21:24:14 -0400 Subject: [PATCH] glx: Allocate the __GLXcontext in the DRI drivers --- src/glx/dri2_glx.c | 40 +++++++++++-------- src/glx/dri_glx.c | 43 +++++++++++--------- src/glx/drisw_glx.c | 30 ++++++++------ src/glx/glxclient.h | 31 ++++++--------- src/glx/glxcmds.c | 108 +++++++++++++++++++++++++++------------------------ src/glx/glxcurrent.c | 8 ++-- 6 files changed, 136 insertions(+), 124 deletions(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 6ce5ae6..778607d 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -94,9 +94,9 @@ struct dri2_screen { struct dri2_context { - __GLXDRIcontext base; + __GLXcontext base; + __GLXDRIcontext dri_vtable; __DRIcontext *driContext; - __GLXscreenConfigs *psc; }; struct dri2_drawable @@ -111,12 +111,13 @@ struct dri2_drawable int swap_interval; }; +static const struct glx_context_vtable dri2_context_vtable; + static void -dri2DestroyContext(__GLXDRIcontext *context, - __GLXscreenConfigs *base, Display *dpy) +dri2DestroyContext(__GLXcontext *context) { struct dri2_context *pcp = (struct dri2_context *) context; - struct dri2_screen *psc = (struct dri2_screen *) base; + struct dri2_screen *psc = (struct dri2_screen *) context->psc; (*psc->core->destroyContext) (pcp->driContext); @@ -124,11 +125,11 @@ dri2DestroyContext(__GLXDRIcontext *context, } static Bool -dri2BindContext(__GLXDRIcontext *context, +dri2BindContext(__GLXcontext *context, __GLXDRIdrawable *draw, __GLXDRIdrawable *read) { struct dri2_context *pcp = (struct dri2_context *) context; - struct dri2_screen *psc = (struct dri2_screen *) pcp->psc; + struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; struct dri2_drawable *pdr = (struct dri2_drawable *) draw; struct dri2_drawable *prd = (struct dri2_drawable *) read; @@ -137,18 +138,18 @@ dri2BindContext(__GLXDRIcontext *context, } static void -dri2UnbindContext(__GLXDRIcontext *context) +dri2UnbindContext(__GLXcontext *context) { struct dri2_context *pcp = (struct dri2_context *) context; - struct dri2_screen *psc = (struct dri2_screen *) pcp->psc; + struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); } -static __GLXDRIcontext * +static __GLXcontext * dri2CreateContext(__GLXscreenConfigs *base, const __GLcontextModes * mode, - GLXContext gc, GLXContext shareList, int renderType) + GLXContext shareList, int renderType) { struct dri2_context *pcp, *pcp_shared; struct dri2_screen *psc = (struct dri2_screen *) base; @@ -164,7 +165,12 @@ dri2CreateContext(__GLXscreenConfigs *base, if (pcp == NULL) return NULL; - pcp->psc = &psc->base; + memset(pcp, 0, sizeof *pcp); + if (!glx_context_init(&pcp->base, &psc->base, mode)) { + Xfree(pcp); + return NULL; + } + pcp->driContext = (*psc->dri2->createNewContext) (psc->driScreen, config->driConfig, shared, pcp); @@ -174,9 +180,11 @@ dri2CreateContext(__GLXscreenConfigs *base, return NULL; } - pcp->base.destroyContext = dri2DestroyContext; - pcp->base.bindContext = dri2BindContext; - pcp->base.unbindContext = dri2UnbindContext; + pcp->base.vtable = &dri2_context_vtable; + pcp->base.driContext = &pcp->dri_vtable; + pcp->dri_vtable.destroyContext = dri2DestroyContext; + pcp->dri_vtable.bindContext = dri2BindContext; + pcp->dri_vtable.unbindContext = dri2UnbindContext; return &pcp->base; } @@ -826,8 +834,6 @@ dri2CreateScreen(int screen, __GLXdisplayPrivate * priv) psp->copySubBuffer = dri2CopySubBuffer; __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer"); - psc->base.direct_context_vtable = &dri2_context_vtable; - Xfree(driverName); Xfree(deviceName); diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 369d07a..959fc74 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -78,7 +78,8 @@ struct dri_screen struct dri_context { - __GLXDRIcontext base; + __GLXcontext base; + __GLXDRIcontext dri_vtable; __DRIcontext *driContext; XID hwContextID; __GLXscreenConfigs *psc; @@ -91,6 +92,11 @@ struct dri_drawable __DRIdrawable *driDrawable; }; +static const struct glx_context_vtable dri_context_vtable = { + NULL, + NULL, +}; + /* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen. (I.e. "r128", "tdfx", etc). @@ -497,11 +503,10 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, } static void -driDestroyContext(__GLXDRIcontext * context, - __GLXscreenConfigs *base, Display * dpy) +driDestroyContext(__GLXcontext * context) { struct dri_context *pcp = (struct dri_context *) context; - struct dri_screen *psc = (struct dri_screen *) base; + struct dri_screen *psc = (struct dri_screen *) context->psc; (*psc->core->destroyContext) (pcp->driContext); @@ -510,7 +515,7 @@ driDestroyContext(__GLXDRIcontext * context, } static Bool -driBindContext(__GLXDRIcontext *context, +driBindContext(__GLXcontext *context, __GLXDRIdrawable *draw, __GLXDRIdrawable *read) { struct dri_context *pcp = (struct dri_context *) context; @@ -523,7 +528,7 @@ driBindContext(__GLXDRIcontext *context, } static void -driUnbindContext(__GLXDRIcontext * context) +driUnbindContext(__GLXcontext * context) { struct dri_context *pcp = (struct dri_context *) context; struct dri_screen *psc = (struct dri_screen *) pcp->psc; @@ -531,10 +536,10 @@ driUnbindContext(__GLXDRIcontext * context) (*psc->core->unbindContext) (pcp->driContext); } -static __GLXDRIcontext * +static __GLXcontext * driCreateContext(__GLXscreenConfigs *base, const __GLcontextModes * mode, - GLXContext gc, GLXContext shareList, int renderType) + GLXContext shareList, int renderType) { struct dri_context *pcp, *pcp_shared; struct dri_screen *psc = (struct dri_screen *) base; @@ -554,7 +559,12 @@ driCreateContext(__GLXscreenConfigs *base, if (pcp == NULL) return NULL; - pcp->psc = &psc->base; + memset(pcp, 0, sizeof *pcp); + if (!glx_context_init(&pcp->base, &psc->base, mode)) { + Xfree(pcp); + return NULL; + } + if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr, mode->visualID, &pcp->hwContextID, &hwContext)) { @@ -572,9 +582,11 @@ driCreateContext(__GLXscreenConfigs *base, return NULL; } - pcp->base.destroyContext = driDestroyContext; - pcp->base.bindContext = driBindContext; - pcp->base.unbindContext = driUnbindContext; + pcp->base.vtable = &dri_context_vtable; + pcp->base.driContext = &pcp->dri_vtable; + pcp->dri_vtable.destroyContext = driDestroyContext; + pcp->dri_vtable.bindContext = driBindContext; + pcp->dri_vtable.unbindContext = driUnbindContext; return &pcp->base; } @@ -673,11 +685,6 @@ driDestroyScreen(__GLXscreenConfigs *base) dlclose(psc->driver); } -static const struct glx_context_vtable dri_context_vtable = { - NULL, - NULL, -}; - #ifdef __DRI_SWAP_BUFFER_COUNTER static int @@ -884,8 +891,6 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) psp->setSwapInterval = driSetSwapInterval; psp->getSwapInterval = driGetSwapInterval; - psc->base.direct_context_vtable = &dri_context_vtable; - return &psc->base; } diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 4416061..367aa6a 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -35,7 +35,8 @@ struct drisw_display struct drisw_context { - __GLXDRIcontext base; + __GLXcontext base; + __GLXDRIcontext dri_vtable; __DRIcontext *driContext; __GLXscreenConfigs *psc; }; @@ -239,11 +240,10 @@ static const __DRIextension *loader_extensions[] = { */ static void -driDestroyContext(__GLXDRIcontext *context, - __GLXscreenConfigs *base, Display *dpy) +driDestroyContext(__GLXcontext *context) { struct drisw_context *pcp = (struct drisw_context *) context; - struct drisw_screen *psc = (struct drisw_screen *) base; + struct drisw_screen *psc = (struct drisw_screen *) context->psc; (*psc->core->destroyContext) (pcp->driContext); @@ -251,7 +251,7 @@ driDestroyContext(__GLXDRIcontext *context, } static Bool -driBindContext(__GLXDRIcontext * context, +driBindContext(__GLXcontext * context, __GLXDRIdrawable * draw, __GLXDRIdrawable * read) { struct drisw_context *pcp = (struct drisw_context *) context; @@ -264,7 +264,7 @@ driBindContext(__GLXDRIcontext * context, } static void -driUnbindContext(__GLXDRIcontext * context) +driUnbindContext(__GLXcontext * context) { struct drisw_context *pcp = (struct drisw_context *) context; struct drisw_screen *psc = (struct drisw_screen *) pcp->psc; @@ -272,10 +272,10 @@ driUnbindContext(__GLXDRIcontext * context) (*psc->core->unbindContext) (pcp->driContext); } -static __GLXDRIcontext * +static __GLXcontext * driCreateContext(__GLXscreenConfigs *base, const __GLcontextModes *mode, - GLXContext gc, GLXContext shareList, int renderType) + GLXContext shareList, int renderType) { struct drisw_context *pcp, *pcp_shared; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; @@ -294,7 +294,12 @@ driCreateContext(__GLXscreenConfigs *base, if (pcp == NULL) return NULL; - pcp->psc = &psc->base; + memset(pcp, 0, sizeof *pcp); + if (!glx_context_init(&pcp->base, &psc->base, mode)) { + Xfree(pcp); + return NULL; + } + pcp->driContext = (*psc->core->createNewContext) (psc->driScreen, config->driConfig, shared, pcp); @@ -303,9 +308,10 @@ driCreateContext(__GLXscreenConfigs *base, return NULL; } - pcp->base.destroyContext = driDestroyContext; - pcp->base.bindContext = driBindContext; - pcp->base.unbindContext = driUnbindContext; + pcp->base.driContext = &pcp->dri_vtable; + pcp->dri_vtable.destroyContext = driDestroyContext; + pcp->dri_vtable.bindContext = driBindContext; + pcp->dri_vtable.unbindContext = driUnbindContext; return &pcp->base; } diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 4f83305..dcb75d4 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -126,10 +126,9 @@ struct __GLXDRIscreenRec { void (*destroyScreen)(__GLXscreenConfigs *psc); - __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc, - const __GLcontextModes *mode, - GLXContext gc, - GLXContext shareList, int renderType); + __GLXcontext *(*createContext)(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext shareList, int renderType); __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, XID drawable, @@ -155,12 +154,10 @@ struct __GLXDRIscreenRec { struct __GLXDRIcontextRec { - void (*destroyContext) (__GLXDRIcontext * context, - __GLXscreenConfigs * psc, Display * dpy); - Bool(*bindContext) (__GLXDRIcontext * context, __GLXDRIdrawable * pdraw, - __GLXDRIdrawable * pread); - - void (*unbindContext) (__GLXDRIcontext * context); + void (*destroyContext) (__GLXcontext *context); + Bool(*bindContext) (__GLXcontext *context, __GLXDRIdrawable *pdraw, + __GLXDRIdrawable *pread); + void (*unbindContext) (__GLXcontext *context); }; struct __GLXDRIdrawableRec @@ -389,11 +386,6 @@ struct __GLXcontextRec /*@} */ /** - * Record the dpy this context was created on for later freeing - */ - Display *createDpy; - - /** * Maximum small render command size. This is the smaller of 64k and * the size of the above buffer. */ @@ -463,6 +455,10 @@ struct __GLXcontextRec const struct glx_context_vtable *vtable; }; +extern Bool +glx_context_init(__GLXcontext *gc, + __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig); + #define __glXSetError(gc,code) \ if (!(gc)->error) { \ (gc)->error = code; \ @@ -515,11 +511,6 @@ struct __GLXscreenConfigsRec */ char *effectiveGLXexts; - /** - * Context vtable to use for direct contexts on this screen - */ - const struct glx_context_vtable *direct_context_vtable; - __GLXdisplayPrivate *display; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index a9f6b17..5eae5a9 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -62,7 +62,7 @@ static const char __glXGLXClientVendorName[] = "Mesa Project and SGI"; static const char __glXGLXClientVersion[] = "1.4"; -static const struct glx_context_vtable glx_indirect_context_vtable; +static const struct glx_context_vtable indirect_context_vtable; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) @@ -272,6 +272,7 @@ AllocateGLXContext(Display * dpy) } memset(gc, 0, sizeof(struct __GLXcontextRec)); + gc->vtable = &indirect_context_vtable; state = Xmalloc(sizeof(struct __GLXattributeRec)); if (state == NULL) { /* Out of memory */ @@ -325,7 +326,6 @@ AllocateGLXContext(Display * dpy) else { gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; } - gc->createDpy = dpy; gc->majorOpcode = opcode; /* @@ -350,6 +350,22 @@ AllocateGLXContext(Display * dpy) return gc; } +_X_HIDDEN Bool +glx_context_init(__GLXcontext *gc, + __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig) +{ + gc->majorOpcode = __glXSetupForCommand(psc->display->dpy); + if (!gc->majorOpcode) + return GL_FALSE; + + gc->screen = psc->scr; + gc->psc = psc; + gc->mode = fbconfig; + gc->isDirect = GL_TRUE; + + return GL_TRUE; +} + /** * Create a new context. Exactly one of \c vis and \c fbconfig should be @@ -367,7 +383,7 @@ CreateContext(Display * dpy, int generic_id, Bool allowDirect, unsigned code, int renderType, int screen) { - GLXContext gc; + GLXContext gc = NULL; __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); #if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL) int errorcode; @@ -380,28 +396,18 @@ CreateContext(Display * dpy, int generic_id, if (generic_id == None) return NULL; - gc = AllocateGLXContext(dpy); - if (!gc) - return NULL; - #ifndef GLX_USE_APPLEGL /* TODO: darwin indirect */ #ifdef GLX_DIRECT_RENDERING if (allowDirect && psc->driScreen) { - gc->driContext = psc->driScreen->createContext(psc, fbconfig, gc, - shareList, renderType); - if (gc->driContext != NULL) { - gc->screen = screen; - gc->psc = psc; - gc->mode = fbconfig; - gc->isDirect = GL_TRUE; - } + gc = psc->driScreen->createContext(psc, fbconfig, + shareList, renderType); } #endif - if (gc->driContext != NULL) - gc->vtable = psc->direct_context_vtable; - else - gc->vtable = &glx_indirect_context_vtable; + if (!gc) + gc = AllocateGLXContext(dpy); + if (!gc) + return NULL; LockDisplay(dpy); switch (code) { @@ -570,54 +576,54 @@ DestroyContext(Display * dpy, GLXContext gc) return; } -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) +#if defined(GLX_DIRECT_RENDERING) /* Destroy the direct rendering context */ if (gc->driContext) { - (*gc->driContext->destroyContext) (gc->driContext, gc->psc, dpy); - gc->driContext = NULL; GarbageCollectDRIDrawables(gc->psc); + if (gc->extensions) + XFree((char *) gc->extensions); + (*gc->driContext->destroyContext) (gc); } + else #endif + { + __glXFreeVertexArrayState(gc); + __glXFreeContext(gc); + } + + if (!imported) { + /* + ** This dpy also created the server side part of the context. + ** Send the glXDestroyContext request. + */ + LockDisplay(dpy); + GetReq(GLXDestroyContext, req); + req->reqType = opcode; + req->glxCode = X_GLXDestroyContext; + req->context = xid; + UnlockDisplay(dpy); + SyncHandle(); + } - __glXFreeVertexArrayState(gc); #else - __glXLock(); -#endif /* GLX_USE_APPLEGL */ + __glXLock(); if (gc->currentDpy) { -#ifdef GLX_USE_APPLEGL /* * Set the Bool that indicates that we should destroy this GLX context * when the context is no longer current. */ gc->do_destroy = True; -#endif /* Have to free later cuz it's in use now */ __glXUnlock(); } else { /* Destroy the handle if not current to anybody */ __glXUnlock(); -#ifdef GLX_USE_APPLEGL if(gc->driContext) - apple_glx_destroy_context(&gc->driContext, dpy); -#endif + apple_glx_destroy_context(&gc->driContext, dpy); __glXFreeContext(gc); } -#ifndef GLX_USE_APPLEGL - if (!imported) { - /* - ** This dpy also created the server side part of the context. - ** Send the glXDestroyContext request. - */ - LockDisplay(dpy); - GetReq(GLXDestroyContext, req); - req->reqType = opcode; - req->glxCode = X_GLXDestroyContext; - req->context = xid; - UnlockDisplay(dpy); - SyncHandle(); - } #endif } @@ -2711,9 +2717,9 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, * GLX_EXT_texture_from_pixmap */ static void -glx_indirect_bind_tex_image(Display * dpy, - GLXDrawable drawable, - int buffer, const int *attrib_list) +indirect_bind_tex_image(Display * dpy, + GLXDrawable drawable, + int buffer, const int *attrib_list) { xGLXVendorPrivateReq *req; GLXContext gc = __glXGetCurrentContext(); @@ -2764,7 +2770,7 @@ glx_indirect_bind_tex_image(Display * dpy, } static void -glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) +indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) { xGLXVendorPrivateReq *req; GLXContext gc = __glXGetCurrentContext(); @@ -2793,9 +2799,9 @@ glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) SyncHandle(); } -static const struct glx_context_vtable glx_indirect_context_vtable = { - glx_indirect_bind_tex_image, - glx_indirect_release_tex_image, +static const struct glx_context_vtable indirect_context_vtable = { + indirect_bind_tex_image, + indirect_release_tex_image, }; /*@{*/ diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index 43469c3..0bf6177 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -399,7 +399,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, } bindReturnValue = - (gc->driContext->bindContext) (gc->driContext, pdraw, pread); + (gc->driContext->bindContext) (gc, pdraw, pread); } else if (!gc && oldGC && oldGC->driContext) { bindReturnValue = True; @@ -441,7 +441,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) else if (oldGC->driContext && oldGC != gc) { - oldGC->driContext->unbindContext(oldGC->driContext); + oldGC->driContext->unbindContext(oldGC); } #endif @@ -488,9 +488,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /* Destroy the old direct rendering context */ if (oldGC->driContext) { - oldGC->driContext->destroyContext(oldGC->driContext, - oldGC->psc, - oldGC->createDpy); + oldGC->driContext->destroyContext(oldGC); oldGC->driContext = NULL; } #endif -- 2.7.4