ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

buffers.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00033 #include "glheader.h"
00034 #include "buffers.h"
00035 #include "colormac.h"
00036 #include "context.h"
00037 #include "enums.h"
00038 #include "fbobject.h"
00039 #include "state.h"
00040 
00041 
00042 #define BAD_MASK ~0u
00043 
00044 
00054 static GLbitfield
00055 supported_buffer_bitmask(const GLcontext *ctx, const struct gl_framebuffer *fb)
00056 {
00057    GLbitfield mask = 0x0;
00058 
00059    if (fb->Name > 0) {
00060       /* A user-created renderbuffer */
00061       GLuint i;
00062       ASSERT(ctx->Extensions.EXT_framebuffer_object);
00063       for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
00064          mask |= (BUFFER_BIT_COLOR0 << i);
00065       }
00066    }
00067    else {
00068       /* A window system framebuffer */
00069       GLint i;
00070       mask = BUFFER_BIT_FRONT_LEFT; /* always have this */
00071       if (fb->Visual.stereoMode) {
00072          mask |= BUFFER_BIT_FRONT_RIGHT;
00073          if (fb->Visual.doubleBufferMode) {
00074             mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
00075          }
00076       }
00077       else if (fb->Visual.doubleBufferMode) {
00078          mask |= BUFFER_BIT_BACK_LEFT;
00079       }
00080 
00081       for (i = 0; i < fb->Visual.numAuxBuffers; i++) {
00082          mask |= (BUFFER_BIT_AUX0 << i);
00083       }
00084    }
00085 
00086    return mask;
00087 }
00088 
00089 
00095 static GLbitfield
00096 draw_buffer_enum_to_bitmask(GLenum buffer)
00097 {
00098    switch (buffer) {
00099       case GL_NONE:
00100          return 0;
00101       case GL_FRONT:
00102          return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
00103       case GL_BACK:
00104          return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
00105       case GL_RIGHT:
00106          return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
00107       case GL_FRONT_RIGHT:
00108          return BUFFER_BIT_FRONT_RIGHT;
00109       case GL_BACK_RIGHT:
00110          return BUFFER_BIT_BACK_RIGHT;
00111       case GL_BACK_LEFT:
00112          return BUFFER_BIT_BACK_LEFT;
00113       case GL_FRONT_AND_BACK:
00114          return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT
00115               | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
00116       case GL_LEFT:
00117          return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT;
00118       case GL_FRONT_LEFT:
00119          return BUFFER_BIT_FRONT_LEFT;
00120       case GL_AUX0:
00121          return BUFFER_BIT_AUX0;
00122       case GL_AUX1:
00123          return BUFFER_BIT_AUX1;
00124       case GL_AUX2:
00125          return BUFFER_BIT_AUX2;
00126       case GL_AUX3:
00127          return BUFFER_BIT_AUX3;
00128       case GL_COLOR_ATTACHMENT0_EXT:
00129          return BUFFER_BIT_COLOR0;
00130       case GL_COLOR_ATTACHMENT1_EXT:
00131          return BUFFER_BIT_COLOR1;
00132       case GL_COLOR_ATTACHMENT2_EXT:
00133          return BUFFER_BIT_COLOR2;
00134       case GL_COLOR_ATTACHMENT3_EXT:
00135          return BUFFER_BIT_COLOR3;
00136       case GL_COLOR_ATTACHMENT4_EXT:
00137          return BUFFER_BIT_COLOR4;
00138       case GL_COLOR_ATTACHMENT5_EXT:
00139          return BUFFER_BIT_COLOR5;
00140       case GL_COLOR_ATTACHMENT6_EXT:
00141          return BUFFER_BIT_COLOR6;
00142       case GL_COLOR_ATTACHMENT7_EXT:
00143          return BUFFER_BIT_COLOR7;
00144       default:
00145          /* error */
00146          return BAD_MASK;
00147    }
00148 }
00149 
00150 
00157 static GLint
00158 read_buffer_enum_to_index(GLenum buffer)
00159 {
00160    switch (buffer) {
00161       case GL_FRONT:
00162          return BUFFER_FRONT_LEFT;
00163       case GL_BACK:
00164          return BUFFER_BACK_LEFT;
00165       case GL_RIGHT:
00166          return BUFFER_FRONT_RIGHT;
00167       case GL_FRONT_RIGHT:
00168          return BUFFER_FRONT_RIGHT;
00169       case GL_BACK_RIGHT:
00170          return BUFFER_BACK_RIGHT;
00171       case GL_BACK_LEFT:
00172          return BUFFER_BACK_LEFT;
00173       case GL_LEFT:
00174          return BUFFER_FRONT_LEFT;
00175       case GL_FRONT_LEFT:
00176          return BUFFER_FRONT_LEFT;
00177       case GL_AUX0:
00178          return BUFFER_AUX0;
00179       case GL_AUX1:
00180          return BUFFER_AUX1;
00181       case GL_AUX2:
00182          return BUFFER_AUX2;
00183       case GL_AUX3:
00184          return BUFFER_AUX3;
00185       case GL_COLOR_ATTACHMENT0_EXT:
00186          return BUFFER_COLOR0;
00187       case GL_COLOR_ATTACHMENT1_EXT:
00188          return BUFFER_COLOR1;
00189       case GL_COLOR_ATTACHMENT2_EXT:
00190          return BUFFER_COLOR2;
00191       case GL_COLOR_ATTACHMENT3_EXT:
00192          return BUFFER_COLOR3;
00193       case GL_COLOR_ATTACHMENT4_EXT:
00194          return BUFFER_COLOR4;
00195       case GL_COLOR_ATTACHMENT5_EXT:
00196          return BUFFER_COLOR5;
00197       case GL_COLOR_ATTACHMENT6_EXT:
00198          return BUFFER_COLOR6;
00199       case GL_COLOR_ATTACHMENT7_EXT:
00200          return BUFFER_COLOR7;
00201       default:
00202          /* error */
00203          return -1;
00204    }
00205 }
00206 
00207 
00230 void GLAPIENTRY
00231 _mesa_DrawBuffer(GLenum buffer)
00232 {
00233    GLbitfield destMask;
00234    GET_CURRENT_CONTEXT(ctx);
00235    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
00236 
00237    if (MESA_VERBOSE & VERBOSE_API) {
00238       _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
00239    }
00240 
00241    if (buffer == GL_NONE) {
00242       destMask = 0x0;
00243    }
00244    else {
00245       const GLbitfield supportedMask
00246          = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
00247       destMask = draw_buffer_enum_to_bitmask(buffer);
00248       if (destMask == BAD_MASK) {
00249          /* totally bogus buffer */
00250          _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer=0x%x)", buffer);
00251          return;
00252       }
00253       destMask &= supportedMask;
00254       if (destMask == 0x0) {
00255          /* none of the named color buffers exist! */
00256          _mesa_error(ctx, GL_INVALID_OPERATION,
00257                      "glDrawBuffer(buffer=0x%x)", buffer);
00258          return;
00259       }
00260    }
00261 
00262    /* if we get here, there's no error so set new state */
00263    _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
00264 
00265    /*
00266     * Call device driver function.
00267     */
00268    if (ctx->Driver.DrawBuffers)
00269       ctx->Driver.DrawBuffers(ctx, 1, &buffer);
00270    else if (ctx->Driver.DrawBuffer)
00271       ctx->Driver.DrawBuffer(ctx, buffer);
00272 }
00273 
00274 
00284 void GLAPIENTRY
00285 _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
00286 {
00287    GLint output;
00288    GLbitfield usedBufferMask, supportedMask;
00289    GLbitfield destMask[MAX_DRAW_BUFFERS];
00290    GET_CURRENT_CONTEXT(ctx);
00291    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
00292 
00293    if (!ctx->Extensions.ARB_draw_buffers) {
00294       _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB");
00295       return;
00296    }
00297    if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
00298       _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
00299       return;
00300    }
00301 
00302    supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
00303    usedBufferMask = 0x0;
00304 
00305    /* complicated error checking... */
00306    for (output = 0; output < n; output++) {
00307       if (buffers[output] == GL_NONE) {
00308          destMask[output] = 0x0;
00309       }
00310       else {
00311          destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
00312          if (destMask[output] == BAD_MASK
00313              || _mesa_bitcount(destMask[output]) > 1) {
00314             _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
00315             return;
00316          }         
00317          destMask[output] &= supportedMask;
00318          if (destMask[output] == 0) {
00319             _mesa_error(ctx, GL_INVALID_OPERATION,
00320                         "glDrawBuffersARB(unsupported buffer)");
00321             return;
00322          }
00323          if (destMask[output] & usedBufferMask) {
00324             /* can't specify a dest buffer more than once! */
00325             _mesa_error(ctx, GL_INVALID_OPERATION,
00326                         "glDrawBuffersARB(duplicated buffer)");
00327             return;
00328          }
00329 
00330          /* update bitmask */
00331          usedBufferMask |= destMask[output];
00332       }
00333    }
00334 
00335    /* OK, if we get here, there were no errors so set the new state */
00336    _mesa_drawbuffers(ctx, n, buffers, destMask);
00337 
00338    /*
00339     * Call device driver function.
00340     */
00341    if (ctx->Driver.DrawBuffers)
00342       ctx->Driver.DrawBuffers(ctx, n, buffers);
00343    else if (ctx->Driver.DrawBuffer)
00344       ctx->Driver.DrawBuffer(ctx, buffers[0]);
00345 }
00346 
00347 
00362 void
00363 _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers,
00364                   const GLbitfield *destMask)
00365 {
00366    struct gl_framebuffer *fb = ctx->DrawBuffer;
00367    GLbitfield mask[MAX_DRAW_BUFFERS];
00368 
00369    if (!destMask) {
00370       /* compute destMask values now */
00371       const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb);
00372       GLuint output;
00373       for (output = 0; output < n; output++) {
00374          mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
00375          ASSERT(mask[output] != BAD_MASK);
00376          mask[output] &= supportedMask;
00377       }
00378       destMask = mask;
00379    }
00380 
00381    if (n == 1) {
00382       GLuint buf, count = 0;
00383       /* init to -1 to help catch errors */
00384       fb->_ColorDrawBufferIndexes[0] = -1;
00385       for (buf = 0; buf < BUFFER_COUNT; buf++) {
00386          if (destMask[0] & (1 << buf)) {
00387             fb->_ColorDrawBufferIndexes[count] = buf;
00388             count++;
00389          }
00390       }
00391       fb->ColorDrawBuffer[0] = buffers[0];
00392       fb->_NumColorDrawBuffers = count;
00393    }
00394    else {
00395       GLuint buf, count = 0;
00396       for (buf = 0; buf < n; buf++ ) {
00397          if (destMask[buf]) {
00398             fb->_ColorDrawBufferIndexes[buf] = _mesa_ffs(destMask[buf]) - 1;
00399             fb->ColorDrawBuffer[buf] = buffers[buf];
00400             count = buf + 1;
00401          }
00402          else {
00403             fb->_ColorDrawBufferIndexes[buf] = -1;
00404          }
00405       }
00406       /* set remaining outputs to -1 (GL_NONE) */
00407       while (buf < ctx->Const.MaxDrawBuffers) {
00408          fb->_ColorDrawBufferIndexes[buf] = -1;
00409          fb->ColorDrawBuffer[buf] = GL_NONE;
00410          buf++;
00411       }
00412       fb->_NumColorDrawBuffers = count;
00413    }
00414 
00415    if (fb->Name == 0) {
00416       /* also set context drawbuffer state */
00417       GLuint buf;
00418       for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
00419          ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf];
00420       }
00421    }
00422 
00423    ctx->NewState |= _NEW_COLOR;
00424 }
00425 
00426 
00434 void
00435 _mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex)
00436 {
00437    struct gl_framebuffer *fb = ctx->ReadBuffer;
00438 
00439    if (fb->Name == 0) {
00440       /* Only update the per-context READ_BUFFER state if we're bound to
00441        * a window-system framebuffer.
00442        */
00443       ctx->Pixel.ReadBuffer = buffer;
00444    }
00445 
00446    fb->ColorReadBuffer = buffer;
00447    fb->_ColorReadBufferIndex = bufferIndex;
00448 
00449    ctx->NewState |= _NEW_PIXEL;
00450 }
00451 
00452 
00453 
00458 void GLAPIENTRY
00459 _mesa_ReadBuffer(GLenum buffer)
00460 {
00461    struct gl_framebuffer *fb;
00462    GLbitfield supportedMask;
00463    GLint srcBuffer;
00464    GET_CURRENT_CONTEXT(ctx);
00465    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
00466 
00467    if (MESA_VERBOSE & VERBOSE_API)
00468       _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
00469 
00470    fb = ctx->ReadBuffer;
00471 
00472    if (MESA_VERBOSE & VERBOSE_API)
00473       _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
00474 
00475    if (fb->Name > 0 && buffer == GL_NONE) {
00476       /* This is legal for user-created framebuffer objects */
00477       srcBuffer = -1;
00478    }
00479    else {
00480       /* general case / window-system framebuffer */
00481       srcBuffer = read_buffer_enum_to_index(buffer);
00482       if (srcBuffer == -1) {
00483          _mesa_error(ctx, GL_INVALID_ENUM,
00484                      "glReadBuffer(buffer=0x%x)", buffer);
00485          return;
00486       }
00487       supportedMask = supported_buffer_bitmask(ctx, fb);
00488       if (((1 << srcBuffer) & supportedMask) == 0) {
00489          _mesa_error(ctx, GL_INVALID_OPERATION,
00490                      "glReadBuffer(buffer=0x%x)", buffer);
00491          return;
00492       }
00493    }
00494 
00495    /* OK, all error checking has been completed now */
00496 
00497    _mesa_readbuffer(ctx, buffer, srcBuffer);
00498 
00499    /*
00500     * Call device driver function.
00501     */
00502    if (ctx->Driver.ReadBuffer)
00503       (*ctx->Driver.ReadBuffer)(ctx, buffer);
00504 }

Generated on Sat May 26 2012 04:18:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.