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

framebuffer.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.2
00004  *
00005  * Copyright (C) 1999-2008  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 "imports.h"
00035 #include "buffers.h"
00036 #include "context.h"
00037 #include "depthstencil.h"
00038 #include "mtypes.h"
00039 #include "fbobject.h"
00040 #include "framebuffer.h"
00041 #include "renderbuffer.h"
00042 #include "texobj.h"
00043 
00044 
00045 
00050 static void
00051 compute_depth_max(struct gl_framebuffer *fb)
00052 {
00053    if (fb->Visual.depthBits == 0) {
00054       /* Special case.  Even if we don't have a depth buffer we need
00055        * good values for DepthMax for Z vertex transformation purposes
00056        * and for per-fragment fog computation.
00057        */
00058       fb->_DepthMax = (1 << 16) - 1;
00059    }
00060    else if (fb->Visual.depthBits < 32) {
00061       fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
00062    }
00063    else {
00064       /* Special case since shift values greater than or equal to the
00065        * number of bits in the left hand expression's type are undefined.
00066        */
00067       fb->_DepthMax = 0xffffffff;
00068    }
00069    fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
00070 
00071    /* Minimum resolvable depth value, for polygon offset */
00072    fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
00073 }
00074 
00075 
00083 struct gl_framebuffer *
00084 _mesa_create_framebuffer(const GLvisual *visual)
00085 {
00086    struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
00087    assert(visual);
00088    if (fb) {
00089       _mesa_initialize_framebuffer(fb, visual);
00090    }
00091    return fb;
00092 }
00093 
00094 
00102 struct gl_framebuffer *
00103 _mesa_new_framebuffer(GLcontext *ctx, GLuint name)
00104 {
00105    struct gl_framebuffer *fb;
00106    (void) ctx;
00107    assert(name != 0);
00108    fb = CALLOC_STRUCT(gl_framebuffer);
00109    if (fb) {
00110       fb->Name = name;
00111       fb->RefCount = 1;
00112       fb->_NumColorDrawBuffers = 1;
00113       fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
00114       fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
00115       fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
00116       fb->_ColorReadBufferIndex = BUFFER_COLOR0;
00117       fb->Delete = _mesa_destroy_framebuffer;
00118       _glthread_INIT_MUTEX(fb->Mutex);
00119    }
00120    return fb;
00121 }
00122 
00123 
00129 void
00130 _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual)
00131 {
00132    assert(fb);
00133    assert(visual);
00134 
00135    _mesa_bzero(fb, sizeof(struct gl_framebuffer));
00136 
00137    _glthread_INIT_MUTEX(fb->Mutex);
00138 
00139    fb->RefCount = 1;
00140 
00141    /* save the visual */
00142    fb->Visual = *visual;
00143 
00144    /* Init read/draw renderbuffer state */
00145    if (visual->doubleBufferMode) {
00146       fb->_NumColorDrawBuffers = 1;
00147       fb->ColorDrawBuffer[0] = GL_BACK;
00148       fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
00149       fb->ColorReadBuffer = GL_BACK;
00150       fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
00151    }
00152    else {
00153       fb->_NumColorDrawBuffers = 1;
00154       fb->ColorDrawBuffer[0] = GL_FRONT;
00155       fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
00156       fb->ColorReadBuffer = GL_FRONT;
00157       fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
00158    }
00159 
00160    fb->Delete = _mesa_destroy_framebuffer;
00161    fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
00162 
00163    compute_depth_max(fb);
00164 }
00165 
00166 
00171 void
00172 _mesa_destroy_framebuffer(struct gl_framebuffer *fb)
00173 {
00174    if (fb) {
00175       _mesa_free_framebuffer_data(fb);
00176       _mesa_free(fb);
00177    }
00178 }
00179 
00180 
00185 void
00186 _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
00187 {
00188    GLuint i;
00189 
00190    assert(fb);
00191    assert(fb->RefCount == 0);
00192 
00193    _glthread_DESTROY_MUTEX(fb->Mutex);
00194 
00195    for (i = 0; i < BUFFER_COUNT; i++) {
00196       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
00197       if (att->Renderbuffer) {
00198          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
00199       }
00200       if (att->Texture) {
00201          _mesa_reference_texobj(&att->Texture, NULL);
00202       }
00203       ASSERT(!att->Renderbuffer);
00204       ASSERT(!att->Texture);
00205       att->Type = GL_NONE;
00206    }
00207 
00208    /* unbind _Depth/_StencilBuffer to decr ref counts */
00209    _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
00210    _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
00211 }
00212 
00213 
00217 void
00218 _mesa_reference_framebuffer(struct gl_framebuffer **ptr,
00219                             struct gl_framebuffer *fb)
00220 {
00221    assert(ptr);
00222    if (*ptr == fb) {
00223       /* no change */
00224       return;
00225    }
00226    if (*ptr) {
00227       _mesa_unreference_framebuffer(ptr);
00228    }
00229    assert(!*ptr);
00230    assert(fb);
00231    _glthread_LOCK_MUTEX(fb->Mutex);
00232    fb->RefCount++;
00233    _glthread_UNLOCK_MUTEX(fb->Mutex);
00234    *ptr = fb;
00235 }
00236 
00237 
00244 void
00245 _mesa_unreference_framebuffer(struct gl_framebuffer **fb)
00246 {
00247    assert(fb);
00248    if (*fb) {
00249       GLboolean deleteFlag = GL_FALSE;
00250 
00251       _glthread_LOCK_MUTEX((*fb)->Mutex);
00252       ASSERT((*fb)->RefCount > 0);
00253       (*fb)->RefCount--;
00254       deleteFlag = ((*fb)->RefCount == 0);
00255       _glthread_UNLOCK_MUTEX((*fb)->Mutex);
00256       
00257       if (deleteFlag)
00258          (*fb)->Delete(*fb);
00259 
00260       *fb = NULL;
00261    }
00262 }
00263 
00264 
00265 
00266 
00277 void
00278 _mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
00279                          GLuint width, GLuint height)
00280 {
00281    GLuint i;
00282 
00283    /* XXX I think we could check if the size is not changing
00284     * and return early.
00285     */
00286 
00287    /* For window system framebuffers, Name is zero */
00288    assert(fb->Name == 0);
00289 
00290    for (i = 0; i < BUFFER_COUNT; i++) {
00291       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
00292       if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
00293          struct gl_renderbuffer *rb = att->Renderbuffer;
00294          /* only resize if size is changing */
00295          if (rb->Width != width || rb->Height != height) {
00296             /* could just as well pass rb->_ActualFormat here */
00297             if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
00298                ASSERT(rb->Width == width);
00299                ASSERT(rb->Height == height);
00300             }
00301             else {
00302                _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
00303                /* no return */
00304             }
00305          }
00306       }
00307    }
00308 
00309    if (fb->_DepthBuffer) {
00310       struct gl_renderbuffer *rb = fb->_DepthBuffer;
00311       if (rb->Width != width || rb->Height != height) {
00312          if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
00313             _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
00314          }
00315       }
00316    }
00317 
00318    if (fb->_StencilBuffer) {
00319       struct gl_renderbuffer *rb = fb->_StencilBuffer;
00320       if (rb->Width != width || rb->Height != height) {
00321          if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
00322             _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
00323          }
00324       }
00325    }
00326 
00327    fb->Width = width;
00328    fb->Height = height;
00329 
00330    if (ctx) {
00331       /* update scissor / window bounds */
00332       _mesa_update_draw_buffer_bounds(ctx);
00333       /* Signal new buffer state so that swrast will update its clipping
00334        * info (the CLIP_BIT flag).
00335        */
00336       ctx->NewState |= _NEW_BUFFERS;
00337    }
00338 }
00339 
00340 
00341 
00356 void
00357 _mesa_resizebuffers( GLcontext *ctx )
00358 {
00359    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
00360 
00361    if (MESA_VERBOSE & VERBOSE_API)
00362       _mesa_debug(ctx, "glResizeBuffersMESA\n");
00363 
00364    if (!ctx->Driver.GetBufferSize) {
00365       return;
00366    }
00367 
00368    if (ctx->WinSysDrawBuffer) {
00369       GLuint newWidth, newHeight;
00370       GLframebuffer *buffer = ctx->WinSysDrawBuffer;
00371 
00372       assert(buffer->Name == 0);
00373 
00374       /* ask device driver for size of output buffer */
00375       ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
00376 
00377       /* see if size of device driver's color buffer (window) has changed */
00378       if (buffer->Width != newWidth || buffer->Height != newHeight) {
00379          if (ctx->Driver.ResizeBuffers)
00380             ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
00381       }
00382    }
00383 
00384    if (ctx->WinSysReadBuffer
00385        && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
00386       GLuint newWidth, newHeight;
00387       GLframebuffer *buffer = ctx->WinSysReadBuffer;
00388 
00389       assert(buffer->Name == 0);
00390 
00391       /* ask device driver for size of read buffer */
00392       ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
00393 
00394       /* see if size of device driver's color buffer (window) has changed */
00395       if (buffer->Width != newWidth || buffer->Height != newHeight) {
00396          if (ctx->Driver.ResizeBuffers)
00397             ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
00398       }
00399    }
00400 
00401    ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
00402 }
00403 
00404 
00405 /*
00406  * XXX THIS IS OBSOLETE
00407  */
00408 void GLAPIENTRY
00409 _mesa_ResizeBuffersMESA( void )
00410 {
00411    GET_CURRENT_CONTEXT(ctx);
00412 
00413    if (ctx->Extensions.MESA_resize_buffers)
00414       _mesa_resizebuffers( ctx );
00415 }
00416 
00417 
00418 
00426 static void
00427 update_framebuffer_size(struct gl_framebuffer *fb)
00428 {
00429    GLboolean haveSize = GL_FALSE;
00430    GLuint i;
00431 
00432    /* user-created framebuffers only */
00433    assert(fb->Name);
00434 
00435    for (i = 0; i < BUFFER_COUNT; i++) {
00436       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
00437       const struct gl_renderbuffer *rb = att->Renderbuffer;
00438       if (rb) {
00439          if (haveSize) {
00440             if (rb->Width != fb->Width && rb->Height != fb->Height) {
00441                /* size mismatch! */
00442                fb->Width = 0;
00443                fb->Height = 0;
00444                return;
00445             }
00446          }
00447          else {
00448             fb->Width = rb->Width;
00449             fb->Height = rb->Height;
00450             haveSize = GL_TRUE;
00451          }
00452       }
00453    }
00454 }
00455 
00456 
00463 void
00464 _mesa_update_draw_buffer_bounds(GLcontext *ctx)
00465 {
00466    struct gl_framebuffer *buffer = ctx->DrawBuffer;
00467 
00468    if (!buffer)
00469       return;
00470 
00471    if (buffer->Name) {
00472       /* user-created framebuffer size depends on the renderbuffers */
00473       update_framebuffer_size(buffer);
00474    }
00475 
00476    buffer->_Xmin = 0;
00477    buffer->_Ymin = 0;
00478    buffer->_Xmax = buffer->Width;
00479    buffer->_Ymax = buffer->Height;
00480 
00481    if (ctx->Scissor.Enabled) {
00482       if (ctx->Scissor.X > buffer->_Xmin) {
00483      buffer->_Xmin = ctx->Scissor.X;
00484       }
00485       if (ctx->Scissor.Y > buffer->_Ymin) {
00486      buffer->_Ymin = ctx->Scissor.Y;
00487       }
00488       if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
00489      buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
00490       }
00491       if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
00492      buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
00493       }
00494       /* finally, check for empty region */
00495       if (buffer->_Xmin > buffer->_Xmax) {
00496          buffer->_Xmin = buffer->_Xmax;
00497       }
00498       if (buffer->_Ymin > buffer->_Ymax) {
00499          buffer->_Ymin = buffer->_Ymax;
00500       }
00501    }
00502 
00503    ASSERT(buffer->_Xmin <= buffer->_Xmax);
00504    ASSERT(buffer->_Ymin <= buffer->_Ymax);
00505 }
00506 
00507 
00521 void
00522 _mesa_update_framebuffer_visual(struct gl_framebuffer *fb)
00523 {
00524    GLuint i;
00525 
00526    _mesa_bzero(&fb->Visual, sizeof(fb->Visual));
00527    fb->Visual.rgbMode = GL_TRUE; /* assume this */
00528 
00529 #if 0 /* this _might_ be needed */
00530    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
00531       /* leave visual fields zero'd */
00532       return;
00533    }
00534 #endif
00535 
00536    /* find first RGB or CI renderbuffer */
00537    for (i = 0; i < BUFFER_COUNT; i++) {
00538       if (fb->Attachment[i].Renderbuffer) {
00539          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
00540          if (rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB) {
00541             fb->Visual.redBits = rb->RedBits;
00542             fb->Visual.greenBits = rb->GreenBits;
00543             fb->Visual.blueBits = rb->BlueBits;
00544             fb->Visual.alphaBits = rb->AlphaBits;
00545             fb->Visual.rgbBits = fb->Visual.redBits
00546                + fb->Visual.greenBits + fb->Visual.blueBits;
00547             fb->Visual.floatMode = GL_FALSE;
00548             break;
00549          }
00550          else if (rb->_BaseFormat == GL_COLOR_INDEX) {
00551             fb->Visual.indexBits = rb->IndexBits;
00552             fb->Visual.rgbMode = GL_FALSE;
00553             break;
00554          }
00555       }
00556    }
00557 
00558    if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
00559       fb->Visual.haveDepthBuffer = GL_TRUE;
00560       fb->Visual.depthBits
00561          = fb->Attachment[BUFFER_DEPTH].Renderbuffer->DepthBits;
00562    }
00563 
00564    if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
00565       fb->Visual.haveStencilBuffer = GL_TRUE;
00566       fb->Visual.stencilBits
00567          = fb->Attachment[BUFFER_STENCIL].Renderbuffer->StencilBits;
00568    }
00569 
00570    if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
00571       fb->Visual.haveAccumBuffer = GL_TRUE;
00572       fb->Visual.accumRedBits
00573          = fb->Attachment[BUFFER_ACCUM].Renderbuffer->RedBits;
00574       fb->Visual.accumGreenBits
00575          = fb->Attachment[BUFFER_ACCUM].Renderbuffer->GreenBits;
00576       fb->Visual.accumBlueBits
00577          = fb->Attachment[BUFFER_ACCUM].Renderbuffer->BlueBits;
00578       fb->Visual.accumAlphaBits
00579          = fb->Attachment[BUFFER_ACCUM].Renderbuffer->AlphaBits;
00580    }
00581 
00582    compute_depth_max(fb);
00583 }
00584 
00585 
00596 void
00597 _mesa_update_depth_buffer(GLcontext *ctx,
00598                           struct gl_framebuffer *fb,
00599                           GLuint attIndex)
00600 {
00601    struct gl_renderbuffer *depthRb;
00602 
00603    /* only one possiblity for now */
00604    ASSERT(attIndex == BUFFER_DEPTH);
00605 
00606    depthRb = fb->Attachment[attIndex].Renderbuffer;
00607 
00608    if (depthRb && depthRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
00609       /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
00610       if (!fb->_DepthBuffer
00611           || fb->_DepthBuffer->Wrapped != depthRb
00612           || fb->_DepthBuffer->_BaseFormat != GL_DEPTH_COMPONENT) {
00613          /* need to update wrapper */
00614          struct gl_renderbuffer *wrapper
00615             = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
00616          _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
00617          ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
00618       }
00619    }
00620    else {
00621       /* depthRb may be null */
00622       _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
00623    }
00624 }
00625 
00626 
00637 void
00638 _mesa_update_stencil_buffer(GLcontext *ctx,
00639                             struct gl_framebuffer *fb,
00640                             GLuint attIndex)
00641 {
00642    struct gl_renderbuffer *stencilRb;
00643 
00644    ASSERT(attIndex == BUFFER_DEPTH ||
00645           attIndex == BUFFER_STENCIL);
00646 
00647    stencilRb = fb->Attachment[attIndex].Renderbuffer;
00648 
00649    if (stencilRb && stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
00650       /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
00651       if (!fb->_StencilBuffer
00652           || fb->_StencilBuffer->Wrapped != stencilRb
00653           || fb->_StencilBuffer->_BaseFormat != GL_STENCIL_INDEX) {
00654          /* need to update wrapper */
00655          struct gl_renderbuffer *wrapper
00656             = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
00657          _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
00658          ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
00659       }
00660    }
00661    else {
00662       /* stencilRb may be null */
00663       _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
00664    }
00665 }
00666 
00667 
00668 /*
00669  * Example DrawBuffers scenarios:
00670  *
00671  * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
00672  * "gl_FragColor" or program writes to the "result.color" register:
00673  *
00674  *   fragment color output   renderbuffer
00675  *   ---------------------   ---------------
00676  *   color[0]                Front, Back
00677  *
00678  *
00679  * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
00680  * gl_FragData[i] or program writes to result.color[i] registers:
00681  *
00682  *   fragment color output   renderbuffer
00683  *   ---------------------   ---------------
00684  *   color[0]                Front
00685  *   color[1]                Aux0
00686  *   color[3]                Aux1
00687  *
00688  *
00689  * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
00690  * gl_FragColor, or fixed function:
00691  *
00692  *   fragment color output   renderbuffer
00693  *   ---------------------   ---------------
00694  *   color[0]                Front, Aux0, Aux1
00695  *
00696  *
00697  * In either case, the list of renderbuffers is stored in the
00698  * framebuffer->_ColorDrawBuffers[] array and
00699  * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
00700  * The renderer (like swrast) has to look at the current fragment shader
00701  * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
00702  * how to map color outputs to renderbuffers.
00703  *
00704  * Note that these two calls are equivalent (for fixed function fragment
00705  * shading anyway):
00706  *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
00707  *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
00708  */
00709 
00710 
00711 
00712 
00718 static void
00719 update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
00720 {
00721    GLuint output;
00722 
00723    /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
00724    fb->_ColorDrawBuffers[0] = NULL;
00725 
00726    for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
00727       GLint buf = fb->_ColorDrawBufferIndexes[output];
00728       if (buf >= 0) {
00729          fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
00730       }
00731       else {
00732          fb->_ColorDrawBuffers[output] = NULL;
00733       }
00734    }
00735 }
00736 
00737 
00742 static void
00743 update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
00744 {
00745    (void) ctx;
00746    if (fb->_ColorReadBufferIndex == -1 ||
00747        fb->DeletePending ||
00748        fb->Width == 0 ||
00749        fb->Height == 0) {
00750       fb->_ColorReadBuffer = NULL; /* legal! */
00751    }
00752    else {
00753       ASSERT(fb->_ColorReadBufferIndex >= 0);
00754       ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
00755       fb->_ColorReadBuffer
00756          = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
00757    }
00758 }
00759 
00760 
00777 static void
00778 update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
00779 {
00780    if (fb->Name == 0) {
00781       /* This is a window-system framebuffer */
00782       /* Need to update the FB's GL_DRAW_BUFFER state to match the
00783        * context state (GL_READ_BUFFER too).
00784        */
00785       if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
00786          _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
00787                            ctx->Color.DrawBuffer, NULL);
00788       }
00789       if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) {
00790          
00791       }
00792    }
00793    else {
00794       /* This is a user-created framebuffer.
00795        * Completeness only matters for user-created framebuffers.
00796        */
00797       _mesa_test_framebuffer_completeness(ctx, fb);
00798       _mesa_update_framebuffer_visual(fb);
00799    }
00800 
00801    /* Strictly speaking, we don't need to update the draw-state
00802     * if this FB is bound as ctx->ReadBuffer (and conversely, the
00803     * read-state if this FB is bound as ctx->DrawBuffer), but no
00804     * harm.
00805     */
00806    update_color_draw_buffers(ctx, fb);
00807    update_color_read_buffer(ctx, fb);
00808    _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
00809    _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);
00810 
00811    compute_depth_max(fb);
00812 }
00813 
00814 
00818 void
00819 _mesa_update_framebuffer(GLcontext *ctx)
00820 {
00821    struct gl_framebuffer *drawFb = ctx->DrawBuffer;
00822    struct gl_framebuffer *readFb = ctx->ReadBuffer;
00823 
00824    update_framebuffer(ctx, drawFb);
00825    if (readFb != drawFb)
00826       update_framebuffer(ctx, readFb);
00827 }
00828 
00829 
00837 GLboolean
00838 _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
00839 {
00840    const struct gl_renderbuffer_attachment *att
00841       = ctx->ReadBuffer->Attachment;
00842 
00843    if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
00844       return GL_FALSE;
00845    }
00846 
00847    switch (format) {
00848    case GL_COLOR:
00849    case GL_RED:
00850    case GL_GREEN:
00851    case GL_BLUE:
00852    case GL_ALPHA:
00853    case GL_LUMINANCE:
00854    case GL_LUMINANCE_ALPHA:
00855    case GL_INTENSITY:
00856    case GL_RGB:
00857    case GL_BGR:
00858    case GL_RGBA:
00859    case GL_BGRA:
00860    case GL_ABGR_EXT:
00861    case GL_COLOR_INDEX:
00862       if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
00863          return GL_FALSE;
00864       }
00865       /* XXX enable this post 6.5 release:
00866       ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||
00867              ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);
00868       */
00869       break;
00870    case GL_DEPTH:
00871    case GL_DEPTH_COMPONENT:
00872       if (!att[BUFFER_DEPTH].Renderbuffer) {
00873          return GL_FALSE;
00874       }
00875       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
00876       break;
00877    case GL_STENCIL:
00878    case GL_STENCIL_INDEX:
00879       if (!att[BUFFER_STENCIL].Renderbuffer) {
00880          return GL_FALSE;
00881       }
00882       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
00883       break;
00884    case GL_DEPTH_STENCIL_EXT:
00885       if (!att[BUFFER_DEPTH].Renderbuffer ||
00886           !att[BUFFER_STENCIL].Renderbuffer) {
00887          return GL_FALSE;
00888       }
00889       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
00890       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
00891       break;
00892    default:
00893       _mesa_problem(ctx,
00894                     "Unexpected format 0x%x in _mesa_source_buffer_exists",
00895                     format);
00896       return GL_FALSE;
00897    }
00898 
00899    /* OK */
00900    return GL_TRUE;
00901 }
00902 
00903 
00908 GLboolean
00909 _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
00910 {
00911    const struct gl_renderbuffer_attachment *att
00912       = ctx->ReadBuffer->Attachment;
00913 
00914    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
00915       return GL_FALSE;
00916    }
00917 
00918    switch (format) {
00919    case GL_COLOR:
00920    case GL_RED:
00921    case GL_GREEN:
00922    case GL_BLUE:
00923    case GL_ALPHA:
00924    case GL_LUMINANCE:
00925    case GL_LUMINANCE_ALPHA:
00926    case GL_INTENSITY:
00927    case GL_RGB:
00928    case GL_BGR:
00929    case GL_RGBA:
00930    case GL_BGRA:
00931    case GL_ABGR_EXT:
00932    case GL_COLOR_INDEX:
00933       /* nothing special */
00934       /* Could assert that colorbuffer has RedBits > 0 */
00935       break;
00936    case GL_DEPTH:
00937    case GL_DEPTH_COMPONENT:
00938       if (!att[BUFFER_DEPTH].Renderbuffer) {
00939          return GL_FALSE;
00940       }
00941       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
00942       break;
00943    case GL_STENCIL:
00944    case GL_STENCIL_INDEX:
00945       if (!att[BUFFER_STENCIL].Renderbuffer) {
00946          return GL_FALSE;
00947       }
00948       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
00949       break;
00950    case GL_DEPTH_STENCIL_EXT:
00951       if (!att[BUFFER_DEPTH].Renderbuffer ||
00952           !att[BUFFER_STENCIL].Renderbuffer) {
00953          return GL_FALSE;
00954       }
00955       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
00956       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
00957       break;
00958    default:
00959       _mesa_problem(ctx,
00960                     "Unexpected format 0x%x in _mesa_source_buffer_exists",
00961                     format);
00962       return GL_FALSE;
00963    }
00964 
00965    /* OK */
00966    return GL_TRUE;
00967 }

Generated on Sun May 27 2012 04:20:17 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.