X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Frenderbuffer.c;h=38be8266e05c5bd6df0fa3e83e3f7525bbb0af84;hb=cab7ea03688ec73dd71c0b969f2db30cabeb713c;hp=1cc95a7d3b4b12b2233ce53e38f139683ac1a354;hpb=2cf5fd48d1586f961910a14324a457854cb66221;p=mesa.git diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index 1cc95a7d3b4..38be8266e05 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -1192,18 +1192,23 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, ASSERT(rb->PutMonoValues); /* free old buffer storage */ - if (rb->Data) + if (rb->Data) { _mesa_free(rb->Data); + rb->Data = NULL; + } - /* allocate new buffer storage */ - rb->Data = _mesa_malloc(width * height * pixelSize); - if (rb->Data == NULL) { - rb->Width = 0; - rb->Height = 0; - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "software renderbuffer allocation (%d x %d x %d)", - width, height, pixelSize); - return GL_FALSE; + if (width > 0 && height > 0) { + /* allocate new buffer storage */ + rb->Data = malloc(width * height * pixelSize); + + if (rb->Data == NULL) { + rb->Width = 0; + rb->Height = 0; + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "software renderbuffer allocation (%d x %d x %d)", + width, height, pixelSize); + return GL_FALSE; + } } rb->Width = width; @@ -1431,6 +1436,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)); +} + /**********************************************************************/ /**********************************************************************/ @@ -1456,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 @@ -1471,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 @@ -1761,6 +1783,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 @@ -2069,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); } @@ -2089,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. @@ -2144,4 +2207,3 @@ _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name) return dsrb; } -