diff options
author | David Reveman <c99drn@cs.umu.se> | 2005-04-19 14:51:29 +0000 |
---|---|---|
committer | David Reveman <c99drn@cs.umu.se> | 2005-04-19 14:51:29 +0000 |
commit | 4e914c5ed7679a1102f3e25af0c087380f834865 (patch) | |
tree | e04992f21349aa46a40a63f5082e8cd05ac88426 | |
parent | 6bde764de102a56d2c71b971eaa36535e9760b52 (diff) |
Hash texture objects and display lists in Xgl
-rw-r--r-- | hw/xgl/Makefile.am | 4 | ||||
-rw-r--r-- | hw/xgl/xgl.h | 32 | ||||
-rw-r--r-- | hw/xgl/xglglx.c | 807 | ||||
-rw-r--r-- | hw/xgl/xglhash.c | 118 |
4 files changed, 910 insertions, 51 deletions
diff --git a/hw/xgl/Makefile.am b/hw/xgl/Makefile.am index f63e0cc3b..eb92a9994 100644 --- a/hw/xgl/Makefile.am +++ b/hw/xgl/Makefile.am @@ -30,4 +30,6 @@ libxgl_a_SOURCES = \ xglcomp.c \ xglpict.c \ xglglyph.c \ - xgltrap.c + xgltrap.c \ + xglhash.c \ + xglglx.c diff --git a/hw/xgl/xgl.h b/hw/xgl/xgl.h index f7c6102df..82680e368 100644 --- a/hw/xgl/xgl.h +++ b/hw/xgl/xgl.h @@ -1371,6 +1371,38 @@ xglAddTraps (PicturePtr pDst, #ifdef GLXEXT +typedef struct _xglHashTable *xglHashTablePtr; + +xglHashTablePtr +xglNewHashTable (void); + +void +xglDeleteHashTable (xglHashTablePtr pTable); + +void * +xglHashLookup (const xglHashTablePtr pTable, + unsigned int key); + +void +xglHashInsert (xglHashTablePtr pTable, + unsigned int key, + void *data); + +void +xglHashRemove (xglHashTablePtr pTable, + unsigned int key); + +unsigned int +xglHashFirstEntry (xglHashTablePtr pTable); + +unsigned int +xglHashNextEntry (const xglHashTablePtr pTable, + unsigned int key); + +unsigned int +xglHashFindFreeKeyBlock (xglHashTablePtr pTable, + unsigned int numKeys); + Bool xglInitVisualConfigs (ScreenPtr pScreen); diff --git a/hw/xgl/xglglx.c b/hw/xgl/xglglx.c index a036362d6..40d8ec5bb 100644 --- a/hw/xgl/xglglx.c +++ b/hw/xgl/xglglx.c @@ -101,6 +101,8 @@ typedef int xglGLXVisualConfigRec, *xglGLXVisualConfigPtr; typedef struct _xglGLContext { __GLinterface iface; __GLinterface *mIface; + int refcnt; + struct _xglGLContext *shared; glitz_context_t *context; __glProcTableEXT glRenderTableEXT; PFNGLWINDOWPOS3FMESAPROC WindowPos3fMESA; @@ -110,9 +112,21 @@ typedef struct _xglGLContext { int tx, ty; xRectangle viewport; xRectangle scissor; + GLboolean scissorTest; char *versionString; + GLenum error; + xglHashTablePtr texObjects; + xglHashTablePtr displayLists; } xglGLContextRec, *xglGLContextPtr; +typedef struct _xglTexObj { + GLuint name; +} xglTexObjRec, *xglTexObjPtr; + +typedef struct _xglDisplayList { + GLuint name; +} xglDisplayListRec, *xglDisplayListPtr; + xglGLContextPtr cctx = NULL; static void @@ -141,8 +155,9 @@ xglScissor (GLint x, cctx->scissor.width = width; cctx->scissor.height = height; - glitz_context_set_scissor (cctx->context, - cctx->tx + x, cctx->ty + y, width, height); + if (cctx->scissorTest) + glitz_context_set_scissor (cctx->context, + cctx->tx + x, cctx->ty + y, width, height); } static void @@ -154,8 +169,42 @@ xglDrawBuffer (GLenum mode) static void xglDisable (GLenum cap) { - if (cap != GL_SCISSOR_TEST) + switch (cap) { + case GL_SCISSOR_TEST: + if (cctx->scissorTest) + { + __GLcontext *gc = (__GLcontext *) cctx; + __GLinterface *i = cctx->mIface; + __GLdrawablePrivate *drawPriv = i->imports.getDrawablePrivate (gc); + xglGLBufferPtr pDrawBufferPriv = drawPriv->private; + DrawablePtr pDrawable = pDrawBufferPriv->pDrawable; + + cctx->scissorTest = GL_FALSE; + glitz_context_set_scissor (cctx->context, + cctx->tx, cctx->ty, + pDrawable->width, pDrawable->height); + } + break; + default: glDisable (cap); + } +} + +static void +xglEnable (GLenum cap) +{ + switch (cap) { + case GL_SCISSOR_TEST: + cctx->scissorTest = GL_TRUE; + glitz_context_set_scissor (cctx->context, + cctx->tx + cctx->scissor.x, + cctx->ty + cctx->scissor.y, + cctx->scissor.width, + cctx->scissor.height); + break; + default: + glEnable (cap); + } } static void @@ -175,6 +224,215 @@ xglCopyPixels (GLint x, x, y, width, height, type); } +static GLint +xglGetTextureBinding (GLenum pname) +{ + xglTexObjPtr pTexObj; + GLuint key; + GLint texture; + + glGetIntegerv (pname, &texture); + + key = xglHashFirstEntry (cctx->shared->texObjects); + while (key) + { + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, key); + if (pTexObj && pTexObj->name == texture) + return key; + + key = xglHashNextEntry (cctx->shared->texObjects, key); + } + + return 0; +} + +#define INT_TO_BOOLEAN(I) ((I) ? GL_TRUE : GL_FALSE) +#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE) + +static void +xglGetBooleanv (GLenum pname, + GLboolean *params) +{ + switch (pname) { + case GL_DOUBLEBUFFER: + params[0] = GL_TRUE; + break; + case GL_DRAW_BUFFER: + params[0] = ENUM_TO_BOOLEAN (GL_BACK); + break; + case GL_READ_BUFFER: + params[0] = ENUM_TO_BOOLEAN (GL_BACK); + break; + case GL_SCISSOR_BOX: + params[0] = INT_TO_BOOLEAN (cctx->scissor.x); + params[1] = INT_TO_BOOLEAN (cctx->scissor.y); + params[2] = INT_TO_BOOLEAN (cctx->scissor.width); + params[3] = INT_TO_BOOLEAN (cctx->scissor.height); + break; + case GL_SCISSOR_TEST: + params[0] = cctx->scissorTest; + break; + case GL_VIEWPORT: + params[0] = INT_TO_BOOLEAN (cctx->viewport.x); + params[1] = INT_TO_BOOLEAN (cctx->viewport.y); + params[2] = INT_TO_BOOLEAN (cctx->viewport.width); + params[3] = INT_TO_BOOLEAN (cctx->viewport.height); + break; + case GL_TEXTURE_BINDING_1D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_3D: + /* should be safe to fall-through here */ + default: + glGetBooleanv (pname, params); + } +} + +#define ENUM_TO_DOUBLE(E) ((GLdouble) (E)) +#define BOOLEAN_TO_DOUBLE(B) ((B) ? 1.0F : 0.0F) + +static void +xglGetDoublev (GLenum pname, + GLdouble *params) +{ + switch (pname) { + case GL_DOUBLEBUFFER: + params[0] = BOOLEAN_TO_DOUBLE (GL_TRUE); + break; + case GL_DRAW_BUFFER: + params[0] = ENUM_TO_DOUBLE (GL_BACK); + break; + case GL_READ_BUFFER: + params[0] = ENUM_TO_DOUBLE (GL_BACK); + break; + case GL_SCISSOR_BOX: + params[0] = cctx->scissor.x; + params[1] = cctx->scissor.y; + params[2] = cctx->scissor.width; + params[3] = cctx->scissor.height; + break; + case GL_SCISSOR_TEST: + params[0] = BOOLEAN_TO_DOUBLE (cctx->scissorTest); + break; + case GL_VIEWPORT: + params[0] = cctx->viewport.x; + params[1] = cctx->viewport.y; + params[2] = cctx->viewport.width; + params[3] = cctx->viewport.height; + break; + case GL_TEXTURE_BINDING_1D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_3D: + params[0] = xglGetTextureBinding (pname); + break; + default: + glGetDoublev (pname, params); + } +} + +#define ENUM_TO_FLOAT(E) ((GLfloat) (E)) +#define BOOLEAN_TO_FLOAT(B) ((B) ? 1.0F : 0.0F) + +static void +xglGetFloatv (GLenum pname, + GLfloat *params) +{ + switch (pname) { + case GL_DOUBLEBUFFER: + params[0] = BOOLEAN_TO_FLOAT (GL_TRUE); + break; + case GL_DRAW_BUFFER: + params[0] = ENUM_TO_FLOAT (GL_BACK); + break; + case GL_READ_BUFFER: + params[0] = ENUM_TO_FLOAT (GL_BACK); + break; + case GL_SCISSOR_BOX: + params[0] = cctx->scissor.x; + params[1] = cctx->scissor.y; + params[2] = cctx->scissor.width; + params[3] = cctx->scissor.height; + break; + case GL_SCISSOR_TEST: + params[0] = BOOLEAN_TO_FLOAT (cctx->scissorTest); + break; + case GL_VIEWPORT: + params[0] = cctx->viewport.x; + params[1] = cctx->viewport.y; + params[2] = cctx->viewport.width; + params[3] = cctx->viewport.height; + break; + case GL_TEXTURE_BINDING_1D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_3D: + params[0] = xglGetTextureBinding (pname); + break; + default: + glGetFloatv (pname, params); + } +} + +#define ENUM_TO_INT(E) ((GLint) (E)) +#define BOOLEAN_TO_INT(B) ((GLint) (B)) + +static void +xglGetIntegerv (GLenum pname, + GLint *params) +{ + switch (pname) { + case GL_DOUBLEBUFFER: + params[0] = BOOLEAN_TO_INT (GL_TRUE); + break; + case GL_DRAW_BUFFER: + params[0] = ENUM_TO_INT (GL_BACK); + break; + case GL_READ_BUFFER: + params[0] = ENUM_TO_INT (GL_BACK); + break; + case GL_SCISSOR_BOX: + params[0] = cctx->scissor.x; + params[1] = cctx->scissor.y; + params[2] = cctx->scissor.width; + params[3] = cctx->scissor.height; + break; + case GL_SCISSOR_TEST: + params[0] = BOOLEAN_TO_INT (cctx->scissorTest); + break; + case GL_VIEWPORT: + params[0] = cctx->viewport.x; + params[1] = cctx->viewport.y; + params[2] = cctx->viewport.width; + params[3] = cctx->viewport.height; + break; + case GL_TEXTURE_BINDING_1D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_3D: + params[0] = xglGetTextureBinding (pname); + break; + default: + glGetIntegerv (pname, params); + } +} + +static GLboolean +xglIsEnabled (GLenum cap) +{ + switch (cap) { + case GL_SCISSOR_TEST: + return cctx->scissorTest; + default: + return glIsEnabled (cap); + } +} + +static GLenum +xglGetError (void) +{ + if (cctx->error != GL_NO_ERROR) + return cctx->error; + + return glGetError (); +} + static const GLubyte * xglGetString (GLenum name) { @@ -196,13 +454,380 @@ xglGetString (GLenum name) } } +static void +xglGenTextures (GLsizei n, + GLuint *textures) +{ + xglTexObjPtr pTexObj; + GLuint name; + + name = xglHashFindFreeKeyBlock (cctx->shared->texObjects, n); + + glGenTextures (n, textures); + + while (n--) + { + pTexObj = xalloc (sizeof (xglTexObjRec)); + if (pTexObj) + { + pTexObj->name = *textures; + xglHashInsert (cctx->shared->texObjects, name, pTexObj); + } + else + { + glDeleteTextures (1, textures); + cctx->error = GL_OUT_OF_MEMORY; + } + + *textures++ = name++; + } +} + +static void +xglBindTexture (GLenum target, + GLuint texture) +{ + if (texture) + { + xglTexObjPtr pTexObj; + + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, + texture); + if (!pTexObj) + { + pTexObj = xalloc (sizeof (xglTexObjRec)); + if (!pTexObj) + { + cctx->error = GL_OUT_OF_MEMORY; + return; + } + + glGenTextures (1, &pTexObj->name); + xglHashInsert (cctx->shared->texObjects, texture, pTexObj); + } + + glBindTexture (target, pTexObj->name); + } + else + glBindTexture (target, 0); +} + +static GLboolean +xglAreTexturesResident (GLsizei n, + const GLuint *textures, + GLboolean *residences) +{ + GLboolean allResident = GL_TRUE; + int i, j; + + if (n < 0) + { + cctx->error = GL_INVALID_VALUE; + return GL_FALSE; + } + + if (!textures || !residences) + return GL_FALSE; + + for (i = 0; i < n; i++) + { + xglTexObjPtr pTexObj; + GLboolean resident; + + if (textures[i] == 0) + { + cctx->error = GL_INVALID_VALUE; + return GL_FALSE; + } + + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, + textures[i]); + if (!pTexObj) + { + cctx->error = GL_INVALID_VALUE; + return GL_FALSE; + } + + if (glAreTexturesResident (1, &pTexObj->name, &resident)) + { + if (!allResident) + residences[i] = GL_TRUE; + } + else + { + if (allResident) + { + allResident = GL_FALSE; + + for (j = 0; j < i; j++) + residences[j] = GL_TRUE; + } + residences[i] = GL_FALSE; + } + } + + return allResident; +} + +static void +xglDeleteTextures (GLsizei n, + const GLuint *textures) +{ + xglTexObjPtr pTexObj; + + while (n--) + { + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, + *textures); + if (pTexObj) + { + glDeleteTextures (1, &pTexObj->name); + xglHashRemove (cctx->shared->texObjects, *textures); + xfree (pTexObj); + } + textures++; + } +} + +static GLboolean +xglIsTexture (GLuint texture) +{ + xglTexObjPtr pTexObj; + + if (!texture) + return GL_FALSE; + + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, texture); + if (pTexObj) + return glIsTexture (pTexObj->name); + + return GL_FALSE; +} + +static void +xglPrioritizeTextures (GLsizei n, + const GLuint *textures, + const GLclampf *priorities) +{ + xglTexObjPtr pTexObj; + int i; + + if (n < 0) + { + cctx->error = GL_INVALID_VALUE; + return; + } + + if (!priorities) + return; + + for (i = 0; i < n; i++) + { + if (textures[i] <= 0) + continue; + + pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, + textures[i]); + if (pTexObj) + glPrioritizeTextures (1, &pTexObj->name, &priorities[i]); + } +} + +static GLuint +xglGenLists (GLsizei range) +{ + xglDisplayListPtr pDisplayList; + GLuint first, name, lists; + + lists = glGenLists (range); + if (!lists) + return 0; + + first = xglHashFindFreeKeyBlock (cctx->shared->displayLists, range); + + name = first; + for (name = first; range--; name++) + { + pDisplayList = xalloc (sizeof (xglDisplayListRec)); + if (pDisplayList) + { + pDisplayList->name = lists; + xglHashInsert (cctx->shared->displayLists, name, pDisplayList); + } + else + { + glDeleteLists (lists, 1); + cctx->error = GL_OUT_OF_MEMORY; + } + lists++; + } + + return first; +} + +static void +xglNewList (GLuint list, + GLenum mode) +{ + xglDisplayListPtr pDisplayList; + + if (!list) + { + cctx->error = GL_INVALID_VALUE; + return; + } + + pDisplayList = (xglDisplayListPtr) + xglHashLookup (cctx->shared->displayLists, list); + if (!pDisplayList) + { + pDisplayList = xalloc (sizeof (xglDisplayListRec)); + if (!pDisplayList) + { + cctx->error = GL_OUT_OF_MEMORY; + return; + } + + pDisplayList->name = glGenLists (1); + xglHashInsert (cctx->shared->displayLists, list, pDisplayList); + } + + glNewList (pDisplayList->name, mode); +} + +static void +xglCallList (GLuint list) +{ + xglDisplayListPtr pDisplayList; + + if (!list) + { + cctx->error = GL_INVALID_VALUE; + return; + } + + pDisplayList = (xglDisplayListPtr) + xglHashLookup (cctx->shared->displayLists, list); + if (pDisplayList) + glCallList (pDisplayList->name); +} + +static void +xglCallLists (GLsizei n, + GLenum type, + const GLvoid *lists) +{ + xglDisplayListPtr pDisplayList; + GLuint list; + GLint base, i; + + glGetIntegerv (GL_LIST_BASE, &base); + + for (i = 0; i < n; i++) + { + switch (type) { + case GL_BYTE: + list = (GLuint) *(((GLbyte *) lists) + n); + break; + case GL_UNSIGNED_BYTE: + list = (GLuint) *(((GLubyte *) lists) + n); + break; + case GL_SHORT: + list = (GLuint) *(((GLshort *) lists) + n); + break; + case GL_UNSIGNED_SHORT: + list = (GLuint) *(((GLushort *) lists) + n); + break; + case GL_INT: + list = (GLuint) *(((GLint *) lists) + n); + break; + case GL_UNSIGNED_INT: + list = (GLuint) *(((GLuint *) lists) + n); + break; + case GL_FLOAT: + list = (GLuint) *(((GLfloat *) lists) + n); + break; + case GL_2_BYTES: + { + GLubyte *ubptr = ((GLubyte *) lists) + 2 * n; + list = (GLuint) *ubptr * 256 + (GLuint) *(ubptr + 1); + } break; + case GL_3_BYTES: + { + GLubyte *ubptr = ((GLubyte *) lists) + 3 * n; + list = (GLuint) * ubptr * 65536 + + (GLuint) * (ubptr + 1) * 256 + + (GLuint) * (ubptr + 2); + } break; + case GL_4_BYTES: + { + GLubyte *ubptr = ((GLubyte *) lists) + 4 * n; + list = (GLuint) * ubptr * 16777216 + + (GLuint) * (ubptr + 1) * 65536 + + (GLuint) * (ubptr + 2) * 256 + + (GLuint) * (ubptr + 3); + } break; + default: + cctx->error = GL_INVALID_ENUM; + return; + } + + pDisplayList = (xglDisplayListPtr) + xglHashLookup (cctx->shared->displayLists, base + list); + if (pDisplayList) + glCallList (pDisplayList->name); + } +} + +static void +xglDeleteLists (GLuint list, + GLsizei range) +{ + xglDisplayListPtr pDisplayList; + GLint i; + + if (range < 0) + { + cctx->error = GL_INVALID_VALUE; + return; + } + + for (i = 0; i < range; i++) + { + pDisplayList = (xglDisplayListPtr) + xglHashLookup (cctx->shared->displayLists, list + i); + if (pDisplayList) + { + glDeleteLists (pDisplayList->name, 1); + xglHashRemove (cctx->shared->displayLists, list + i); + xfree (pDisplayList); + } + } +} + +static GLboolean +xglIsList (GLuint list) +{ + xglDisplayListPtr pDisplayList; + + if (!list) + return GL_FALSE; + + pDisplayList = (xglDisplayListPtr) + xglHashLookup (cctx->shared->displayLists, list); + if (pDisplayList) + return glIsList (pDisplayList->name); + + return GL_FALSE; +} + __glProcTable __glNativeRenderTable = { - glNewList, + xglNewList, /* glNewList */ glEndList, - glCallList, - glCallLists, - glDeleteLists, - glGenLists, + xglCallList, /* glCallList */ + xglCallLists, /* glCallLists */ + xglDeleteLists, /* glDeleteLists */ + xglGenLists, /* glGenLists */ glListBase, glBegin, glBitmap, @@ -342,7 +967,7 @@ __glProcTable __glNativeRenderTable = { glIndexMask, glAccum, xglDisable, /* glDisable */ - glEnable, + xglEnable, /* glEnable */ glFinish, glFlush, glPopAttrib, @@ -381,12 +1006,12 @@ __glProcTable __glNativeRenderTable = { xglCopyPixels, /* glCopyPixels */ glReadPixels, glDrawPixels, - glGetBooleanv, + xglGetBooleanv, /* glGetBooleanv */ glGetClipPlane, - glGetDoublev, - glGetError, - glGetFloatv, - glGetIntegerv, + xglGetDoublev, /* glGetDoublev */ + xglGetError, /* glGetError */ + xglGetFloatv, /* glGetFloatv */ + xglGetIntegerv, /* glGetIntegerv */ glGetLightfv, glGetLightiv, glGetMapdv, @@ -409,8 +1034,8 @@ __glProcTable __glNativeRenderTable = { glGetTexParameteriv, glGetTexLevelParameterfv, glGetTexLevelParameteriv, - glIsEnabled, - glIsList, + xglIsEnabled, /* glIsEnabled */ + xglIsList, /* glIsList */ glDepthRange, glFrustum, glLoadIdentity, @@ -430,7 +1055,7 @@ __glProcTable __glNativeRenderTable = { glTranslatef, xglViewport, /* glViewport */ glArrayElement, - glBindTexture, + xglBindTexture, /* glBindTexture */ glColorPointer, glDisableClientState, glDrawArrays, @@ -444,16 +1069,16 @@ __glProcTable __glNativeRenderTable = { glPolygonOffset, glTexCoordPointer, glVertexPointer, - glAreTexturesResident, + xglAreTexturesResident, /* glAreTexturesResident */ glCopyTexImage1D, glCopyTexImage2D, glCopyTexSubImage1D, glCopyTexSubImage2D, - glDeleteTextures, - glGenTextures, + xglDeleteTextures, /* glDeleteTextures */ + xglGenTextures, /* glGenTextures */ glGetPointerv, - glIsTexture, - glPrioritizeTextures, + xglIsTexture, /* glIsTexture */ + xglPrioritizeTextures, /* glPrioritizeTextures */ glTexSubImage1D, glTexSubImage2D, glPopClientAttrib, @@ -764,17 +1389,9 @@ xglInitExtensions (xglGLContextPtr pContext) if (strstr (extensions, "GL_EXT_texture_object")) { pContext->glRenderTableEXT.AreTexturesResidentEXT = - (PFNGLARETEXTURESRESIDENTEXTPROC) - glitz_context_get_proc_address (pContext->context, - "glAreTexturesResidentEXT"); - pContext->glRenderTableEXT.GenTexturesEXT = - (PFNGLGENTEXTURESEXTPROC) - glitz_context_get_proc_address (pContext->context, - "glGenTexturesEXT"); - pContext->glRenderTableEXT.IsTextureEXT = - (PFNGLISTEXTUREEXTPROC) - glitz_context_get_proc_address (pContext->context, - "glIsTextureEXT"); + xglAreTexturesResident; + pContext->glRenderTableEXT.GenTexturesEXT = xglGenTextures; + pContext->glRenderTableEXT.IsTextureEXT = xglIsTexture; } if (strstr (extensions, "GL_SGIS_multisample")) @@ -897,16 +1514,80 @@ xglInitExtensions (xglGLContextPtr pContext) pContext->needInit = FALSE; } -static GLboolean -xglDestroyContext (__GLcontext *gc) +static void +xglFreeContext (xglGLContextPtr pContext) { - xglGLContextPtr pContext = (xglGLContextPtr) gc; - __GLinterface *iface = pContext->mIface; + pContext->refcnt--; + if (pContext->shared == pContext) + pContext->refcnt--; + + if (pContext->refcnt) + return; + if (pContext->shared != pContext) + xglFreeContext (pContext->shared); + + if (pContext->texObjects) + { + xglTexObjPtr pTexObj; + GLuint key; + + do { + key = xglHashFirstEntry (pContext->texObjects); + if (key) + { + pTexObj = (xglTexObjPtr) xglHashLookup (pContext->texObjects, + key); + if (pTexObj) + { + glDeleteTextures (1, &pTexObj->name); + xfree (pTexObj); + } + xglHashRemove (pContext->texObjects, key); + } + } while (key); + + xglDeleteHashTable (pContext->texObjects); + } + + if (pContext->displayLists) + { + xglDisplayListPtr pDisplayList; + GLuint key; + + do { + key = xglHashFirstEntry (pContext->displayLists); + if (key) + { + pDisplayList = (xglDisplayListPtr) + xglHashLookup (pContext->displayLists, key); + if (pDisplayList) + { + glDeleteLists (pDisplayList->name, 1); + xfree (pDisplayList); + } + xglHashRemove (pContext->displayLists, key); + } + } while (key); + + xglDeleteHashTable (pContext->displayLists); + } + glitz_context_destroy (pContext->context); + if (pContext->versionString) xfree (pContext->versionString); + xfree (pContext); +} + +static GLboolean +xglDestroyContext (__GLcontext *gc) +{ + xglGLContextPtr pContext = (xglGLContextPtr) gc; + __GLinterface *iface = pContext->mIface; + + xglFreeContext (pContext); return (*iface->exports.destroyContext) ((__GLcontext *) iface); } @@ -993,8 +1674,6 @@ xglShareContext (__GLcontext *gc, __GLinterface *iface = pContext->mIface; __GLinterface *ifaceShare = pContextShare->mIface; - /* NYI. all contexts are currently shared */ - return (*iface->exports.shareContext) ((__GLcontext *) iface, (__GLcontext *) ifaceShare); } @@ -1121,30 +1800,58 @@ xglCreateContext (__GLimports *imports, __GLXcontext *glxCtx = (__GLXcontext *) imports->other; XGL_SCREEN_PRIV (glxCtx->pScreen); - - if (shareGC) - shareIface = pShareContext->mIface; - + + format = glitz_drawable_get_format (pScreenPriv->drawable); + pContext = xalloc (sizeof (xglGLContextRec)); if (!pContext) return NULL; - format = glitz_drawable_get_format (pScreenPriv->drawable); - pContext->context = glitz_context_create (pScreenPriv->drawable, format); - + glitz_context_set_user_data (pContext->context, NULL, + xglLoseCurrentContext); + pContext->needInit = TRUE; pContext->draw = NULL; pContext->target = FALSE; pContext->versionString = NULL; + pContext->scissorTest = GL_FALSE; + pContext->error = GL_NO_ERROR; + + pContext->refcnt = 1; + if (shareGC) + { + pContext->texObjects = NULL; + pContext->displayLists = NULL; + + pContext->shared = pShareContext->shared; + shareIface = pShareContext->mIface; + } + else + { + pContext->texObjects = xglNewHashTable (); + if (!pContext->texObjects) + { + xglFreeContext (pContext); + return NULL; + } + + pContext->displayLists = xglNewHashTable (); + if (!pContext->displayLists) + { + xglFreeContext (pContext); + return NULL; + } + + pContext->shared = pContext; + } + + pContext->shared->refcnt++; - glitz_context_set_user_data (pContext->context, NULL, - xglLoseCurrentContext); - iface = (*screenInfoPriv.createContext) (imports, modes, shareIface); if (!iface) { - xfree (pContext); + xglFreeContext (pContext); return NULL; } diff --git a/hw/xgl/xglhash.c b/hw/xgl/xglhash.c new file mode 100644 index 000000000..a541d7dd4 --- /dev/null +++ b/hw/xgl/xglhash.c @@ -0,0 +1,118 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman <davidr@novell.com> + */ + +#include "xgl.h" + +#ifdef GLXEXT + +/* This is just a wrapper around Mesa's hash functions. */ + +extern struct _mesa_HashTable * +_mesa_NewHashTable (void); + +extern void +_mesa_DeleteHashTable (struct _mesa_HashTable *table); + +extern void * +_mesa_HashLookup (const struct _mesa_HashTable *table, + unsigned int key); + +extern void +_mesa_HashInsert (struct _mesa_HashTable *table, + unsigned int key, + void *data); + +extern void +_mesa_HashRemove (struct _mesa_HashTable *table, + unsigned int key); + +extern unsigned int +_mesa_HashFirstEntry (struct _mesa_HashTable *table); + +extern unsigned int +_mesa_HashNextEntry (const struct _mesa_HashTable *table, + unsigned int key); + +extern unsigned int +_mesa_HashFindFreeKeyBlock (struct _mesa_HashTable *table, + unsigned int numKeys); + + +xglHashTablePtr +xglNewHashTable (void) +{ + return (xglHashTablePtr) _mesa_NewHashTable (); +} + +void +xglDeleteHashTable (xglHashTablePtr pTable) +{ + _mesa_DeleteHashTable ((struct _mesa_HashTable *) pTable); +} + +void * +xglHashLookup (const xglHashTablePtr pTable, + unsigned int key) +{ + return _mesa_HashLookup ((struct _mesa_HashTable *) pTable, key); +} + +void +xglHashInsert (xglHashTablePtr pTable, + unsigned int key, + void *data) +{ + _mesa_HashInsert ((struct _mesa_HashTable *) pTable, key, data); +} + +void +xglHashRemove (xglHashTablePtr pTable, + unsigned int key) +{ + _mesa_HashRemove ((struct _mesa_HashTable *) pTable, key); +} + +unsigned int +xglHashFirstEntry (xglHashTablePtr pTable) +{ + return _mesa_HashFirstEntry ((struct _mesa_HashTable *) pTable); +} + +unsigned int +xglHashNextEntry (const xglHashTablePtr pTable, + unsigned int key) +{ + return _mesa_HashNextEntry ((struct _mesa_HashTable *) pTable, key); +} + +unsigned int +xglHashFindFreeKeyBlock (xglHashTablePtr pTable, + unsigned int numKeys) +{ + return _mesa_HashFindFreeKeyBlock ((struct _mesa_HashTable *) pTable, + numKeys); +} + +#endif |