From 6ec39db726beead21d97bf64ddbe1f0b2d2d6ca1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 23 Jul 2010 16:15:31 -0400 Subject: [PATCH] glx: Refactor and simplify context creation This lets us better separate context creation between the different backends. --- src/glx/dri2_glx.c | 11 +- src/glx/dri_glx.c | 12 +- src/glx/drisw_glx.c | 12 +- src/glx/glxclient.h | 11 ++ src/glx/glxcmds.c | 327 ++++++++++++++++++++------------------------ src/glx/glxext.c | 17 +-- 6 files changed, 185 insertions(+), 205 deletions(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 02c0f9f24ee..58f09ed86af 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -154,9 +154,9 @@ dri2UnbindContext(__GLXcontext *context) } static __GLXcontext * -dri2CreateContext(__GLXscreenConfigs *base, - const __GLcontextModes * mode, - GLXContext shareList, int renderType) +dri2_create_context(__GLXscreenConfigs *base, + const __GLcontextModes * mode, + GLXContext shareList, int renderType) { struct dri2_context *pcp, *pcp_shared; struct dri2_screen *psc = (struct dri2_screen *) base; @@ -718,6 +718,9 @@ dri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions) } } +static const struct glx_screen_vtable dri2_screen_vtable = { + dri2_create_context +}; static __GLXscreenConfigs * dri2CreateScreen(int screen, __GLXdisplayPrivate * priv) @@ -811,10 +814,10 @@ dri2CreateScreen(int screen, __GLXdisplayPrivate * priv) psc->driver_configs = driver_configs; + psc->base.vtable = &dri2_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; psp->destroyScreen = dri2DestroyScreen; - psp->createContext = dri2CreateContext; psp->createDrawable = dri2CreateDrawable; psp->swapBuffers = dri2SwapBuffers; psp->getDrawableMSC = NULL; diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index ff7ca5ef7d6..95cded792d9 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -550,9 +550,9 @@ static const struct glx_context_vtable dri_context_vtable = { }; static __GLXcontext * -driCreateContext(__GLXscreenConfigs *base, - const __GLcontextModes * mode, - GLXContext shareList, int renderType) +dri_create_context(__GLXscreenConfigs *base, + const __GLcontextModes *mode, + GLXContext shareList, int renderType) { struct dri_context *pcp, *pcp_shared; struct dri_screen *psc = (struct dri_screen *) base; @@ -821,6 +821,10 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions) } } +static const struct glx_screen_vtable dri_screen_vtable = { + dri_create_context +}; + static __GLXscreenConfigs * driCreateScreen(int screen, __GLXdisplayPrivate *priv) { @@ -882,13 +886,13 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) extensions = psc->core->getExtensions(psc->driScreen); driBindExtensions(psc, extensions); + psc->base.vtable = &dri_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; if (psc->driCopySubBuffer) psp->copySubBuffer = driCopySubBuffer; psp->destroyScreen = driDestroyScreen; - psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index c971de2f76f..4265f564120 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -289,9 +289,9 @@ static const struct glx_context_vtable drisw_context_vtable = { }; static __GLXcontext * -driCreateContext(__GLXscreenConfigs *base, - const __GLcontextModes *mode, - GLXContext shareList, int renderType) +drisw_create_context(__GLXscreenConfigs *base, + const __GLcontextModes *mode, + GLXContext shareList, int renderType) { struct drisw_context *pcp, *pcp_shared; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; @@ -426,6 +426,10 @@ driOpenSwrast(void) return driver; } +static const struct glx_screen_vtable drisw_screen_vtable = { + drisw_create_context +}; + static __GLXscreenConfigs * driCreateScreen(int screen, __GLXdisplayPrivate *priv) { @@ -482,10 +486,10 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) psc->driver_configs = driver_configs; + psc->base.vtable = &drisw_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; psp->destroyScreen = driDestroyScreen; - psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 20c45291315..48b5501fe9e 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -504,8 +504,16 @@ extern void __glFreeAttributeState(__GLXcontext *); * One of these records exists per screen of the display. It contains * a pointer to the config data for that screen (if the screen supports GL). */ +struct glx_screen_vtable { + __GLXcontext *(*create_context)(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext shareList, int renderType); +}; + struct __GLXscreenConfigsRec { + const struct glx_screen_vtable *vtable; + /** * GLX extension string reported by the X-server. */ @@ -799,4 +807,7 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable); #endif +extern __GLXscreenConfigs * +indirect_create_screen(int screen, __GLXdisplayPrivate * priv); + #endif /* !__GLX_client_h__ */ diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 72ac3ecd7d7..1ded6247ef3 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -234,6 +234,55 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config) return NULL; } +#ifdef GLX_USE_APPLEGL + +static const struct glx_context_vtable applegl_context_vtable; + +static __GLcontext * +applegl_create_context(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext shareList, int renderType) +{ + __GLXcontext *gc; + int errorcode; + bool x11error; + + /* TODO: Integrate this with apple_glx_create_context and make + * struct apple_glx_context inherit from __GLXcontext. */ + + gc = Xmalloc(sizeof *gc); + if (pcp == NULL) + return NULL; + + memset(gc, 0, sizeof *gc); + if (!glx_context_init(&gc->base, &psc->base, mode)) { + Xfree(gc); + return NULL; + } + + gc->vtable = &applegl_context_vtable; + gc->driContext = NULL; + gc->do_destroy = False; + + /* TODO: darwin: Integrate with above to do indirect */ + if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, + shareList ? shareList->driContext : NULL, + &errorcode, &x11error)) { + __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error); + gc->vtable->destroy(gc); + return NULL; + } + + gc->currentContextTag = -1; + gc->mode = fbconfig; + gc->isDirect = allowDirect; + gc->xid = 1; /* Just something not None, so we know when to destroy + * it in MakeContextCurrent. */ + + return gc; +} +#endif + /** * \todo It should be possible to move the allocate of \c client_state_private @@ -246,17 +295,16 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config) * does all the initialization (including the pixel pack / unpack). */ static GLXContext -AllocateGLXContext(Display * dpy) +indirect_create_context(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext shareList, int renderType) { GLXContext gc; int bufSize; CARD8 opcode; __GLXattribute *state; - if (!dpy) - return NULL; - - opcode = __glXSetupForCommand(dpy); + opcode = __glXSetupForCommand(psc->dpy); if (!opcode) { return NULL; } @@ -269,6 +317,8 @@ AllocateGLXContext(Display * dpy) } memset(gc, 0, sizeof(struct __GLXcontextRec)); + glx_context_init(gc, psc, mode); + gc->isDirect = GL_FALSE; gc->vtable = &indirect_context_vtable; state = Xmalloc(sizeof(struct __GLXattributeRec)); if (state == NULL) { @@ -287,7 +337,7 @@ AllocateGLXContext(Display * dpy) ** packet for the GLXRenderReq header. */ - bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq; + bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq; gc->buf = (GLubyte *) Xmalloc(bufSize); if (!gc->buf) { Xfree(gc->client_state_private); @@ -339,14 +389,31 @@ AllocateGLXContext(Display * dpy) } gc->maxSmallRenderCommandSize = bufSize; -#ifdef GLX_USE_APPLEGL - gc->driContext = NULL; - gc->do_destroy = False; -#endif return gc; } +struct glx_screen_vtable indirect_screen_vtable = { + indirect_create_context +}; + +_X_HIDDEN __GLXscreenConfigs * +indirect_create_screen(int screen, __GLXdisplayPrivate * priv) +{ + __GLXscreenConfigs *psc; + + psc = Xmalloc(sizeof *psc); + if (psc == NULL) + return NULL; + + memset(psc, 0, sizeof *psc); + glx_screen_init(psc, screen, priv); + psc->vtable = &indirect_screen_vtable; + + return psc; +} + + _X_HIDDEN Bool glx_context_init(__GLXcontext *gc, __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig) @@ -382,27 +449,19 @@ CreateContext(Display * dpy, int generic_id, { GLXContext gc = NULL; __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); -#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL) - int errorcode; - bool x11error; -#endif - + if (dpy == NULL) return NULL; if (generic_id == None) return NULL; -#ifndef GLX_USE_APPLEGL /* TODO: darwin indirect */ -#ifdef GLX_DIRECT_RENDERING - if (allowDirect && psc->driScreen) { - gc = psc->driScreen->createContext(psc, fbconfig, - shareList, renderType); - } -#endif - + gc = NULL; + if (allowDirect && psc->vtable->create_context) + gc = psc->vtable->create_context(psc, fbconfig, + shareList, renderType); if (!gc) - gc = AllocateGLXContext(dpy); + gc = indirect_create_context(psc, fbconfig, shareList, renderType); if (!gc) return NULL; @@ -469,26 +528,10 @@ CreateContext(Display * dpy, int generic_id, UnlockDisplay(dpy); SyncHandle(); -#endif gc->imported = GL_FALSE; gc->renderType = renderType; - /* TODO: darwin: Integrate with above to do indirect */ -#ifdef GLX_USE_APPLEGL - if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, - shareList ? shareList->driContext : NULL, - &errorcode, &x11error)) { - __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error); - gc->vtable->destroy(gc); - return NULL; - } - - gc->currentContextTag = -1; - gc->mode = fbconfig; - gc->isDirect = allowDirect; -#endif - return gc; } @@ -1633,122 +1676,103 @@ GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (), glXGetCurrentDisplay) #ifndef GLX_USE_APPLEGL -/** - * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests - * to the X-server. - * - * \param dpy Display where \c ctx was created. - * \param ctx Context to query. - * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid, - * or zero if the request failed due to internal problems (i.e., - * unable to allocate temporary memory, etc.) - * - * \note - * This function dynamically determines whether to use the EXT_import_context - * version of the protocol or the GLX 1.3 version of the protocol. - */ -static int __glXQueryContextInfo(Display * dpy, GLXContext ctx) +PUBLIC GLXContext +glXImportContextEXT(Display *dpy, GLXContextID contextID) { __GLXdisplayPrivate *priv = __glXInitialize(dpy); + __GLXscreenConfigs *psc; xGLXQueryContextReply reply; CARD8 opcode; - GLuint numValues; - int retval; + GLXContext ctx; + int propList[__GLX_MAX_CONTEXT_PROPS * 2], *pProp, nPropListBytes; + int i, renderType; + XID share; + __GLcontextModes *mode; + + if (contextID == None || __glXIsDirect(dpy, contextID)) + return NULL; - if (ctx == NULL) { - return GLX_BAD_CONTEXT; - } opcode = __glXSetupForCommand(dpy); - if (!opcode) { + if (!opcode) return 0; - } /* Send the glXQueryContextInfoEXT request */ LockDisplay(dpy); - if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { + if (priv->majorVersion > 1 || priv->minorVersion >= 3) { xGLXQueryContextReq *req; GetReq(GLXQueryContext, req); req->reqType = opcode; req->glxCode = X_GLXQueryContext; - req->context = (unsigned int) (ctx->xid); + req->context = contextID; } else { xGLXVendorPrivateReq *vpreq; xGLXQueryContextInfoEXTReq *req; GetReqExtra(GLXVendorPrivate, - sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, - vpreq); + sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, + vpreq); req = (xGLXQueryContextInfoEXTReq *) vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_QueryContextInfoEXT; - req->context = (unsigned int) (ctx->xid); + req->context = contextID; } _XReply(dpy, (xReply *) & reply, 0, False); - numValues = reply.n; - if (numValues == 0) - retval = Success; - else if (numValues > __GLX_MAX_CONTEXT_PROPS) - retval = 0; - else { - int *propList, *pProp; - int nPropListBytes; - - nPropListBytes = numValues << 3; - propList = (int *) Xmalloc(nPropListBytes); - if (NULL == propList) { - retval = 0; - } - else { - unsigned i; - - _XRead(dpy, (char *) propList, nPropListBytes); - - /* Look up screen first so we can look up visuals/fbconfigs later */ - pProp = propList; - for (i = 0; i < numValues; i++, pProp += 2) - if (pProp[0] == GLX_SCREEN) { - ctx->screen = pProp[1]; - ctx->psc = GetGLXScreenConfigs(dpy, ctx->screen); - } - - pProp = propList; - for (i = 0; i < numValues; i++) { - switch (*pProp++) { - case GLX_SHARE_CONTEXT_EXT: - ctx->share_xid = *pProp++; - break; - case GLX_VISUAL_ID_EXT: - ctx->mode = - _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++); - break; - case GLX_FBCONFIG_ID: - ctx->mode = - _gl_context_modes_find_fbconfig(ctx->psc->configs, - *pProp++); - break; - case GLX_RENDER_TYPE: - ctx->renderType = *pProp++; - break; - case GLX_SCREEN: - default: - pProp++; - continue; - } - } - Xfree((char *) propList); - retval = Success; - } - } + if (reply.n <= __GLX_MAX_CONTEXT_PROPS) + nPropListBytes = reply.n * 2 * sizeof propList[0]; + else + nPropListBytes = 0; + _XRead(dpy, (char *) propList, nPropListBytes); UnlockDisplay(dpy); SyncHandle(); - return retval; + + /* Look up screen first so we can look up visuals/fbconfigs later */ + psc = NULL; + for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2) + if (pProp[0] == GLX_SCREEN) + psc = GetGLXScreenConfigs(dpy, pProp[1]); + if (psc == NULL) + return NULL; + + share = None; + mode = NULL; + renderType = 0; + pProp = propList; + + for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2) + switch (pProp[0]) { + case GLX_SHARE_CONTEXT_EXT: + share = pProp[1]; + break; + case GLX_VISUAL_ID_EXT: + mode = _gl_context_modes_find_visual(psc->visuals, pProp[1]); + break; + case GLX_FBCONFIG_ID: + mode = _gl_context_modes_find_fbconfig(psc->configs, pProp[1]); + break; + case GLX_RENDER_TYPE: + renderType = pProp[1]; + break; + } + + if (mode == NULL) + return NULL; + + ctx = indirect_create_context(psc, mode, NULL, renderType); + if (ctx == NULL) + return NULL; + + ctx->xid = contextID; + ctx->imported = GL_TRUE; + ctx->share_xid = share; + + return ctx; } #endif @@ -1756,38 +1780,21 @@ static int __glXQueryContextInfo(Display * dpy, GLXContext ctx) PUBLIC int glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value) { -#ifndef GLX_USE_APPLEGL - int retVal; - - /* get the information from the server if we don't have it already */ -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (!ctx->driContext && (ctx->mode == NULL)) { -#else - if (ctx->mode == NULL) { -#endif - retVal = __glXQueryContextInfo(dpy, ctx); - if (Success != retVal) - return retVal; - } -#endif - switch (attribute) { -#ifndef GLX_USE_APPLEGL case GLX_SHARE_CONTEXT_EXT: - *value = (int) (ctx->share_xid); + *value = ctx->share_xid; break; case GLX_VISUAL_ID_EXT: *value = ctx->mode ? ctx->mode->visualID : None; break; -#endif case GLX_SCREEN: - *value = (int) (ctx->screen); + *value = ctx->screen; break; case GLX_FBCONFIG_ID: *value = ctx->mode ? ctx->mode->fbconfigID : None; break; case GLX_RENDER_TYPE: - *value = (int) (ctx->renderType); + *value = ctx->renderType; break; default: return GLX_BAD_ATTRIBUTE; @@ -1805,35 +1812,6 @@ PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx) return ctx->xid; } -PUBLIC GLXContext -glXImportContextEXT(Display * dpy, GLXContextID contextID) -{ -#ifdef GLX_USE_APPLEGL - return NULL; -#else - GLXContext ctx; - - if (contextID == None) { - return NULL; - } - if (__glXIsDirect(dpy, contextID)) { - return NULL; - } - - ctx = AllocateGLXContext(dpy); - if (NULL != ctx) { - ctx->xid = contextID; - ctx->imported = GL_TRUE; - - if (Success != __glXQueryContextInfo(dpy, ctx)) { - ctx->vtable->destroy(ctx); - ctx = NULL; - } - } - return ctx; -#endif -} - PUBLIC void glXFreeContextEXT(Display * dpy, GLXContext ctx) { @@ -1841,11 +1819,6 @@ glXFreeContextEXT(Display * dpy, GLXContext ctx) } - -/* - * GLX 1.3 functions - these are just stubs for now! - */ - PUBLIC GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int *attribList, int *nitems) diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 324230f5e3e..f9a5f7ce5d7 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -738,21 +738,6 @@ glx_screen_init(__GLXscreenConfigs *psc, return GL_TRUE; } -static __GLXscreenConfigs * -createIndirectScreen(int screen, __GLXdisplayPrivate * priv) -{ - __GLXscreenConfigs *psc; - - psc = Xmalloc(sizeof *psc); - if (psc == NULL) - return NULL; - - memset(psc, 0, sizeof *psc); - glx_screen_init(psc, screen, priv); - - return psc; -} - /* ** Allocate the memory for the per screen configs for each screen. ** If that works then fetch the per screen configs data. @@ -789,7 +774,7 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) psc = (*priv->driswDisplay->createScreen) (i, priv); #endif if (psc == NULL) - psc = createIndirectScreen (i, priv); + psc = indirect_create_screen(i, priv); priv->screenConfigs[i] = psc; } SyncHandle(); -- 2.30.2