#include "version.h"
#include "vtxfmt.h"
#include "glapi/glthread.h"
-#include "glapi/glapioffsets.h"
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
#include "shader/program.h"
#endif
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
-static void
-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**
#endif
#if FEATURE_ARB_vertex_program
- ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ ss->DefaultVertexProgram = (struct gl_vertex_program *)
+ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
- ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ ss->DefaultFragmentProgram = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- if (ss->DefaultVertexProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- if (ss->DefaultFragmentProgram)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray);
if (ss->Default2DArray)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray);
- if (ss)
- _mesa_free(ss);
+
+ _mesa_free(ss);
+
return GL_FALSE;
}
{
struct gl_program *prog = (struct gl_program *) data;
GLcontext *ctx = (GLcontext *) userData;
+ ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
+ prog->RefCount = 0; /* now going away */
ctx->Driver.DeleteProgram(ctx, prog);
}
_mesa_delete_array_object(ctx, arrayObj);
}
+/**
+ * Callback for freeing shader program data. Call it before delete_shader_cb
+ * to avoid memory access error.
+ */
+static void
+free_shader_program_data_cb(GLuint id, void *data, void *userData)
+{
+ GLcontext *ctx = (GLcontext *) userData;
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+
+ if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
+ _mesa_free_shader_program_data(ctx, shProg);
+ }
+}
+
/**
* Callback for deleting shader and shader programs objects.
* Called by _mesa_HashDeleteAll().
*/
/*assert(fb->RefCount == 1);*/
fb->RefCount = 0;
- fb->Delete(fb);
+
+ /* NOTE: Delete should always be defined but there are two reports
+ * of it being NULL (bugs 13507, 14293). Work-around for now.
+ */
+ if (fb->Delete)
+ fb->Delete(fb);
}
/**
{
struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
rb->RefCount = 0; /* see comment for FBOs above */
- rb->Delete(rb);
+ if (rb->Delete)
+ rb->Delete(rb);
}
_mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
_mesa_DeleteHashTable(ss->DisplayList);
+#if FEATURE_ARB_shader_objects
+ _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
+ _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
+ _mesa_DeleteHashTable(ss->ShaderObjects);
+#endif
+
#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
_mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
#endif
#if FEATURE_ARB_fragment_program
- _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
#endif
#if FEATURE_ATI_fragment_shader
_mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
_mesa_DeleteHashTable(ss->ArrayObjects);
-#if FEATURE_ARB_shader_objects
- _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
- _mesa_DeleteHashTable(ss->ShaderObjects);
-#endif
-
#if FEATURE_EXT_framebuffer_object
_mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
_mesa_DeleteHashTable(ss->FrameBuffers);
}
/* redo special cases: */
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
_mesa_init_debug( ctx );
_mesa_init_display_list( ctx );
_mesa_init_eval( ctx );
+ _mesa_init_fbobjects( ctx );
_mesa_init_feedback( ctx );
_mesa_init_fog( ctx );
_mesa_init_histogram( ctx );
/* Miscellaneous */
ctx->NewState = _NEW_ALL;
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
- ctx->_Facing = 0;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * 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;
}
_mesa_unreference_framebuffer(&ctx->DrawBuffer);
_mesa_unreference_framebuffer(&ctx->ReadBuffer);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
+
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+
_mesa_free_attrib_data(ctx);
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
- GET_CURRENT_CONTEXT(oldCtx);
-
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n");
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
- if (oldCtx) {
- _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer);
- _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer);
- _mesa_unreference_framebuffer(&oldCtx->DrawBuffer);
- _mesa_unreference_framebuffer(&oldCtx->ReadBuffer);
- }
-
if (!newCtx) {
_glapi_set_dispatch(NULL); /* none current */
}
*/
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
_mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
- /* fix up the fb fields - these will end up wrong otherwise
- if the DRIdrawable changes, and everything relies on them.
- This is a bit messy (same as needed in _mesa_BindFramebufferEXT) */
- int i;
- GLenum buffers[MAX_DRAW_BUFFERS];
- for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) {
- buffers[i] = newCtx->Color.DrawBuffer[i];
- }
- _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, buffers, NULL);
}
if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
_mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
- _mesa_readbuffer_update_fields(newCtx, newCtx->Pixel.ReadBuffer);
}
+ /* XXX only set this flag if we're really changing the draw/read
+ * framebuffer bindings.
+ */
newCtx->NewState |= _NEW_BUFFERS;
#if 1
_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);
- }
+ 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 {