aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_loopback.c2
-rw-r--r--src/mesa/main/fbobject.c22
-rw-r--r--src/mesa/main/framebuffer.c52
-rw-r--r--src/mesa/main/rbadaptors.c2
-rw-r--r--src/mesa/main/renderbuffer.c88
-rw-r--r--src/mesa/main/renderbuffer.h6
-rw-r--r--src/mesa/main/texenvprogram.c7
-rw-r--r--src/mesa/main/teximage.c12
8 files changed, 100 insertions, 91 deletions
diff --git a/src/mesa/main/api_loopback.c b/src/mesa/main/api_loopback.c
index 717ef1fc8f0..efe5a77d581 100644
--- a/src/mesa/main/api_loopback.c
+++ b/src/mesa/main/api_loopback.c
@@ -146,7 +146,7 @@ static void GLAPIENTRY
loopback_Color3iv_f( const GLint *v )
{
COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
- INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) );
+ INT_TO_FLOAT(v[2]), 1.0 );
}
static void GLAPIENTRY
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index f7e870b49cd..fefa14e5036 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -559,7 +559,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuffer)
void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
- struct gl_renderbuffer *newRb, *oldRb;
+ struct gl_renderbuffer *newRb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -593,21 +593,16 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
}
ASSERT(newRb->AllocStorage);
_mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
+ newRb->RefCount = 1; /* referenced by hash table */
}
- newRb->RefCount++;
}
else {
newRb = NULL;
}
- oldRb = ctx->CurrentRenderbuffer;
- if (oldRb) {
- _mesa_unreference_renderbuffer(&oldRb);
- }
-
ASSERT(newRb != &DummyRenderbuffer);
- ctx->CurrentRenderbuffer = newRb;
+ _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
}
@@ -632,14 +627,15 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- /* remove from hash table immediately, to free the ID */
+ /* Remove from hash table immediately, to free the ID.
+ * But the object will not be freed until it's no longer
+ * referenced anywhere else.
+ */
_mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
if (rb != &DummyRenderbuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- _mesa_unreference_renderbuffer(&rb);
+ /* no longer referenced by hash table */
+ _mesa_reference_renderbuffer(&rb, NULL);
}
}
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index cd4f594aa29..1fd31a53211 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -70,42 +70,6 @@ compute_depth_max(struct gl_framebuffer *fb)
/**
- * Set the framebuffer's _DepthBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_depth_renderbuffer(struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- if (fb->_DepthBuffer) {
- _mesa_unreference_renderbuffer(&fb->_DepthBuffer);
- }
- fb->_DepthBuffer = rb;
- if (rb) {
- rb->RefCount++;
- }
-}
-
-
-/**
- * Set the framebuffer's _StencilBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_stencil_renderbuffer(struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
-{
- if (fb->_StencilBuffer) {
- _mesa_unreference_renderbuffer(&fb->_StencilBuffer);
- }
- fb->_StencilBuffer = rb;
- if (rb) {
- rb->RefCount++;
- }
-}
-
-
-/**
* Create and initialize a gl_framebuffer object.
* This is intended for creating _window_system_ framebuffers, not generic
* framebuffer objects ala GL_EXT_framebuffer_object.
@@ -223,7 +187,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_unreference_renderbuffer(&att->Renderbuffer);
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
}
if (att->Texture) {
/* render to texture */
@@ -239,9 +203,9 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
att->Texture = NULL;
}
- /* unbind depth/stencil to decr ref counts */
- set_depth_renderbuffer(fb, NULL);
- set_stencil_renderbuffer(fb, NULL);
+ /* unbind _Depth/_StencilBuffer to decr ref counts */
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
}
@@ -569,13 +533,13 @@ _mesa_update_depth_buffer(GLcontext *ctx,
/* need to update wrapper */
struct gl_renderbuffer *wrapper
= _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
- set_depth_renderbuffer(fb, wrapper);
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
}
}
else {
/* depthRb may be null */
- set_depth_renderbuffer(fb, depthRb);
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
}
}
@@ -610,13 +574,13 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
/* need to update wrapper */
struct gl_renderbuffer *wrapper
= _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
- set_stencil_renderbuffer(fb, wrapper);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
}
}
else {
/* stencilRb may be null */
- set_stencil_renderbuffer(fb, stencilRb);
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
}
}
diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c
index 60f4948becf..c1ac0606c86 100644
--- a/src/mesa/main/rbadaptors.c
+++ b/src/mesa/main/rbadaptors.c
@@ -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_unreference_renderbuffer(&rb->Wrapped);
+ _mesa_reference_renderbuffer(&rb->Wrapped, NULL);
/* delete myself */
_mesa_delete_renderbuffer(rb);
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index e387c42c345..49706b52516 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -1435,6 +1435,17 @@ put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
}
+static void
+copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
+{
+ ASSERT(dst->_ActualFormat == GL_ALPHA8);
+ ASSERT(src->_ActualFormat == GL_ALPHA8);
+ ASSERT(dst->Width == src->Width);
+ ASSERT(dst->Height == src->Height);
+
+ _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
+}
+
/**********************************************************************/
/**********************************************************************/
@@ -1462,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
@@ -1766,6 +1777,27 @@ _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
/**
+ * For framebuffers that use a software alpha channel wrapper
+ * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
+ * copy the back buffer alpha channel into the front buffer alpha channel.
+ */
+void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+
+ if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+}
+
+
+/**
* Add a software-based depth renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
@@ -2073,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);
}
@@ -2093,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;
+ }
+}
/**
@@ -2148,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
return dsrb;
}
-
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index e1a0a559792..c9bf8885487 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -64,6 +64,9 @@ _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLboolean frontLeft, GLboolean backLeft,
GLboolean frontRight, GLboolean backRight);
+extern void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb);
+
extern GLboolean
_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint depthBits);
@@ -99,7 +102,8 @@ extern void
_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName);
extern void
-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb);
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb);
extern struct gl_renderbuffer *
_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name);
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 54ae7ce0a13..0c6fa82f112 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1014,7 +1014,7 @@ create_new_program(GLcontext *ctx, struct state_key *key,
p.program->Base.NumTexIndirections = 1; /* correct? */
p.program->Base.NumTexInstructions = 0;
p.program->Base.NumAluInstructions = 0;
- p.program->Base.String = 0;
+ p.program->Base.String = NULL;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
p.program->Base.NumParameters =
@@ -1103,9 +1103,8 @@ create_new_program(GLcontext *ctx, struct state_key *key,
"generating tex env program");
return;
}
- _mesa_memcpy(program->Base.Instructions, instBuffer,
- sizeof(struct prog_instruction)
- * program->Base.NumInstructions);
+ _mesa_copy_instructions(program->Base.Instructions, instBuffer,
+ program->Base.NumInstructions);
/* Notify driver the fragment program has (actually) changed.
*/
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 543d6efc984..706d3466955 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2061,12 +2061,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
if (teximage->IsCompressed) {
- if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexSubImage%dD(missing readbuffer)", dimensions);
- return GL_TRUE;
- }
-
if (target != GL_TEXTURE_2D) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexSubImage%d(target)", dimensions);
@@ -2096,6 +2090,12 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
+ if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexSubImage%dD(missing readbuffer)", dimensions);
+ return GL_TRUE;
+ }
+
if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,