mesa/main: Make FEATURE_histogram follow feature conventions.
[mesa.git] / src / mesa / main / renderbuffer.c
index ded0063c73909b141b6d57d0487d4cec23fed122..38be8266e05c5bd6df0fa3e83e3f7525bbb0af84 100644 (file)
@@ -1199,7 +1199,8 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
    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;
@@ -1471,9 +1472,10 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
 {
    _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
@@ -1486,11 +1488,16 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
    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
@@ -2105,9 +2112,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,40 +2130,62 @@ _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) {
-      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.
@@ -2180,4 +2207,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
 
    return dsrb;
 }
-