summaryrefslogtreecommitdiff
path: root/src/mesa/main/renderbuffer.c
diff options
context:
space:
mode:
authorBrian <brian@nostromo.localnet.net>2007-03-25 10:39:36 -0600
committerBrian <brian@nostromo.localnet.net>2007-03-25 10:39:36 -0600
commit42aaa548a1020be5d40b3dce9448d8004b1ef947 (patch)
treee8543e05c9df7d8c34133eab3e219084a06b6eac /src/mesa/main/renderbuffer.c
parent6fda763989f9102399407098773de227abba822c (diff)
Fix some renderbuffer reference counting issues. Also fixes a mem leak.
Diffstat (limited to 'src/mesa/main/renderbuffer.c')
-rw-r--r--src/mesa/main/renderbuffer.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index ded0063c73..49706b5251 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -1473,7 +1473,7 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
rb->ClassID = 0;
rb->Name = name;
- rb->RefCount = 1;
+ rb->RefCount = 0;
rb->Delete = _mesa_delete_renderbuffer;
/* The rest of these should be set later by the caller of this function or
@@ -2105,9 +2105,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb,
fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
fb->Attachment[bufferName].Complete = GL_TRUE;
- fb->Attachment[bufferName].Renderbuffer = rb;
-
- rb->RefCount++;
+ _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
}
@@ -2125,38 +2123,55 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
if (!rb)
return;
- _mesa_unreference_renderbuffer(&rb);
+ _mesa_reference_renderbuffer(&rb, NULL);
fb->Attachment[bufferName].Renderbuffer = NULL;
}
/**
- * Decrement a renderbuffer object's reference count and delete it when
- * the refcount hits zero.
- * Note: we pass the address of a pointer.
+ * Set *ptr to point to rb. If *ptr points to another renderbuffer,
+ * dereference that buffer first. The new renderbuffer's refcount will
+ * be incremented. The old renderbuffer's refcount will be decremented.
*/
void
-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb)
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb)
{
- assert(rb);
- if (*rb) {
+ assert(ptr);
+ if (*ptr == rb) {
+ /* no change */
+ return;
+ }
+
+ if (*ptr) {
+ /* Unreference the old renderbuffer */
GLboolean deleteFlag = GL_FALSE;
+ struct gl_renderbuffer *oldRb = *ptr;
- _glthread_LOCK_MUTEX((*rb)->Mutex);
- ASSERT((*rb)->RefCount > 0);
- (*rb)->RefCount--;
- deleteFlag = ((*rb)->RefCount == 0);
- _glthread_UNLOCK_MUTEX((*rb)->Mutex);
+ _glthread_LOCK_MUTEX(oldRb->Mutex);
+ ASSERT(oldRb->RefCount > 0);
+ oldRb->RefCount--;
+ /*printf("RB DECR %p to %d\n", (void*) oldRb, oldRb->RefCount);*/
+ deleteFlag = (oldRb->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldRb->Mutex);
if (deleteFlag)
- (*rb)->Delete(*rb);
+ oldRb->Delete(oldRb);
- *rb = NULL;
+ *ptr = NULL;
}
-}
-
+ assert(!*ptr);
+ if (rb) {
+ /* reference new renderbuffer */
+ _glthread_LOCK_MUTEX(rb->Mutex);
+ rb->RefCount++;
+ /*printf("RB REF %p to %d\n", (void*)rb, rb->RefCount);*/
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ *ptr = rb;
+ }
+}
/**
@@ -2180,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
return dsrb;
}
-