if (width > 0 && height > 0) {
/* allocate new buffer storage */
- rb->Data = _mesa_malloc(width * height * pixelSize);
+ rb->Data = malloc(width * height * pixelSize);
+
if (rb->Data == NULL) {
rb->Width = 0;
rb->Height = 0;
{
_glthread_INIT_MUTEX(rb->Mutex);
+ rb->Magic = RB_MAGIC;
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
rb->InternalFormat = GL_NONE;
rb->_ActualFormat = GL_NONE;
rb->_BaseFormat = GL_NONE;
- rb->DataType = GL_NONE;
+
+ rb->ComponentType = GL_UNSIGNED_NORMALIZED; /* ARB_fbo */
+ rb->ColorEncoding = GL_LINEAR; /* ARB_fbo */
+
rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
rb->IndexBits = 0;
rb->DepthBits = 0;
rb->StencilBits = 0;
+
+ rb->DataType = GL_NONE;
rb->Data = NULL;
/* Point back to ourself so that we don't have to check for Wrapped==NULL
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);
}
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) {
- GLboolean deleteFlag = GL_FALSE;
+ assert(ptr);
+ if (*ptr == rb) {
+ /* no change */
+ return;
+ }
- _glthread_LOCK_MUTEX((*rb)->Mutex);
- ASSERT((*rb)->RefCount > 0);
- (*rb)->RefCount--;
- deleteFlag = ((*rb)->RefCount == 0);
- _glthread_UNLOCK_MUTEX((*rb)->Mutex);
+ if (*ptr) {
+ /* Unreference the old renderbuffer */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_renderbuffer *oldRb = *ptr;
+
+ assert(oldRb->Magic == RB_MAGIC);
+ _glthread_LOCK_MUTEX(oldRb->Mutex);
+ assert(oldRb->Magic == RB_MAGIC);
+ ASSERT(oldRb->RefCount > 0);
+ oldRb->RefCount--;
+ /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
+ deleteFlag = (oldRb->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldRb->Mutex);
+
+ if (deleteFlag) {
+ oldRb->Magic = 0; /* now invalid memory! */
+ oldRb->Delete(oldRb);
+ }
- if (deleteFlag)
- (*rb)->Delete(*rb);
+ *ptr = NULL;
+ }
+ assert(!*ptr);
- *rb = NULL;
+ if (rb) {
+ assert(rb->Magic == RB_MAGIC);
+ /* reference new renderbuffer */
+ _glthread_LOCK_MUTEX(rb->Mutex);
+ rb->RefCount++;
+ /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ *ptr = rb;
}
}
-
-
/**
* Create a new combined depth/stencil renderbuffer for implementing
* the GL_EXT_packed_depth_stencil extension.
return dsrb;
}
-