X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fframebuffer.c;h=d958dbf7d48a76d33f2303d0dd18ec9f2ac992ea;hb=43867acb6afc7fad26cdc2f22b2a3bb6eeefb2da;hp=079f457503f46f8197f376bf6dd746a5ee2f3b85;hpb=23524e87339b25be75580a2dd2ea296b1741bffb;p=mesa.git diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 079f457503f..d958dbf7d48 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -35,6 +35,7 @@ #include "buffers.h" #include "context.h" #include "depthstencil.h" +#include "formats.h" #include "macros.h" #include "mtypes.h" #include "fbobject.h" @@ -116,6 +117,7 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; fb->_ColorReadBufferIndex = BUFFER_COLOR0; fb->Delete = _mesa_destroy_framebuffer; + _glthread_INIT_MUTEX(fb->Mutex); } return fb; } @@ -223,45 +225,32 @@ _mesa_reference_framebuffer(struct gl_framebuffer **ptr, /* no change */ return; } - if (*ptr) { - _mesa_unreference_framebuffer(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. - */ -void -_mesa_unreference_framebuffer(struct gl_framebuffer **fb) -{ - assert(fb); - if (*fb) { + if (*ptr) { + /* unreference old renderbuffer */ GLboolean deleteFlag = GL_FALSE; + struct gl_framebuffer *oldFb = *ptr; - _glthread_LOCK_MUTEX((*fb)->Mutex); - ASSERT((*fb)->RefCount > 0); - (*fb)->RefCount--; - deleteFlag = ((*fb)->RefCount == 0); - _glthread_UNLOCK_MUTEX((*fb)->Mutex); + _glthread_LOCK_MUTEX(oldFb->Mutex); + ASSERT(oldFb->RefCount > 0); + oldFb->RefCount--; + deleteFlag = (oldFb->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldFb->Mutex); if (deleteFlag) - (*fb)->Delete(*fb); + oldFb->Delete(oldFb); - *fb = NULL; + *ptr = NULL; } -} - + assert(!*ptr); + if (fb) { + _glthread_LOCK_MUTEX(fb->Mutex); + fb->RefCount++; + _glthread_UNLOCK_MUTEX(fb->Mutex); + *ptr = fb; + } +} /** @@ -293,7 +282,6 @@ _mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer *rb = att->Renderbuffer; /* only resize if size is changing */ if (rb->Width != width || rb->Height != height) { - /* could just as well pass rb->_ActualFormat here */ if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) { ASSERT(rb->Width == width); ASSERT(rb->Height == height); @@ -535,19 +523,22 @@ _mesa_update_framebuffer_visual(struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; - if (rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB) { - fb->Visual.redBits = rb->RedBits; - fb->Visual.greenBits = rb->GreenBits; - fb->Visual.blueBits = rb->BlueBits; - fb->Visual.alphaBits = rb->AlphaBits; + const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); + const gl_format fmt = rb->Format; + + if (baseFormat == GL_RGBA || baseFormat == GL_RGB) { + fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS); + fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS); + fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS); + fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS); fb->Visual.rgbBits = fb->Visual.redBits + fb->Visual.greenBits + fb->Visual.blueBits; fb->Visual.floatMode = GL_FALSE; fb->Visual.samples = rb->NumSamples; break; } - else if (rb->_BaseFormat == GL_COLOR_INDEX) { - fb->Visual.indexBits = rb->IndexBits; + else if (baseFormat == GL_COLOR_INDEX) { + fb->Visual.indexBits = _mesa_get_format_bits(fmt, GL_INDEX_BITS); fb->Visual.rgbMode = GL_FALSE; break; } @@ -555,27 +546,30 @@ _mesa_update_framebuffer_visual(struct gl_framebuffer *fb) } if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { + const struct gl_renderbuffer *rb = + fb->Attachment[BUFFER_DEPTH].Renderbuffer; + const gl_format fmt = rb->Format; fb->Visual.haveDepthBuffer = GL_TRUE; - fb->Visual.depthBits - = fb->Attachment[BUFFER_DEPTH].Renderbuffer->DepthBits; + fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS); } if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { + const struct gl_renderbuffer *rb = + fb->Attachment[BUFFER_STENCIL].Renderbuffer; + const gl_format fmt = rb->Format; fb->Visual.haveStencilBuffer = GL_TRUE; - fb->Visual.stencilBits - = fb->Attachment[BUFFER_STENCIL].Renderbuffer->StencilBits; + fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS); } if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) { + const struct gl_renderbuffer *rb = + fb->Attachment[BUFFER_ACCUM].Renderbuffer; + const gl_format fmt = rb->Format; fb->Visual.haveAccumBuffer = GL_TRUE; - fb->Visual.accumRedBits - = fb->Attachment[BUFFER_ACCUM].Renderbuffer->RedBits; - fb->Visual.accumGreenBits - = fb->Attachment[BUFFER_ACCUM].Renderbuffer->GreenBits; - fb->Visual.accumBlueBits - = fb->Attachment[BUFFER_ACCUM].Renderbuffer->BlueBits; - fb->Visual.accumAlphaBits - = fb->Attachment[BUFFER_ACCUM].Renderbuffer->AlphaBits; + fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS); + fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS); + fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS); + fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS); } compute_depth_max(fb); @@ -604,11 +598,11 @@ _mesa_update_depth_buffer(GLcontext *ctx, depthRb = fb->Attachment[attIndex].Renderbuffer; - if (depthRb && depthRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + if (depthRb && depthRb->_BaseFormat == GL_DEPTH_STENCIL) { /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */ if (!fb->_DepthBuffer || fb->_DepthBuffer->Wrapped != depthRb - || fb->_DepthBuffer->_BaseFormat != GL_DEPTH_COMPONENT) { + || _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) { /* need to update wrapper */ struct gl_renderbuffer *wrapper = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb); @@ -645,11 +639,11 @@ _mesa_update_stencil_buffer(GLcontext *ctx, stencilRb = fb->Attachment[attIndex].Renderbuffer; - if (stencilRb && stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + if (stencilRb && stencilRb->_BaseFormat == GL_DEPTH_STENCIL) { /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */ if (!fb->_StencilBuffer || fb->_StencilBuffer->Wrapped != stencilRb - || fb->_StencilBuffer->_BaseFormat != GL_STENCIL_INDEX) { + || _mesa_get_format_base_format(fb->_StencilBuffer->Format) != GL_STENCIL_INDEX) { /* need to update wrapper */ struct gl_renderbuffer *wrapper = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb); @@ -793,8 +787,9 @@ update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) /* This is a user-created framebuffer. * Completeness only matters for user-created framebuffers. */ - _mesa_test_framebuffer_completeness(ctx, fb); - _mesa_update_framebuffer_visual(fb); + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) { + _mesa_test_framebuffer_completeness(ctx, fb); + } } /* Strictly speaking, we don't need to update the draw-state @@ -828,7 +823,7 @@ _mesa_update_framebuffer(GLcontext *ctx) /** * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels, - * glCopyTex[Sub]Image, etc. exists. + * glCopyTex[Sub]Image, etc) exists. * \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA, * GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL. * \return GL_TRUE if buffer exists, GL_FALSE otherwise @@ -836,8 +831,12 @@ _mesa_update_framebuffer(GLcontext *ctx) GLboolean _mesa_source_buffer_exists(GLcontext *ctx, GLenum format) { - const struct gl_renderbuffer_attachment *att - = ctx->ReadBuffer->Attachment; + const struct gl_renderbuffer_attachment *att = ctx->ReadBuffer->Attachment; + + /* If we don't know the framebuffer status, update it now */ + if (ctx->ReadBuffer->_Status == 0) { + _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); + } if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { return GL_FALSE; @@ -861,32 +860,32 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format) if (ctx->ReadBuffer->_ColorReadBuffer == NULL) { return GL_FALSE; } - /* XXX enable this post 6.5 release: - ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 || - ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0); - */ + ASSERT(_mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_RED_BITS) > 0 || + _mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_INDEX_BITS) > 0); break; case GL_DEPTH: case GL_DEPTH_COMPONENT: if (!att[BUFFER_DEPTH].Renderbuffer) { return GL_FALSE; } - ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0); + /*ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);*/ break; case GL_STENCIL: case GL_STENCIL_INDEX: if (!att[BUFFER_STENCIL].Renderbuffer) { return GL_FALSE; } - ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0); + /*ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);*/ break; case GL_DEPTH_STENCIL_EXT: if (!att[BUFFER_DEPTH].Renderbuffer || !att[BUFFER_STENCIL].Renderbuffer) { return GL_FALSE; } + /* ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0); ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0); + */ break; default: _mesa_problem(ctx, @@ -902,13 +901,17 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format) /** * As above, but for drawing operations. - * XXX code do some code merging w/ above function. + * XXX could do some code merging w/ above function. */ GLboolean _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format) { - const struct gl_renderbuffer_attachment *att - = ctx->ReadBuffer->Attachment; + const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; + + /* If we don't know the framebuffer status, update it now */ + if (ctx->DrawBuffer->_Status == 0) { + _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer); + } if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { return GL_FALSE; @@ -929,7 +932,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format) case GL_BGRA: case GL_ABGR_EXT: case GL_COLOR_INDEX: - /* nothing special */ + /* Nothing special since GL_DRAW_BUFFER could be GL_NONE. */ /* Could assert that colorbuffer has RedBits > 0 */ break; case GL_DEPTH: @@ -937,26 +940,28 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format) if (!att[BUFFER_DEPTH].Renderbuffer) { return GL_FALSE; } - ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0); + /*ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);*/ break; case GL_STENCIL: case GL_STENCIL_INDEX: if (!att[BUFFER_STENCIL].Renderbuffer) { return GL_FALSE; } - ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0); + /*ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);*/ break; case GL_DEPTH_STENCIL_EXT: if (!att[BUFFER_DEPTH].Renderbuffer || !att[BUFFER_STENCIL].Renderbuffer) { return GL_FALSE; } + /* ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0); ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0); + */ break; default: _mesa_problem(ctx, - "Unexpected format 0x%x in _mesa_source_buffer_exists", + "Unexpected format 0x%x in _mesa_dest_buffer_exists", format); return GL_FALSE; } @@ -964,3 +969,29 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format) /* OK */ return GL_TRUE; } + +GLenum +_mesa_get_color_read_format(GLcontext *ctx) +{ + switch (ctx->ReadBuffer->_ColorReadBuffer->Format) { + case MESA_FORMAT_ARGB8888: + return GL_BGRA; + case MESA_FORMAT_RGB565: + return GL_BGR; + default: + return GL_RGBA; + } +} + +GLenum +_mesa_get_color_read_type(GLcontext *ctx) +{ + switch (ctx->ReadBuffer->_ColorReadBuffer->Format) { + case MESA_FORMAT_ARGB8888: + return GL_UNSIGNED_BYTE; + case MESA_FORMAT_RGB565: + return GL_UNSIGNED_SHORT_5_6_5_REV; + default: + return GL_UNSIGNED_BYTE; + } +}