summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-03-06 10:07:59 -0700
committerBrian <brian@yutani.localnet.net>2007-03-06 10:07:59 -0700
commita510bc3ee1a696da120c09ee4ec33dc033f671ac (patch)
treec4c594f5f39f060f507dc13fc5e9383956bce909 /src/mesa/main
parent593802c0b0f451299ac2598c6de61e884fb44830 (diff)
Fix/improve framebuffer object reference counting.
Use _mesa_reference_framebuffer() and _mesa_unreference_framebuffer() functions to be sure reference counting is done correctly. Additional assertions are done too. Note _mesa_dereference_framebuffer() renamed to "unreference" as that's more accurate.
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/context.c25
-rw-r--r--src/mesa/main/fbobject.c32
-rw-r--r--src/mesa/main/framebuffer.c46
-rw-r--r--src/mesa/main/framebuffer.h6
-rw-r--r--src/mesa/main/rbadaptors.c6
-rw-r--r--src/mesa/main/renderbuffer.c23
-rw-r--r--src/mesa/main/renderbuffer.h2
7 files changed, 76 insertions, 64 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 1245c10cc2..135c814c0a 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1408,6 +1408,13 @@ _mesa_free_context_data( GLcontext *ctx )
if (ctx == _mesa_get_current_context()) {
_mesa_make_current(NULL, NULL, NULL);
}
+ else {
+ /* unreference WinSysDraw/Read buffers */
+ _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
+ _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
+ _mesa_unreference_framebuffer(&ctx->DrawBuffer);
+ _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+ }
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
@@ -1694,12 +1701,8 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
ASSERT(_mesa_get_current_context() == newCtx);
if (oldCtx) {
- if (oldCtx->WinSysDrawBuffer) {
- _mesa_dereference_framebuffer(&oldCtx->WinSysDrawBuffer);
- }
- if (oldCtx->WinSysReadBuffer) {
- _mesa_dereference_framebuffer(&oldCtx->WinSysReadBuffer);
- }
+ _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer);
+ _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer);
}
if (!newCtx) {
@@ -1713,20 +1716,18 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
ASSERT(drawBuffer->Name == 0);
ASSERT(readBuffer->Name == 0);
- newCtx->WinSysDrawBuffer = drawBuffer;
- newCtx->WinSysReadBuffer = readBuffer;
- drawBuffer->RefCount++;
- readBuffer->RefCount++;
+ _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
+ _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
/*
* Only set the context's Draw/ReadBuffer fields if they're NULL
* or not bound to a user-created FBO.
*/
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
- newCtx->DrawBuffer = drawBuffer;
+ _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
}
if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
- newCtx->ReadBuffer = readBuffer;
+ _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
}
newCtx->NewState |= _NEW_BUFFERS;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index a99ff9dc97..6608eefc6c 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -602,7 +602,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
oldRb = ctx->CurrentRenderbuffer;
if (oldRb) {
- _mesa_dereference_renderbuffer(&oldRb);
+ _mesa_unreference_renderbuffer(&oldRb);
}
ASSERT(newRb != &DummyRenderbuffer);
@@ -639,7 +639,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
/* But the object will not be freed until it's no longer
* bound in any context.
*/
- _mesa_dereference_renderbuffer(&rb);
+ _mesa_unreference_renderbuffer(&rb);
}
}
}
@@ -998,12 +998,6 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
}
_mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
}
- _glthread_LOCK_MUTEX(newFb->Mutex);
- if (bindReadBuf)
- newFb->RefCount++;
- if (bindDrawBuf)
- newFb->RefCount++;
- _glthread_UNLOCK_MUTEX(newFb->Mutex);
}
else {
/* Binding the window system framebuffer (which was originally set
@@ -1020,22 +1014,16 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
*/
if (bindReadBuf) {
- struct gl_framebuffer *oldFb = ctx->ReadBuffer;
- if (oldFb && oldFb->Name != 0) {
- _mesa_dereference_framebuffer(&oldFb);
- }
- ctx->ReadBuffer = newFb;
+ _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+ _mesa_reference_framebuffer(&ctx->ReadBuffer, newFb);
}
if (bindDrawBuf) {
- struct gl_framebuffer *oldFb = ctx->DrawBuffer;
- if (oldFb && oldFb->Name != 0) {
- /* check if old FB had any texture attachments */
- check_end_texture_render(ctx, oldFb);
- /* check if time to delete this framebuffer */
- _mesa_dereference_framebuffer(&oldFb);
- }
- ctx->DrawBuffer = newFb;
+ /* check if old FB had any texture attachments */
+ check_end_texture_render(ctx, ctx->DrawBuffer);
+ /* check if time to delete this framebuffer */
+ _mesa_unreference_framebuffer(&ctx->DrawBuffer);
+ _mesa_reference_framebuffer(&ctx->DrawBuffer, newFb);
if (newFb->Name != 0) {
/* check if newly bound framebuffer has any texture attachments */
check_begin_texture_render(ctx, newFb);
@@ -1083,7 +1071,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
/* But the object will not be freed until it's no longer
* bound in any context.
*/
- _mesa_dereference_framebuffer(&fb);
+ _mesa_unreference_framebuffer(&fb);
}
}
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index dabc96d91d..c97d2f0077 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -78,7 +78,7 @@ set_depth_renderbuffer(struct gl_framebuffer *fb,
struct gl_renderbuffer *rb)
{
if (fb->_DepthBuffer) {
- _mesa_dereference_renderbuffer(&fb->_DepthBuffer);
+ _mesa_unreference_renderbuffer(&fb->_DepthBuffer);
}
fb->_DepthBuffer = rb;
if (rb) {
@@ -96,7 +96,7 @@ set_stencil_renderbuffer(struct gl_framebuffer *fb,
struct gl_renderbuffer *rb)
{
if (fb->_StencilBuffer) {
- _mesa_dereference_renderbuffer(&fb->_StencilBuffer);
+ _mesa_unreference_renderbuffer(&fb->_StencilBuffer);
}
fb->_StencilBuffer = rb;
if (rb) {
@@ -223,7 +223,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
if (att->Renderbuffer) {
- _mesa_dereference_renderbuffer(&att->Renderbuffer);
+ _mesa_unreference_renderbuffer(&att->Renderbuffer);
}
if (att->Texture) {
/* render to texture */
@@ -236,7 +236,6 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
}
}
att->Type = GL_NONE;
- att->Renderbuffer = NULL;
att->Texture = NULL;
}
@@ -247,25 +246,44 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
/**
- * Decrement the reference count on a framebuffer and delete it when
+ * Set *ptr to point to fb, with refcounting and locking.
+ */
+void
+_mesa_reference_framebuffer(struct gl_framebuffer **ptr,
+ struct gl_framebuffer *fb)
+{
+ assert(ptr);
+ assert(!*ptr);
+ assert(fb);
+ _glthread_LOCK_MUTEX(fb->Mutex);
+ fb->RefCount++;
+ _glthread_UNLOCK_MUTEX(fb->Mutex);
+ *ptr = fb;
+}
+
+
+/**
+ * Undo/remove a reference to a framebuffer object.
+ * Decrement the framebuffer object's reference count and delete it when
* the refcount hits zero.
- * Note: we pass the address of a pointer and set it to NULL if we delete it.
+ * Note: we pass the address of a pointer and set it to NULL.
*/
void
-_mesa_dereference_framebuffer(struct gl_framebuffer **fb)
+_mesa_unreference_framebuffer(struct gl_framebuffer **fb)
{
- GLboolean deleteFlag = GL_FALSE;
+ assert(fb);
+ if (*fb) {
+ GLboolean deleteFlag = GL_FALSE;
- _glthread_LOCK_MUTEX((*fb)->Mutex);
- {
+ _glthread_LOCK_MUTEX((*fb)->Mutex);
ASSERT((*fb)->RefCount > 0);
(*fb)->RefCount--;
deleteFlag = ((*fb)->RefCount == 0);
- }
- _glthread_UNLOCK_MUTEX((*fb)->Mutex);
+ _glthread_UNLOCK_MUTEX((*fb)->Mutex);
+
+ if (deleteFlag)
+ (*fb)->Delete(*fb);
- if (deleteFlag) {
- (*fb)->Delete(*fb);
*fb = NULL;
}
}
diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h
index 7f3254fe8e..4d76f3a90f 100644
--- a/src/mesa/main/framebuffer.h
+++ b/src/mesa/main/framebuffer.h
@@ -43,7 +43,11 @@ extern void
_mesa_free_framebuffer_data(struct gl_framebuffer *buffer);
extern void
-_mesa_dereference_framebuffer(struct gl_framebuffer **fb);
+_mesa_reference_framebuffer(struct gl_framebuffer **ptr,
+ struct gl_framebuffer *fb);
+
+extern void
+_mesa_unreference_framebuffer(struct gl_framebuffer **fb);
extern void
_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c
index 313c8d43d6..60f4948bec 100644
--- a/src/mesa/main/rbadaptors.c
+++ b/src/mesa/main/rbadaptors.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.1
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *rb)
/* Decrement reference count on the buffer we're wrapping and delete
* it if refcount hits zero.
*/
- _mesa_dereference_renderbuffer(&rb->Wrapped);
+ _mesa_unreference_renderbuffer(&rb->Wrapped);
/* delete myself */
_mesa_delete_renderbuffer(rb);
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index 6b18d60baf..1cc95a7d3b 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -2089,32 +2089,33 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
if (!rb)
return;
- _mesa_dereference_renderbuffer(&rb);
+ _mesa_unreference_renderbuffer(&rb);
fb->Attachment[bufferName].Renderbuffer = NULL;
}
/**
- * Decrement the reference count on a renderbuffer and delete it when
+ * Decrement a renderbuffer object's reference count and delete it when
* the refcount hits zero.
- * Note: we pass the address of a pointer and set it to NULL if we delete it.
+ * Note: we pass the address of a pointer.
*/
void
-_mesa_dereference_renderbuffer(struct gl_renderbuffer **rb)
+_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb)
{
- GLboolean deleteFlag = GL_FALSE;
+ assert(rb);
+ if (*rb) {
+ GLboolean deleteFlag = GL_FALSE;
- _glthread_LOCK_MUTEX((*rb)->Mutex);
- {
+ _glthread_LOCK_MUTEX((*rb)->Mutex);
ASSERT((*rb)->RefCount > 0);
(*rb)->RefCount--;
deleteFlag = ((*rb)->RefCount == 0);
- }
- _glthread_UNLOCK_MUTEX((*rb)->Mutex);
+ _glthread_UNLOCK_MUTEX((*rb)->Mutex);
+
+ if (deleteFlag)
+ (*rb)->Delete(*rb);
- if (deleteFlag) {
- (*rb)->Delete(*rb);
*rb = NULL;
}
}
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index 74ca43c57a..e1a0a55979 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -99,7 +99,7 @@ extern void
_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName);
extern void
-_mesa_dereference_renderbuffer(struct gl_renderbuffer **rb);
+_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb);
extern struct gl_renderbuffer *
_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name);