diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/api_loopback.c | 2 | ||||
-rw-r--r-- | src/mesa/main/fbobject.c | 22 | ||||
-rw-r--r-- | src/mesa/main/framebuffer.c | 52 | ||||
-rw-r--r-- | src/mesa/main/rbadaptors.c | 2 | ||||
-rw-r--r-- | src/mesa/main/renderbuffer.c | 88 | ||||
-rw-r--r-- | src/mesa/main/renderbuffer.h | 6 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.c | 7 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 12 |
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, |