summaryrefslogtreecommitdiff
path: root/src/glx
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-07-23 16:15:31 -0400
committerKristian Høgsberg <krh@bitplanet.net>2010-07-23 22:05:53 -0400
commit6ec39db726beead21d97bf64ddbe1f0b2d2d6ca1 (patch)
tree65a665c1d10ab43618a2c508081a7cc7d31ab9ab /src/glx
parentb5dedd7c3b4425127d8b85b7e8df0ecda4009fd7 (diff)
glx: Refactor and simplify context creation
This lets us better separate context creation between the different backends.
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/dri2_glx.c11
-rw-r--r--src/glx/dri_glx.c12
-rw-r--r--src/glx/drisw_glx.c12
-rw-r--r--src/glx/glxclient.h11
-rw-r--r--src/glx/glxcmds.c327
-rw-r--r--src/glx/glxext.c17
6 files changed, 185 insertions, 205 deletions
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 02c0f9f24e..58f09ed86a 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 ff7ca5ef7d..95cded792d 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 c971de2f76..4265f56412 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 20c4529131..48b5501fe9 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 72ac3ecd7d..1ded6247ef 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 324230f5e3..f9a5f7ce5d 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();