X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fframebuffer.c;h=7416bb11892110a7a46ddeb58d32d42757eb0c32;hb=3246e11d33b346f904f441fb1772e9e88f29d214;hp=911bb927a6098b2add6323f2c6ee1061f9b845df;hpb=3d8d5b298a268b119d840bc9bae0ee9e0c9244a9;p=mesa.git diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 911bb927a60..7416bb11892 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.2 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * @@ -131,7 +130,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, memset(fb, 0, sizeof(struct gl_framebuffer)); - _glthread_INIT_MUTEX(fb->Mutex); + mtx_init(&fb->Mutex, mtx_plain); fb->RefCount = 1; @@ -183,7 +182,7 @@ _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name) fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; fb->_ColorReadBufferIndex = BUFFER_COLOR0; fb->Delete = _mesa_destroy_framebuffer; - _glthread_INIT_MUTEX(fb->Mutex); + mtx_init(&fb->Mutex, mtx_plain); } @@ -196,6 +195,7 @@ _mesa_destroy_framebuffer(struct gl_framebuffer *fb) { if (fb) { _mesa_free_framebuffer_data(fb); + free(fb->Label); free(fb); } } @@ -213,7 +213,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) assert(fb); assert(fb->RefCount == 0); - _glthread_DESTROY_MUTEX(fb->Mutex); + mtx_destroy(&fb->Mutex); for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; @@ -244,11 +244,11 @@ _mesa_reference_framebuffer_(struct gl_framebuffer **ptr, GLboolean deleteFlag = GL_FALSE; struct gl_framebuffer *oldFb = *ptr; - _glthread_LOCK_MUTEX(oldFb->Mutex); + mtx_lock(&oldFb->Mutex); ASSERT(oldFb->RefCount > 0); oldFb->RefCount--; deleteFlag = (oldFb->RefCount == 0); - _glthread_UNLOCK_MUTEX(oldFb->Mutex); + mtx_unlock(&oldFb->Mutex); if (deleteFlag) oldFb->Delete(oldFb); @@ -258,9 +258,9 @@ _mesa_reference_framebuffer_(struct gl_framebuffer **ptr, assert(!*ptr); if (fb) { - _glthread_LOCK_MUTEX(fb->Mutex); + mtx_lock(&fb->Mutex); fb->RefCount++; - _glthread_UNLOCK_MUTEX(fb->Mutex); + mtx_unlock(&fb->Mutex); *ptr = fb; } } @@ -320,85 +320,6 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, } } - - -/** - * XXX THIS IS OBSOLETE - drivers should take care of detecting window - * size changes and act accordingly, likely calling _mesa_resize_framebuffer(). - * - * GL_MESA_resize_buffers extension. - * - * When this function is called, we'll ask the window system how large - * the current window is. If it's a new size, we'll call the driver's - * ResizeBuffers function. The driver will then resize its color buffers - * as needed, and maybe call the swrast's routine for reallocating - * swrast-managed depth/stencil/accum/etc buffers. - * \note This function should only be called through the GL API, not - * from device drivers (as was done in the past). - */ -void -_mesa_resizebuffers( struct gl_context *ctx ) -{ - FLUSH_VERTICES(ctx, 0); - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glResizeBuffersMESA\n"); - - if (!ctx->Driver.GetBufferSize) { - return; - } - - if (ctx->WinSysDrawBuffer) { - GLuint newWidth, newHeight; - struct gl_framebuffer *buffer = ctx->WinSysDrawBuffer; - - assert(_mesa_is_winsys_fbo(buffer)); - - /* ask device driver for size of output buffer */ - ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width != newWidth || buffer->Height != newHeight) { - if (ctx->Driver.ResizeBuffers) - ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); - } - } - - if (ctx->WinSysReadBuffer - && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) { - GLuint newWidth, newHeight; - struct gl_framebuffer *buffer = ctx->WinSysReadBuffer; - - assert(_mesa_is_winsys_fbo(buffer)); - - /* ask device driver for size of read buffer */ - ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width != newWidth || buffer->Height != newHeight) { - if (ctx->Driver.ResizeBuffers) - ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); - } - } - - ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ -} - - -/* - * XXX THIS IS OBSOLETE - */ -void GLAPIENTRY -_mesa_ResizeBuffersMESA( void ) -{ - GET_CURRENT_CONTEXT(ctx); - - if (ctx->Extensions.MESA_resize_buffers) - _mesa_resizebuffers( ctx ); -} - - - /** * Examine all the framebuffer's renderbuffers to update the Width/Height * fields of the framebuffer. If we have renderbuffers with different @@ -435,6 +356,56 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) } +/** + * Calculate the inclusive bounding box for the scissor of a specific viewport + * + * \param ctx GL context. + * \param buffer Framebuffer to be checked against + * \param idx Index of the desired viewport + * \param bbox Bounding box for the scissored viewport. Stored as xmin, + * xmax, ymin, ymax. + * + * \warning This function assumes that the framebuffer dimensions are up to + * date (e.g., update_framebuffer_size has been recently called on \c buffer). + * + * \sa _mesa_clip_to_region + */ +void +_mesa_scissor_bounding_box(const struct gl_context *ctx, + const struct gl_framebuffer *buffer, + unsigned idx, int *bbox) +{ + bbox[0] = 0; + bbox[2] = 0; + bbox[1] = buffer->Width; + bbox[3] = buffer->Height; + + if (ctx->Scissor.EnableFlags & (1u << idx)) { + if (ctx->Scissor.ScissorArray[idx].X > bbox[0]) { + bbox[0] = ctx->Scissor.ScissorArray[idx].X; + } + if (ctx->Scissor.ScissorArray[idx].Y > bbox[2]) { + bbox[2] = ctx->Scissor.ScissorArray[idx].Y; + } + if (ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width < bbox[1]) { + bbox[1] = ctx->Scissor.ScissorArray[idx].X + ctx->Scissor.ScissorArray[idx].Width; + } + if (ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height < bbox[3]) { + bbox[3] = ctx->Scissor.ScissorArray[idx].Y + ctx->Scissor.ScissorArray[idx].Height; + } + /* finally, check for empty region */ + if (bbox[0] > bbox[1]) { + bbox[0] = bbox[1]; + } + if (bbox[2] > bbox[3]) { + bbox[2] = bbox[3]; + } + } + + ASSERT(bbox[0] <= bbox[1]); + ASSERT(bbox[2] <= bbox[3]); +} + /** * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields. * These values are computed from the buffer's width and height and @@ -445,6 +416,7 @@ void _mesa_update_draw_buffer_bounds(struct gl_context *ctx) { struct gl_framebuffer *buffer = ctx->DrawBuffer; + int bbox[4]; if (!buffer) return; @@ -454,35 +426,12 @@ _mesa_update_draw_buffer_bounds(struct gl_context *ctx) update_framebuffer_size(ctx, buffer); } - buffer->_Xmin = 0; - buffer->_Ymin = 0; - buffer->_Xmax = buffer->Width; - buffer->_Ymax = buffer->Height; - - if (ctx->Scissor.Enabled) { - if (ctx->Scissor.X > buffer->_Xmin) { - buffer->_Xmin = ctx->Scissor.X; - } - if (ctx->Scissor.Y > buffer->_Ymin) { - buffer->_Ymin = ctx->Scissor.Y; - } - if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) { - buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width; - } - if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) { - buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height; - } - /* finally, check for empty region */ - if (buffer->_Xmin > buffer->_Xmax) { - buffer->_Xmin = buffer->_Xmax; - } - if (buffer->_Ymin > buffer->_Ymax) { - buffer->_Ymin = buffer->_Ymax; - } - } - - ASSERT(buffer->_Xmin <= buffer->_Xmax); - ASSERT(buffer->_Ymin <= buffer->_Ymax); + /* Default to the first scissor as that's always valid */ + _mesa_scissor_bounding_box(ctx, buffer, 0, bbox); + buffer->_Xmin = bbox[0]; + buffer->_Ymin = bbox[2]; + buffer->_Xmax = bbox[1]; + buffer->_Ymax = bbox[3]; } @@ -520,7 +469,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, if (fb->Attachment[i].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); - const gl_format fmt = rb->Format; + const mesa_format fmt = rb->Format; /* Grab samples and sampleBuffers from any attachment point (assuming * the framebuffer is complete, we'll get the same answer from all @@ -547,7 +496,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, for (i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; - const gl_format fmt = rb->Format; + const mesa_format fmt = rb->Format; if (_mesa_get_format_datatype(fmt) == GL_FLOAT) { fb->Visual.floatMode = GL_TRUE; @@ -559,7 +508,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; - const gl_format fmt = rb->Format; + const mesa_format fmt = rb->Format; fb->Visual.haveDepthBuffer = GL_TRUE; fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS); } @@ -567,7 +516,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - const gl_format fmt = rb->Format; + const mesa_format fmt = rb->Format; fb->Visual.haveStencilBuffer = GL_TRUE; fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS); } @@ -575,7 +524,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[BUFFER_ACCUM].Renderbuffer; - const gl_format fmt = rb->Format; + const mesa_format fmt = rb->Format; fb->Visual.haveAccumBuffer = GL_TRUE; fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS); fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS); @@ -878,18 +827,29 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) GLenum _mesa_get_color_read_format(struct gl_context *ctx) { - const GLenum data_type = _mesa_get_format_datatype( - ctx->ReadBuffer->_ColorReadBuffer->Format); - - switch (ctx->ReadBuffer->_ColorReadBuffer->Format) { - case MESA_FORMAT_ARGB8888: - return GL_BGRA; - case MESA_FORMAT_RGB565: - return GL_BGR; - default: - if (data_type == GL_UNSIGNED_INT || data_type == GL_INT) { + if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) { + /* The spec is unclear how to handle this case, but NVIDIA's + * driver generates GL_INVALID_OPERATION. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT: " + "no GL_READ_BUFFER)"); + return GL_NONE; + } + else { + const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format; + const GLenum data_type = _mesa_get_format_datatype(format); + + if (format == MESA_FORMAT_B8G8R8A8_UNORM) + return GL_BGRA; + else if (format == MESA_FORMAT_B5G6R5_UNORM) + return GL_BGR; + + switch (data_type) { + case GL_UNSIGNED_INT: + case GL_INT: return GL_RGBA_INTEGER; - } else { + default: return GL_RGBA; } } @@ -902,26 +862,33 @@ _mesa_get_color_read_format(struct gl_context *ctx) GLenum _mesa_get_color_read_type(struct gl_context *ctx) { - const GLenum data_type = _mesa_get_format_datatype( - ctx->ReadBuffer->_ColorReadBuffer->Format); - - switch (ctx->ReadBuffer->_ColorReadBuffer->Format) { - case MESA_FORMAT_RGB565: - return GL_UNSIGNED_SHORT_5_6_5_REV; - default: - break; + if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) { + /* The spec is unclear how to handle this case, but NVIDIA's + * driver generates GL_INVALID_OPERATION. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE: " + "no GL_READ_BUFFER)"); + return GL_NONE; } - - switch (data_type) { - case GL_SIGNED_NORMALIZED: - return GL_BYTE; - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FLOAT: - return data_type; - case GL_UNSIGNED_NORMALIZED: - default: - return GL_UNSIGNED_BYTE; + else { + const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format; + const GLenum data_type = _mesa_get_format_datatype(format); + + if (format == MESA_FORMAT_B5G6R5_UNORM) + return GL_UNSIGNED_SHORT_5_6_5_REV; + + switch (data_type) { + case GL_SIGNED_NORMALIZED: + return GL_BYTE; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + return data_type; + case GL_UNSIGNED_NORMALIZED: + default: + return GL_UNSIGNED_BYTE; + } } } @@ -962,8 +929,7 @@ _mesa_print_framebuffer(const struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { const struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; if (att->Type == GL_TEXTURE) { - const struct gl_texture_image *texImage = - _mesa_get_attachment_teximage_const(att); + const struct gl_texture_image *texImage = att->Renderbuffer->TexImage; fprintf(stderr, " %2d: Texture %u, level %u, face %u, slice %u, complete %d\n", i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,