diff options
author | Brian Paul <[email protected]> | 2005-05-04 20:11:35 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2005-05-04 20:11:35 +0000 |
commit | e4b2356c07d31fbeeabb13b2fb47db703b473080 (patch) | |
tree | d8b7f1c7c9e7c84d84349485f942dd205dd4c16d /src/mesa/main/buffers.c | |
parent | ebef61f5c0950572f9c6a81b08f447957461675c (diff) |
Major check-in of changes for GL_EXT_framebuffer_object extension.
Main driver impacts:
- new code for creating the Mesa GLframebuffer
- new span/pixel read/write code
Some drivers not yet updated/tested.
Diffstat (limited to 'src/mesa/main/buffers.c')
-rw-r--r-- | src/mesa/main/buffers.c | 548 |
1 files changed, 273 insertions, 275 deletions
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 41a1fdb7cca..12f58ff6621 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -29,16 +29,15 @@ #include "glheader.h" -#include "imports.h" #include "buffers.h" #include "colormac.h" #include "context.h" -#include "depth.h" #include "enums.h" #include "fbobject.h" -#include "stencil.h" #include "state.h" -#include "mtypes.h" + + +#define BAD_MASK ~0u #if _HAVE_FULL_GL @@ -133,12 +132,12 @@ _mesa_Clear( GLbitfield mask ) _mesa_update_state( ctx ); /* update _Xmin, etc */ } - if (ctx->RenderMode==GL_RENDER) { + if (ctx->RenderMode == GL_RENDER) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - GLbitfield ddMask; + GLbitfield bufferMask; /* don't clear depth buffer if depth writing disabled */ if (!ctx->Depth.Mask) @@ -146,20 +145,31 @@ _mesa_Clear( GLbitfield mask ) /* Build the bitmask to send to device driver's Clear function. * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 - * of the FRONT/BACK_LEFT/RIGHT_BIT flags. + * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the + * BUFFER_BIT_COLORn flags. */ - ddMask = 0; - if (mask & GL_COLOR_BUFFER_BIT) - ddMask |= ctx->Color._DrawDestMask[0]; - if ((mask & GL_DEPTH_BUFFER_BIT) && ctx->Visual.depthBits > 0) - ddMask |= GL_DEPTH_BUFFER_BIT; - if ((mask & GL_STENCIL_BUFFER_BIT) && ctx->Visual.stencilBits > 0) - ddMask |= GL_STENCIL_BUFFER_BIT; - if ((mask & GL_ACCUM_BUFFER_BIT) && ctx->Visual.accumRedBits > 0) - ddMask |= GL_ACCUM_BUFFER_BIT; + bufferMask = 0; + if (mask & GL_COLOR_BUFFER_BIT) { + bufferMask |= ctx->DrawBuffer->_ColorDrawBufferMask[0]; + } + + if ((mask & GL_DEPTH_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveDepthBuffer) { + bufferMask |= BUFFER_BIT_DEPTH; + } + + if ((mask & GL_STENCIL_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveStencilBuffer) { + bufferMask |= BUFFER_BIT_STENCIL; + } + + if ((mask & GL_ACCUM_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveAccumBuffer) { + bufferMask |= BUFFER_BIT_ACCUM; + } ASSERT(ctx->Driver.Clear); - ctx->Driver.Clear( ctx, ddMask, (GLboolean) !ctx->Scissor.Enabled, + ctx->Driver.Clear( ctx, bufferMask, (GLboolean) !ctx->Scissor.Enabled, x, y, width, height ); } } @@ -167,27 +177,41 @@ _mesa_Clear( GLbitfield mask ) /** - * Return bitmask of DD_* flags indicating which color buffers are - * available to the rendering context; + * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are + * available to the rendering context. + * This depends on the framebuffer we're writing to. For window system + * framebuffers we look at the framebuffer's visual. But for user- + * create framebuffers we look at the number of supported color attachments. */ static GLuint -supported_buffer_bitmask(const GLcontext *ctx) +supported_buffer_bitmask(const GLcontext *ctx, GLuint framebufferID) { - GLuint mask = DD_FRONT_LEFT_BIT; /* always have this */ + GLuint mask = 0x0; GLint i; - if (ctx->Visual.stereoMode) { - mask |= DD_FRONT_RIGHT_BIT; - if (ctx->Visual.doubleBufferMode) { - mask |= DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT; + if (framebufferID > 0) { + /* A user-created renderbuffer */ + ASSERT(ctx->Extensions.EXT_framebuffer_object); + for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { + mask |= (BUFFER_BIT_COLOR0 << i); } } - else if (ctx->Visual.doubleBufferMode) { - mask |= DD_BACK_LEFT_BIT; - } + else { + /* A window system renderbuffer */ + mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ + if (ctx->Visual.stereoMode) { + mask |= BUFFER_BIT_FRONT_RIGHT; + if (ctx->Visual.doubleBufferMode) { + mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; + } + } + else if (ctx->Visual.doubleBufferMode) { + mask |= BUFFER_BIT_BACK_LEFT; + } - for (i = 0; i < ctx->Visual.numAuxBuffers; i++) { - mask |= (DD_AUX0_BIT << i); + for (i = 0; i < ctx->Visual.numAuxBuffers; i++) { + mask |= (BUFFER_BIT_AUX0 << i); + } } return mask; @@ -196,45 +220,53 @@ supported_buffer_bitmask(const GLcontext *ctx) /** * Helper routine used by glDrawBuffer and glDrawBuffersARB. - * Given a GLenum naming (a) color buffer(s), return the corresponding - * bitmask of DD_* flags. + * Given a GLenum naming one or more color buffers (such as + * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. */ static GLuint draw_buffer_enum_to_bitmask(GLenum buffer) { switch (buffer) { - case GL_FRONT: - return DD_FRONT_LEFT_BIT | DD_FRONT_RIGHT_BIT; - case GL_BACK: - return DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT; case GL_NONE: return 0; + case GL_FRONT: + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; + case GL_BACK: + return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; case GL_RIGHT: - return DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; case GL_FRONT_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_BACK_RIGHT: - return DD_BACK_RIGHT_BIT; + return BUFFER_BIT_BACK_RIGHT; case GL_BACK_LEFT: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_FRONT_AND_BACK: - return DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT - | DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT; + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT + | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; case GL_LEFT: - return DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; case GL_FRONT_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_AUX0: - return DD_AUX0_BIT; + return BUFFER_BIT_AUX0; case GL_AUX1: - return DD_AUX1_BIT; + return BUFFER_BIT_AUX1; case GL_AUX2: - return DD_AUX2_BIT; + return BUFFER_BIT_AUX2; case GL_AUX3: - return DD_AUX3_BIT; + return BUFFER_BIT_AUX3; + case GL_COLOR_ATTACHMENT0_EXT: + return BUFFER_BIT_COLOR0; + case GL_COLOR_ATTACHMENT1_EXT: + return BUFFER_BIT_COLOR1; + case GL_COLOR_ATTACHMENT2_EXT: + return BUFFER_BIT_COLOR2; + case GL_COLOR_ATTACHMENT3_EXT: + return BUFFER_BIT_COLOR3; default: /* error */ - return ~0; + return BAD_MASK; } } @@ -249,43 +281,48 @@ read_buffer_enum_to_bitmask(GLenum buffer) { switch (buffer) { case GL_FRONT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_BACK: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_FRONT_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_BACK_RIGHT: - return DD_BACK_RIGHT_BIT; + return BUFFER_BIT_BACK_RIGHT; case GL_BACK_LEFT: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_FRONT_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_AUX0: - return DD_AUX0_BIT; + return BUFFER_BIT_AUX0; case GL_AUX1: - return DD_AUX1_BIT; + return BUFFER_BIT_AUX1; case GL_AUX2: - return DD_AUX2_BIT; + return BUFFER_BIT_AUX2; case GL_AUX3: - return DD_AUX3_BIT; + return BUFFER_BIT_AUX3; + case GL_COLOR_ATTACHMENT0_EXT: + return BUFFER_BIT_COLOR0; + case GL_COLOR_ATTACHMENT1_EXT: + return BUFFER_BIT_COLOR1; + case GL_COLOR_ATTACHMENT2_EXT: + return BUFFER_BIT_COLOR2; + case GL_COLOR_ATTACHMENT3_EXT: + return BUFFER_BIT_COLOR3; default: /* error */ - return ~0; + return BAD_MASK; } } - /** * Specify which color buffers to draw into. * - * \param mode color buffer combination. - * - * \sa glDrawBuffer(). + * \param buffer color buffer, such as GL_LEFT or GL_FRONT_AND_BACK. * * Flushes the vertices and verifies the parameter and updates the * gl_colorbuffer_attrib::_DrawDestMask bitfield. Marks new color state in @@ -293,160 +330,180 @@ read_buffer_enum_to_bitmask(GLenum buffer) * dd_function_table::DrawBuffer callback. */ void GLAPIENTRY -_mesa_DrawBuffer( GLenum mode ) +_mesa_DrawBuffer(GLenum buffer) { + GLuint bufferID; + GLuint destMask; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + if (MESA_VERBOSE & VERBOSE_API) { + _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); + } - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set drawbuffer for a framebuffer object */ - if (mode == GL_NONE) { - ctx->CurrentFramebuffer->DrawBuffer[0] = mode; - } - else { - const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - ctx->CurrentFramebuffer->DrawBuffer[0] = mode; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)"); - return; - } - } + bufferID = ctx->DrawBuffer->Name; + + if (buffer == GL_NONE) { + destMask = 0x0; } else { - /* conventional behaviour */ - /* Do error checking and compute the _DrawDestMask bitfield. */ - GLenum destMask, supportedMask; - - destMask = draw_buffer_enum_to_bitmask(mode); - if (destMask == ~0u) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)"); + const GLuint supportedMask = supported_buffer_bitmask(ctx, bufferID); + destMask = draw_buffer_enum_to_bitmask(buffer); + if (destMask == BAD_MASK) { + /* totally bogus buffer */ + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer)"); return; } - - supportedMask = supported_buffer_bitmask(ctx); destMask &= supportedMask; - - if (destMask == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(mode)"); + if (destMask == 0x0) { + /* none of the named color buffers exist! */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(buffer)"); return; } - - ctx->Color.DrawBuffer[0] = mode; - ctx->Color._DrawDestMask[0] = destMask; - ctx->NewState |= _NEW_COLOR; } - /* - * Call device driver function. - */ - if (ctx->Driver.DrawBuffer) - (*ctx->Driver.DrawBuffer)(ctx, mode); + /* if we get here, there's no error so set new state */ + _mesa_drawbuffers(ctx, 1, &buffer, &destMask); } /** * Called by glDrawBuffersARB; specifies the destination color buffers * for N fragment program color outputs. + * + * XXX This function is called by _mesa_PopAttrib() and we need to do + * some more work to deal with the current framebuffer binding state! */ void GLAPIENTRY _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) { + GLint output; + GLuint usedBufferMask, supportedMask; + GLuint bufferID; + GLuint destMask[MAX_DRAW_BUFFERS]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (!ctx->Extensions.ARB_draw_buffers) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB"); + return; + } if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)" ); + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); return; } - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set drawbuffers for a framebuffer object */ - GLint i; - GLuint usedAttachments = 0x0; - for (i = 0; i < n; i++) { - if (buffers[i] == GL_NONE) { - /* OK */ - ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE; - } - else { - const GLint k = buffers[i] - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - if ((1 << k) & usedAttachments) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawBuffersARB(duplicated attachment)"); - return; - } - usedAttachments |= (1 << k); - ctx->CurrentFramebuffer->DrawBuffer[i] = buffers[i]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(mode)"); - return; - } - } - } + bufferID = ctx->DrawBuffer->Name; + + supportedMask = supported_buffer_bitmask(ctx, bufferID); + usedBufferMask = 0x0; - /* set remaining color outputs to NONE */ - for (i = n; i < ctx->Const.MaxDrawBuffers; i++) { - ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE; + /* complicated error checking... */ + for (output = 0; output < n; output++) { + if (buffers[output] == GL_NONE) { + destMask[output] = 0x0; } - } - else { - /* Conventional operation */ - GLint i; - GLuint usedBufferMask, supportedMask; - - supportedMask = supported_buffer_bitmask(ctx); - usedBufferMask = 0; - for (i = 0; i < n; i++) { - GLuint destMask = draw_buffer_enum_to_bitmask(buffers[i]); - if (destMask == ~0u ) { + else { + destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]); + if (destMask[output] == BAD_MASK + || _mesa_bitcount(destMask[output]) > 1) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); return; } - destMask &= supportedMask; - if (destMask == 0) { + destMask[output] &= supportedMask; + if (destMask[output] == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(unsupported buffer)"); return; } - if (destMask & usedBufferMask) { + if (destMask[output] & usedBufferMask) { /* can't specify a dest buffer more than once! */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(duplicated buffer)"); return; } + /* update bitmask */ - usedBufferMask |= destMask; - /* save state */ - ctx->Color.DrawBuffer[i] = buffers[i]; - ctx->Color._DrawDestMask[i] = destMask; + usedBufferMask |= destMask[output]; } + } + + /* OK, if we get here, there were no errors so set the new state */ + _mesa_drawbuffers(ctx, n, buffers, destMask); +} + - /* set remaining color outputs to NONE */ - for (i = n; i < ctx->Const.MaxDrawBuffers; i++) { - ctx->Color.DrawBuffer[i] = GL_NONE; - ctx->Color._DrawDestMask[i] = 0; +/** + * Set color output state. Traditionally, there was only one color + * output, but fragment programs can now have several distinct color + * outputs (see GL_ARB_draw_buffers). This function sets the state + * for one such color output. + */ +static void +set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, GLuint destMask) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + + ASSERT(output < ctx->Const.MaxDrawBuffers); + + fb->ColorDrawBuffer[output] = buffer; + fb->_ColorDrawBufferMask[output] = destMask; + + if (fb->Name == 0) { + /* Set traditional state var */ + ctx->Color.DrawBuffer[output] = buffer; + } + + /* not really needed, will be set later */ + fb->_NumColorDrawBuffers[output] = 0; +} + + +/** + * Helper routine used by _mesa_DrawBuffer, _mesa_DrawBuffersARB and + * _mesa_PopAttrib to set drawbuffer state. + */ +void +_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers, + const GLuint *destMask) +{ + GLuint mask[MAX_DRAW_BUFFERS]; + GLint output; + + if (!destMask) { + /* compute destMask values now */ + const GLuint bufferID = ctx->DrawBuffer->Name; + const GLuint supportedMask = supported_buffer_bitmask(ctx, bufferID); + for (output = 0; output < n; output++) { + mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); + ASSERT(mask[output] != BAD_MASK); + mask[output] &= supportedMask; } + destMask = mask; + } + + for (output = 0; output < n; output++) { + set_color_output(ctx, output, buffers[output], destMask[output]); + } - ctx->NewState |= _NEW_COLOR; + /* set remaining color outputs to NONE */ + for (output = n; output < ctx->Const.MaxDrawBuffers; output++) { + set_color_output(ctx, output, GL_NONE, 0x0); } + ctx->NewState |= _NEW_COLOR; + /* * Call device driver function. */ if (ctx->Driver.DrawBuffers) - (*ctx->Driver.DrawBuffers)(ctx, n, buffers); + ctx->Driver.DrawBuffers(ctx, n, buffers); + else if (ctx->Driver.DrawBuffer) + ctx->Driver.DrawBuffer(ctx, buffers[0]); } + /** * Set the color buffer source for reading pixels. * @@ -454,60 +511,53 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) * * \sa glReadBuffer(). * - * Verifies the parameter and updates gl_pixel_attrib::_ReadSrcMask. Marks - * new pixel state in __GLcontextRec::NewState and notifies the driver via - * dd_function_table::ReadBuffer. */ void GLAPIENTRY -_mesa_ReadBuffer( GLenum mode ) +_mesa_ReadBuffer(GLenum buffer) { + struct gl_framebuffer *fb; + GLuint srcMask, supportedMask; + GLuint bufferID; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + fb = ctx->ReadBuffer; + bufferID = fb->Name; + if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set readbuffer for a framebuffer object */ - if (mode == GL_NONE) { - ctx->CurrentFramebuffer->ReadBuffer = mode; - } - else { - const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - ctx->CurrentFramebuffer->ReadBuffer = mode; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)"); - return; - } - } + if (bufferID > 0 && buffer == GL_NONE) { + /* legal! */ + srcMask = 0x0; } else { - /* conventional operation */ - GLuint srcMask, supportedMask; - - srcMask = read_buffer_enum_to_bitmask(mode); - if (srcMask == ~0u) { - _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)"); + /* general case */ + srcMask = read_buffer_enum_to_bitmask(buffer); + if (srcMask == BAD_MASK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer)"); return; } - supportedMask = supported_buffer_bitmask(ctx); + supportedMask = supported_buffer_bitmask(ctx, bufferID); if ((srcMask & supportedMask) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(mode)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer)"); return; } - ctx->Pixel._ReadSrcMask = srcMask; - ctx->Pixel.ReadBuffer = mode; - ctx->NewState |= _NEW_PIXEL; } + if (bufferID == 0) { + ctx->Pixel.ReadBuffer = buffer; + } + fb->ColorReadBuffer = buffer; + fb->_ColorReadBufferMask = srcMask; + + ctx->NewState |= _NEW_PIXEL; + /* * Call device driver function. */ if (ctx->Driver.ReadBuffer) - (*ctx->Driver.ReadBuffer)(ctx, mode); + (*ctx->Driver.ReadBuffer)(ctx, buffer); } @@ -524,53 +574,51 @@ _mesa_ReadBuffer( GLenum mode ) * \note This function may be called from within Mesa or called by the * user directly (see the GL_MESA_resize_buffers extension). */ +#if OLD_RENDERBUFFER +/* THIS FUNCTION IS OBSOLETE!!! + * See _mesa_resize_framebuffer + */ +#endif void GLAPIENTRY _mesa_ResizeBuffersMESA( void ) { GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glResizeBuffersMESA\n"); - if (ctx) { - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); - - if (ctx->DrawBuffer) { - GLuint buf_width, buf_height; - GLframebuffer *buffer = ctx->DrawBuffer; - - /* ask device driver for size of output buffer */ - (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height ); + if (ctx->DrawBuffer && ctx->DrawBuffer->Name == 0) { + GLuint newWidth, newHeight; + GLframebuffer *buffer = ctx->DrawBuffer; - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width == buf_width && buffer->Height == buf_height) - return; /* size is as expected */ + /* ask device driver for size of output buffer */ + ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - buffer->Width = buf_width; - buffer->Height = buf_height; - - ctx->Driver.ResizeBuffers( buffer ); + /* 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->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer) { - GLuint buf_width, buf_height; - GLframebuffer *buffer = ctx->ReadBuffer; - - /* ask device driver for size of read buffer */ - (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height ); - - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width == buf_width && buffer->Height == buf_height) - return; /* size is as expected */ + if (ctx->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer + && ctx->ReadBuffer->Name == 0) { + GLuint newWidth, newHeight; + GLframebuffer *buffer = ctx->ReadBuffer; - buffer->Width = buf_width; - buffer->Height = buf_height; + /* ask device driver for size of read buffer */ + ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - ctx->Driver.ResizeBuffers( buffer ); + /* 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 */ } + + ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ } @@ -642,56 +690,6 @@ _mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) /**********************************************************************/ -/** \name State management */ -/*@{*/ - - -/** - * 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 - * the scissor box, if it's enabled. - * \param ctx the GL context. - */ -void -_mesa_update_draw_buffer_bounds(GLcontext *ctx) -{ - GLframebuffer *buffer = ctx->DrawBuffer; - - 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); -} - -/*@}*/ - - -/**********************************************************************/ /** \name Initialization */ /*@{*/ |