#include "imports.h"
+#include "mfeatures.h"
#include "mtypes.h"
#include "hash.h"
-#include "arrayobj.h"
+#if FEATURE_ATI_fragment_shader
+#include "atifragshader.h"
+#endif
#include "bufferobj.h"
#include "shared.h"
-#include "shader/program.h"
-#include "shader/shader_api.h"
-#if FEATURE_dlist
+#include "program/program.h"
#include "dlist.h"
-#endif
-#if FEATURE_ATI_fragment_shader
-#include "shader/atifragshader.h"
-#endif
-
+#include "shaderobj.h"
+#include "syncobj.h"
/**
* Allocate and initialize a shared context state structure.
* failure.
*/
struct gl_shared_state *
-_mesa_alloc_shared_state(GLcontext *ctx)
+_mesa_alloc_shared_state(struct gl_context *ctx)
{
struct gl_shared_state *shared;
GLuint i;
shared->BufferObjects = _mesa_NewHashTable();
#endif
- /* Allocate the default buffer object and set refcount so high that
- * it never gets deleted.
- * XXX with recent/improved refcounting this may not longer be needed.
- */
+ /* Allocate the default buffer object */
shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
- shared->NullBufferObj->RefCount = 1000 * 1000 * 1000;
/* Create default texture objects */
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
shared->RenderBuffers = _mesa_NewHashTable();
#endif
+ make_empty_list(& shared->SyncObjects);
+
return shared;
}
static void
delete_displaylist_cb(GLuint id, void *data, void *userData)
{
-#if FEATURE_dlist
struct gl_display_list *list = (struct gl_display_list *) data;
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
_mesa_delete_list(ctx, list);
-#endif
}
delete_texture_cb(GLuint id, void *data, void *userData)
{
struct gl_texture_object *texObj = (struct gl_texture_object *) data;
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
ctx->Driver.DeleteTexture(ctx, texObj);
}
delete_program_cb(GLuint id, void *data, void *userData)
{
struct gl_program *prog = (struct gl_program *) data;
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
if(prog != &_mesa_DummyProgram) {
ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
prog->RefCount = 0; /* now going away */
delete_fragshader_cb(GLuint id, void *data, void *userData)
{
struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
_mesa_delete_ati_fragment_shader(ctx, shader);
}
#endif
delete_bufferobj_cb(GLuint id, void *data, void *userData)
{
struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
if (_mesa_bufferobj_mapped(bufObj)) {
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->Pointer = NULL;
}
- ctx->Driver.DeleteBuffer(ctx, bufObj);
+ _mesa_reference_buffer_object(ctx, &bufObj, NULL);
}
static void
free_shader_program_data_cb(GLuint id, void *data, void *userData)
{
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
struct gl_shader_program *shProg = (struct gl_shader_program *) data;
if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
static void
delete_shader_cb(GLuint id, void *data, void *userData)
{
- GLcontext *ctx = (GLcontext *) userData;
+ struct gl_context *ctx = (struct gl_context *) userData;
struct gl_shader *sh = (struct gl_shader *) data;
if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
- _mesa_free_shader(ctx, sh);
+ ctx->Driver.DeleteShader(ctx, sh);
}
else {
struct gl_shader_program *shProg = (struct gl_shader_program *) data;
ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
- _mesa_free_shader_program(ctx, shProg);
+ ctx->Driver.DeleteShaderProgram(ctx, shProg);
}
}
*
* \sa alloc_shared_state().
*/
-void
-_mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
+static void
+free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
{
GLuint i;
+ /* Free the dummy/fallback texture object */
+ if (shared->FallbackTex)
+ ctx->Driver.DeleteTexture(ctx, shared->FallbackTex);
+
/*
* Free display lists
*/
#endif
#if FEATURE_ARB_vertex_buffer_object
- ctx->Driver.DeleteBuffer(ctx, shared->NullBufferObj);
+ _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL);
#endif
+ {
+ struct simple_node *node;
+ struct simple_node *temp;
+
+ foreach_s(node, temp, & shared->SyncObjects) {
+ _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node);
+ }
+ }
+
/*
* Free texture objects (after FBOs since some textures might have
* been bound to FBOs).
_glthread_DESTROY_MUTEX(shared->Mutex);
_glthread_DESTROY_MUTEX(shared->TexMutex);
- _mesa_free(shared);
+ free(shared);
+}
+
+
+/**
+ * Decrement shared state object reference count and potentially free it
+ * and all children structures.
+ *
+ * \param ctx GL context.
+ * \param shared shared state pointer.
+ *
+ * \sa free_shared_state().
+ */
+void
+_mesa_release_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
+{
+ GLint RefCount;
+
+ _glthread_LOCK_MUTEX(shared->Mutex);
+ RefCount = --shared->RefCount;
+ _glthread_UNLOCK_MUTEX(shared->Mutex);
+
+ assert(RefCount >= 0);
+
+ if (RefCount == 0) {
+ /* free shared state */
+ free_shared_state( ctx, shared );
+ }
}