Hi,
I have had a go at cleaning up better,
adding update_default_objects to context.c.
It is calling new functions mesa_update_default_objects_program and
mesa_update_default_objects_texture to update those defaults.
It made sense to me to make new functions in the appropriate files
rather than starting to put all the update code in context.c
I am trying to release the old shared state after creating the new
one so that we can make one call to each of the various modules and they
can remove references to old objects and bind to the new ones.
Otherwise when the shared state was destroyed, the objects may also have
been destroyed.
I am a bit worried about calling free_shared_state with the context now
pointing at a different share, hopefully that is OK.
For the buffer objects, I have rebound the NullBufferObj by calling
bind. I had to move the binding code to a static function so that it
does not require the context to be current.
Is this the sort of thing you would like for all the objects which may
be referenced from a hash in the Shared list?
I notice that the wglShareLists definition from MS states that the
context which is going to share should not already contain any display
lists (or other objects?), implying that to conform to this maybe we
don't need to worry to much about unbinding objects?
http://msdn2.microsoft.com/en-us/library/ms537565.aspx
What would you like?
Shane.
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/drivers/windows/gdi/wgl.c Mesa-7.0.1-wglShareLists/src/mesa/drivers/windows/gdi/wgl.c
*** Mesa-7.0.1/src/mesa/drivers/windows/gdi/wgl.c Thu Aug 2 09:50:00 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/drivers/windows/gdi/wgl.c Tue Aug 21 17:37:24 2007
***************
*** 601,608 ****
WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,
HGLRC hglrc2)
{
! (void) hglrc1; (void) hglrc2;
! return(TRUE);
}
--- 601,608 ----
WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,
HGLRC hglrc2)
{
! WMesaShareLists(hglrc1, hglrc2);
! return(TRUE);
}
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/drivers/windows/gdi/wmesa.c Mesa-7.0.1-wglShareLists/src/mesa/drivers/windows/gdi/wmesa.c
*** Mesa-7.0.1/src/mesa/drivers/windows/gdi/wmesa.c Thu Aug 2 09:50:00 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/drivers/windows/gdi/wmesa.c Wed Aug 22 16:49:19 2007
***************
*** 1401,1406 ****
--- 1401,1411 ----
}
}
+ void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx)
+ {
+ _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx);
+ }
+
/* This is hopefully a temporary hack to define some needed dispatch
* table entries. Hopefully, I'll find a better solution. The
* dispatch table generation scripts ought to be making these dummy
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/main/bufferobj.c Mesa-7.0.1-wglShareLists/src/mesa/main/bufferobj.c
*** Mesa-7.0.1/src/mesa/main/bufferobj.c Fri Jun 22 10:10:54 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/main/bufferobj.c Thu Aug 23 13:31:11 2007
***************
*** 409,414 ****
--- 409,506 ----
ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj;
}
+ /**
+ * Bind the specified target to buffer for the specified context.
+ */
+ static void bind_buffer_object( GLcontext *ctx, GLenum target, GLuint buffer)
+ {
+ struct gl_buffer_object *oldBufObj;
+ struct gl_buffer_object *newBufObj = NULL;
+ struct gl_buffer_object **bindTarget = NULL;
+
+ switch (target) {
+ case GL_ARRAY_BUFFER_ARB:
+ bindTarget = &ctx->Array.ArrayBufferObj;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_ARB:
+ bindTarget = &ctx->Array.ElementArrayBufferObj;
+ break;
+ case GL_PIXEL_PACK_BUFFER_EXT:
+ bindTarget = &ctx->Pack.BufferObj;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_EXT:
+ bindTarget = &ctx->Unpack.BufferObj;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)");
+ return;
+ }
+
+ /* Get pointer to old buffer object (to be unbound) */
+ oldBufObj = get_buffer(ctx, target);
+ if (oldBufObj && oldBufObj->Name == buffer)
+ return; /* rebinding the same buffer object- no change */
+
+ /*
+ * Get pointer to new buffer object (newBufObj)
+ */
+ if (buffer == 0) {
+ /* The spec says there's not a buffer object named 0, but we use
+ * one internally because it simplifies things.
+ */
+ newBufObj = ctx->Array.NullBufferObj;
+ }
+ else {
+ /* non-default buffer object */
+ newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
+ if (!newBufObj) {
+ /* if this is a new buffer object id, allocate a buffer object now */
+ ASSERT(ctx->Driver.NewBufferObject);
+ newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
+ if (!newBufObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
+ return;
+ }
+ _mesa_save_buffer_object(ctx, newBufObj);
+ }
+ }
+
+ /* Make new binding */
+ *bindTarget = newBufObj;
+ newBufObj->RefCount++;
+
+ /* Pass BindBuffer call to device driver */
+ if (ctx->Driver.BindBuffer && newBufObj)
+ ctx->Driver.BindBuffer( ctx, target, newBufObj );
+
+ /* decr ref count on old buffer obj, delete if needed */
+ if (oldBufObj) {
+ oldBufObj->RefCount--;
+ assert(oldBufObj->RefCount >= 0);
+ if (oldBufObj->RefCount == 0) {
+ assert(oldBufObj->Name != 0);
+ ASSERT(ctx->Driver.DeleteBuffer);
+ ctx->Driver.DeleteBuffer( ctx, oldBufObj );
+ }
+ }
+ }
+
+ /**
+ * Update the default buffer objects in the given context to reference those
+ * specified in the shared state and release those referencing the old
+ * shared state.
+ */
+ void
+ _mesa_update_default_objects_buffer_objects(GLcontext *ctx)
+ {
+ /* Bind the NullBufferObj to remove references to those
+ in the shared context hash */
+ bind_buffer_object( ctx, GL_ARRAY_BUFFER_ARB, 0);
+ bind_buffer_object( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ bind_buffer_object( ctx, GL_PIXEL_PACK_BUFFER_ARB, 0);
+ bind_buffer_object( ctx, GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+
/**
* When we're about to read pixel data out of a PBO (via glDrawPixels,
***************
*** 493,568 ****
_mesa_BindBufferARB(GLenum target, GLuint buffer)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_buffer_object *oldBufObj;
- struct gl_buffer_object *newBufObj = NULL;
- struct gl_buffer_object **bindTarget = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
! switch (target) {
! case GL_ARRAY_BUFFER_ARB:
! bindTarget = &ctx->Array.ArrayBufferObj;
! break;
! case GL_ELEMENT_ARRAY_BUFFER_ARB:
! bindTarget = &ctx->Array.ElementArrayBufferObj;
! break;
! case GL_PIXEL_PACK_BUFFER_EXT:
! bindTarget = &ctx->Pack.BufferObj;
! break;
! case GL_PIXEL_UNPACK_BUFFER_EXT:
! bindTarget = &ctx->Unpack.BufferObj;
! break;
! default:
! _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)");
! return;
! }
!
! /* Get pointer to old buffer object (to be unbound) */
! oldBufObj = get_buffer(ctx, target);
! if (oldBufObj && oldBufObj->Name == buffer)
! return; /* rebinding the same buffer object- no change */
!
! /*
! * Get pointer to new buffer object (newBufObj)
! */
! if (buffer == 0) {
! /* The spec says there's not a buffer object named 0, but we use
! * one internally because it simplifies things.
! */
! newBufObj = ctx->Array.NullBufferObj;
! }
! else {
! /* non-default buffer object */
! newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
! if (!newBufObj) {
! /* if this is a new buffer object id, allocate a buffer object now */
! ASSERT(ctx->Driver.NewBufferObject);
! newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
! if (!newBufObj) {
! _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
! return;
! }
! _mesa_save_buffer_object(ctx, newBufObj);
! }
! }
!
! /* Make new binding */
! *bindTarget = newBufObj;
! newBufObj->RefCount++;
!
! /* Pass BindBuffer call to device driver */
! if (ctx->Driver.BindBuffer && newBufObj)
! ctx->Driver.BindBuffer( ctx, target, newBufObj );
!
! /* decr ref count on old buffer obj, delete if needed */
! if (oldBufObj) {
! oldBufObj->RefCount--;
! assert(oldBufObj->RefCount >= 0);
! if (oldBufObj->RefCount == 0) {
! assert(oldBufObj->Name != 0);
! ASSERT(ctx->Driver.DeleteBuffer);
! ctx->Driver.DeleteBuffer( ctx, oldBufObj );
! }
! }
}
--- 585,593 ----
_mesa_BindBufferARB(GLenum target, GLuint buffer)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
! bind_buffer_object(ctx, target, buffer);
}
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/main/bufferobj.h Mesa-7.0.1-wglShareLists/src/mesa/main/bufferobj.h
*** Mesa-7.0.1/src/mesa/main/bufferobj.h Fri Jun 22 10:10:54 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/main/bufferobj.h Thu Aug 23 12:55:44 2007
***************
*** 38,43 ****
--- 38,46 ----
extern void
_mesa_init_buffer_objects( GLcontext *ctx );
+ extern void
+ _mesa_update_default_objects_buffer_objects(GLcontext *ctx);
+
extern struct gl_buffer_object *
_mesa_new_buffer_object( GLcontext *ctx, GLuint name, GLenum target );
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/main/context.c Mesa-7.0.1-wglShareLists/src/mesa/main/context.c
*** Mesa-7.0.1/src/mesa/main/context.c Thu Aug 2 09:50:00 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/main/context.c Thu Aug 23 13:13:24 2007
***************
*** 960,965 ****
--- 960,986 ----
/**
+ * Update default objects in a GL context with respect to shared state.
+ *
+ * \param ctx GL context.
+ *
+ * Removes references to old default objects, (texture objects, program objects, etc.)
+ * and changes to reference those from the current shared state.
+ */
+ static GLboolean
+ update_default_objects(GLcontext *ctx)
+ {
+ assert(ctx);
+
+ _mesa_update_default_objects_program(ctx);
+ _mesa_update_default_objects_texture(ctx);
+ _mesa_update_default_objects_buffer_objects(ctx);
+
+ return GL_TRUE;
+ }
+
+
+ /**
* This is the default function we plug into all dispatch table slots
* This helps prevents a segfault when someone calls a GL function without
* first checking if the extension's supported.
***************
*** 1555,1567 ****
GLboolean
_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
{
! if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
! ctx->Shared->RefCount--;
! if (ctx->Shared->RefCount == 0) {
! free_shared_state(ctx, ctx->Shared);
! }
ctx->Shared = ctxToShare->Shared;
ctx->Shared->RefCount++;
return GL_TRUE;
}
else {
--- 1576,1594 ----
GLboolean
_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
{
! if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared)
! {
! struct gl_shared_state *oldSharedState = ctx->Shared;
ctx->Shared = ctxToShare->Shared;
ctx->Shared->RefCount++;
+
+ update_default_objects(ctx);
+
+ oldSharedState->RefCount--;
+ if (oldSharedState->RefCount == 0) {
+ free_shared_state(ctx, oldSharedState);
+ }
+
return GL_TRUE;
}
else {
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/main/texstate.c Mesa-7.0.1-wglShareLists/src/mesa/main/texstate.c
*** Mesa-7.0.1/src/mesa/main/texstate.c Thu Aug 2 09:50:01 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/main/texstate.c Thu Aug 23 13:29:24 2007
***************
*** 3151,3153 ****
--- 3151,3182 ----
_mesa_TexEnvProgramCacheDestroy( ctx );
}
+
+ /**
+ * Update the default texture objects in the given context to reference those
+ * specified in the shared state and release those referencing the old
+ * shared state.
+ */
+ void
+ _mesa_update_default_objects_texture(GLcontext *ctx)
+ {
+ GLuint i;
+
+ for (i=0; i<MAX_TEXTURE_UNITS; i++)
+ {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+
+ texUnit->Current1D->RefCount--;
+ texUnit->Current2D->RefCount--;
+ texUnit->Current3D->RefCount--;
+ texUnit->CurrentCubeMap->RefCount--;
+ texUnit->CurrentRect->RefCount--;
+ /*Check if these can now be destroyed? */
+
+ texUnit->Current1D = ctx->Shared->Default1D;
+ texUnit->Current2D = ctx->Shared->Default2D;
+ texUnit->Current3D = ctx->Shared->Default3D;
+ texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ texUnit->CurrentRect = ctx->Shared->DefaultRect;
+ }
+ }
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/main/texstate.h Mesa-7.0.1-wglShareLists/src/mesa/main/texstate.h
*** Mesa-7.0.1/src/mesa/main/texstate.h Thu Aug 2 09:50:01 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/main/texstate.h Thu Aug 23 11:55:44 2007
***************
*** 147,152 ****
--- 147,155 ----
extern void
_mesa_free_texture_data( GLcontext *ctx );
+ extern void
+ _mesa_update_default_objects_texture(GLcontext *ctx);
+
/[EMAIL PROTECTED]/
#endif
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/shader/program.c Mesa-7.0.1-wglShareLists/src/mesa/shader/program.c
*** Mesa-7.0.1/src/mesa/shader/program.c Thu Aug 2 09:50:01 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/shader/program.c Thu Aug 23 12:10:31 2007
***************
*** 118,124 ****
}
!
/**
* Set the vertex/fragment program error state (position and error string).
--- 118,166 ----
}
! /**
! * Update the default program objects in the given context to reference those
! * specified in the shared state and release those referencing the old
! * shared state.
! */
! void
! _mesa_update_default_objects_program(GLcontext *ctx)
! {
! #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
! if (ctx->VertexProgram.Current) {
! ctx->VertexProgram.Current->Base.RefCount--;
! if (ctx->VertexProgram.Current->Base.RefCount <= 0)
! ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
! }
! ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram;
! assert(ctx->VertexProgram.Current);
! ctx->VertexProgram.Current->Base.RefCount++;
! #endif
!
! #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
! if (ctx->FragmentProgram.Current) {
! ctx->FragmentProgram.Current->Base.RefCount--;
! if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
! ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
! }
! ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram;
! assert(ctx->FragmentProgram.Current);
! ctx->FragmentProgram.Current->Base.RefCount++;
! #endif
!
! /* XXX probably move this stuff */
! #if FEATURE_ATI_fragment_shader
! if (ctx->ATIFragmentShader.Current) {
! ctx->ATIFragmentShader.Current->RefCount--;
! if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
! _mesa_free(ctx->ATIFragmentShader.Current);
! }
! }
! ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
! assert(ctx->ATIFragmentShader.Current);
! ctx->ATIFragmentShader.Current->RefCount++;
! #endif
! }
/**
* Set the vertex/fragment program error state (position and error string).
diff -c -r -x '*.o' Mesa-7.0.1/src/mesa/shader/program.h Mesa-7.0.1-wglShareLists/src/mesa/shader/program.h
*** Mesa-7.0.1/src/mesa/shader/program.h Fri Jun 22 10:10:54 2007
--- Mesa-7.0.1-wglShareLists/src/mesa/shader/program.h Thu Aug 23 11:57:54 2007
***************
*** 57,62 ****
--- 57,65 ----
_mesa_free_program_data(GLcontext *ctx);
extern void
+ _mesa_update_default_objects_program(GLcontext *ctx);
+
+ extern void
_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string);
extern const GLubyte *
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev