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

renderbuffer.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  6.5
00004  *
00005  * Copyright (C) 1999-2006  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 
00043 #include "glheader.h"
00044 #include "imports.h"
00045 #include "context.h"
00046 #include "mtypes.h"
00047 #include "fbobject.h"
00048 #include "renderbuffer.h"
00049 
00050 #include "rbadaptors.h"
00051 
00052 
00053 /* 32-bit color index format.  Not a public format. */
00054 #define COLOR_INDEX32 0x424243
00055 
00056 
00057 /*
00058  * Routines for get/put values in common buffer formats follow.
00059  * Someday add support for arbitrary row stride to make them more
00060  * flexible.
00061  */
00062 
00063 /**********************************************************************
00064  * Functions for buffers of 1 X GLubyte values.
00065  * Typically stencil.
00066  */
00067 
00068 static void *
00069 get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
00070                   GLint x, GLint y)
00071 {
00072    if (!rb->Data)
00073       return NULL;
00074    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00075    /* Can't assert _ActualFormat since these funcs may be used for serveral
00076     * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
00077     */
00078    return (GLubyte *) rb->Data + y * rb->Width + x;
00079 }
00080 
00081 
00082 static void
00083 get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00084               GLint x, GLint y, void *values)
00085 {
00086    const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
00087    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00088    _mesa_memcpy(values, src, count * sizeof(GLubyte));
00089 }
00090 
00091 
00092 static void
00093 get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00094                  const GLint x[], const GLint y[], void *values)
00095 {
00096    GLubyte *dst = (GLubyte *) values;
00097    GLuint i;
00098    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00099    for (i = 0; i < count; i++) {
00100       const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
00101       dst[i] = *src;
00102    }
00103 }
00104 
00105 
00106 static void
00107 put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00108               GLint x, GLint y, const void *values, const GLubyte *mask)
00109 {
00110    const GLubyte *src = (const GLubyte *) values;
00111    GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
00112    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00113    if (mask) {
00114       GLuint i;
00115       for (i = 0; i < count; i++) {
00116          if (mask[i]) {
00117             dst[i] = src[i];
00118          }
00119       }
00120    }
00121    else {
00122       _mesa_memcpy(dst, values, count * sizeof(GLubyte));
00123    }
00124 }
00125 
00126 
00127 static void
00128 put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00129                    GLint x, GLint y, const void *value, const GLubyte *mask)
00130 {
00131    const GLubyte val = *((const GLubyte *) value);
00132    GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
00133    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00134    if (mask) {
00135       GLuint i;
00136       for (i = 0; i < count; i++) {
00137          if (mask[i]) {
00138             dst[i] = val;
00139          }
00140       }
00141    }
00142    else {
00143       GLuint i;
00144       for (i = 0; i < count; i++) {
00145          dst[i] = val;
00146       }
00147    }
00148 }
00149 
00150 
00151 static void
00152 put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00153                  const GLint x[], const GLint y[],
00154                  const void *values, const GLubyte *mask)
00155 {
00156    const GLubyte *src = (const GLubyte *) values;
00157    GLuint i;
00158    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00159    for (i = 0; i < count; i++) {
00160       if (!mask || mask[i]) {
00161          GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
00162          *dst = src[i];
00163       }
00164    }
00165 }
00166 
00167 
00168 static void
00169 put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00170                       const GLint x[], const GLint y[],
00171                       const void *value, const GLubyte *mask)
00172 {
00173    const GLubyte val = *((const GLubyte *) value);
00174    GLuint i;
00175    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00176    for (i = 0; i < count; i++) {
00177       if (!mask || mask[i]) {
00178          GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
00179          *dst = val;
00180       }
00181    }
00182 }
00183 
00184 
00185 /**********************************************************************
00186  * Functions for buffers of 1 X GLushort values.
00187  * Typically depth/Z.
00188  */
00189 
00190 static void *
00191 get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
00192                    GLint x, GLint y)
00193 {
00194    if (!rb->Data)
00195       return NULL;
00196    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00197    ASSERT(rb->Width > 0);
00198    return (GLushort *) rb->Data + y * rb->Width + x;
00199 }
00200 
00201 
00202 static void
00203 get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00204                GLint x, GLint y, void *values)
00205 {
00206    const void *src = rb->GetPointer(ctx, rb, x, y);
00207    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00208    _mesa_memcpy(values, src, count * sizeof(GLushort));
00209 }
00210 
00211 
00212 static void
00213 get_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00214                   const GLint x[], const GLint y[], void *values)
00215 {
00216    GLushort *dst = (GLushort *) values;
00217    GLuint i;
00218    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00219    for (i = 0; i < count; i++) {
00220       const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
00221       dst[i] = *src;
00222    }
00223 }
00224 
00225 
00226 static void
00227 put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00228                GLint x, GLint y, const void *values, const GLubyte *mask)
00229 {
00230    const GLushort *src = (const GLushort *) values;
00231    GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
00232    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00233    if (mask) {
00234       GLuint i;
00235       for (i = 0; i < count; i++) {
00236          if (mask[i]) {
00237             dst[i] = src[i];
00238          }
00239       }
00240    }
00241    else {
00242       _mesa_memcpy(dst, src, count * sizeof(GLushort));
00243    }
00244 }
00245 
00246 
00247 static void
00248 put_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00249                     GLint x, GLint y, const void *value, const GLubyte *mask)
00250 {
00251    const GLushort val = *((const GLushort *) value);
00252    GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
00253    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00254    if (mask) {
00255       GLuint i;
00256       for (i = 0; i < count; i++) {
00257          if (mask[i]) {
00258             dst[i] = val;
00259          }
00260       }
00261    }
00262    else {
00263       GLuint i;
00264       for (i = 0; i < count; i++) {
00265          dst[i] = val;
00266       }
00267    }
00268 }
00269 
00270 
00271 static void
00272 put_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00273                   const GLint x[], const GLint y[], const void *values,
00274                   const GLubyte *mask)
00275 {
00276    const GLushort *src = (const GLushort *) values;
00277    GLuint i;
00278    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00279    for (i = 0; i < count; i++) {
00280       if (!mask || mask[i]) {
00281          GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
00282          *dst = src[i];
00283       }
00284    }
00285 }
00286  
00287 
00288 static void
00289 put_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
00290                        GLuint count, const GLint x[], const GLint y[],
00291                        const void *value, const GLubyte *mask)
00292 {
00293    const GLushort val = *((const GLushort *) value);
00294    ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
00295    if (mask) {
00296       GLuint i;
00297       for (i = 0; i < count; i++) {
00298          if (mask[i]) {
00299             GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
00300             *dst = val;
00301          }
00302       }
00303    }
00304    else {
00305       GLuint i;
00306       for (i = 0; i < count; i++) {
00307          GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
00308          *dst = val;
00309       }
00310    }
00311 }
00312  
00313 
00314 /**********************************************************************
00315  * Functions for buffers of 1 X GLuint values.
00316  * Typically depth/Z or color index.
00317  */
00318 
00319 static void *
00320 get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
00321                  GLint x, GLint y)
00322 {
00323    if (!rb->Data)
00324       return NULL;
00325    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00326           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00327    return (GLuint *) rb->Data + y * rb->Width + x;
00328 }
00329 
00330 
00331 static void
00332 get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00333              GLint x, GLint y, void *values)
00334 {
00335    const void *src = rb->GetPointer(ctx, rb, x, y);
00336    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00337           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00338    _mesa_memcpy(values, src, count * sizeof(GLuint));
00339 }
00340 
00341 
00342 static void
00343 get_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00344                 const GLint x[], const GLint y[], void *values)
00345 {
00346    GLuint *dst = (GLuint *) values;
00347    GLuint i;
00348    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00349           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00350    for (i = 0; i < count; i++) {
00351       const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
00352       dst[i] = *src;
00353    }
00354 }
00355 
00356 
00357 static void
00358 put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00359              GLint x, GLint y, const void *values, const GLubyte *mask)
00360 {
00361    const GLuint *src = (const GLuint *) values;
00362    GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
00363    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00364           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00365    if (mask) {
00366       GLuint i;
00367       for (i = 0; i < count; i++) {
00368          if (mask[i]) {
00369             dst[i] = src[i];
00370          }
00371       }
00372    }
00373    else {
00374       _mesa_memcpy(dst, src, count * sizeof(GLuint));
00375    }
00376 }
00377 
00378 
00379 static void
00380 put_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00381                   GLint x, GLint y, const void *value, const GLubyte *mask)
00382 {
00383    const GLuint val = *((const GLuint *) value);
00384    GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
00385    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00386           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00387    if (mask) {
00388       GLuint i;
00389       for (i = 0; i < count; i++) {
00390          if (mask[i]) {
00391             dst[i] = val;
00392          }
00393       }
00394    }
00395    else {
00396       GLuint i;
00397       for (i = 0; i < count; i++) {
00398          dst[i] = val;
00399       }
00400    }
00401 }
00402 
00403 
00404 static void
00405 put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00406                 const GLint x[], const GLint y[], const void *values,
00407                 const GLubyte *mask)
00408 {
00409    const GLuint *src = (const GLuint *) values;
00410    GLuint i;
00411    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00412           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00413    for (i = 0; i < count; i++) {
00414       if (!mask || mask[i]) {
00415          GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
00416          *dst = src[i];
00417       }
00418    }
00419 }
00420 
00421 
00422 static void
00423 put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00424                      const GLint x[], const GLint y[], const void *value,
00425                      const GLubyte *mask)
00426 {
00427    const GLuint val = *((const GLuint *) value);
00428    GLuint i;
00429    ASSERT(rb->DataType == GL_UNSIGNED_INT ||
00430           rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
00431    for (i = 0; i < count; i++) {
00432       if (!mask || mask[i]) {
00433          GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
00434          *dst = val;
00435       }
00436    }
00437 }
00438 
00439 
00440 /**********************************************************************
00441  * Functions for buffers of 3 X GLubyte (or GLbyte) values.
00442  * Typically color buffers.
00443  * NOTE: the incoming and outgoing colors are RGBA!  We ignore incoming
00444  * alpha values and return 255 for outgoing alpha values.
00445  */
00446 
00447 static void *
00448 get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
00449                    GLint x, GLint y)
00450 {
00451    ASSERT(rb->_ActualFormat == GL_RGB8);
00452    /* No direct access since this buffer is RGB but caller will be
00453     * treating it as if it were RGBA.
00454     */
00455    return NULL;
00456 }
00457 
00458 
00459 static void
00460 get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00461                GLint x, GLint y, void *values)
00462 {
00463    const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
00464    GLubyte *dst = (GLubyte *) values;
00465    GLuint i;
00466    ASSERT(rb->_ActualFormat == GL_RGB8);
00467    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00468    for (i = 0; i < count; i++) {
00469       dst[i * 4 + 0] = src[i * 3 + 0];
00470       dst[i * 4 + 1] = src[i * 3 + 1];
00471       dst[i * 4 + 2] = src[i * 3 + 2];
00472       dst[i * 4 + 3] = 255;
00473    }
00474 }
00475 
00476 
00477 static void
00478 get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00479                   const GLint x[], const GLint y[], void *values)
00480 {
00481    GLubyte *dst = (GLubyte *) values;
00482    GLuint i;
00483    ASSERT(rb->_ActualFormat == GL_RGB8);
00484    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00485    for (i = 0; i < count; i++) {
00486       const GLubyte *src
00487          = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
00488       dst[i * 4 + 0] = src[0];
00489       dst[i * 4 + 1] = src[1];
00490       dst[i * 4 + 2] = src[2];
00491       dst[i * 4 + 3] = 255;
00492    }
00493 }
00494 
00495 
00496 static void
00497 put_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00498                GLint x, GLint y, const void *values, const GLubyte *mask)
00499 {
00500    /* note: incoming values are RGB+A! */
00501    const GLubyte *src = (const GLubyte *) values;
00502    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
00503    GLuint i;
00504    ASSERT(rb->_ActualFormat == GL_RGB8);
00505    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00506    for (i = 0; i < count; i++) {
00507       if (!mask || mask[i]) {
00508          dst[i * 3 + 0] = src[i * 4 + 0];
00509          dst[i * 3 + 1] = src[i * 4 + 1];
00510          dst[i * 3 + 2] = src[i * 4 + 2];
00511       }
00512    }
00513 }
00514 
00515 
00516 static void
00517 put_row_rgb_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00518                    GLint x, GLint y, const void *values, const GLubyte *mask)
00519 {
00520    /* note: incoming values are RGB+A! */
00521    const GLubyte *src = (const GLubyte *) values;
00522    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
00523    GLuint i;
00524    ASSERT(rb->_ActualFormat == GL_RGB8);
00525    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00526    for (i = 0; i < count; i++) {
00527       if (!mask || mask[i]) {
00528          dst[i * 3 + 0] = src[i * 3 + 0];
00529          dst[i * 3 + 1] = src[i * 3 + 1];
00530          dst[i * 3 + 2] = src[i * 3 + 2];
00531       }
00532    }
00533 }
00534 
00535 
00536 static void
00537 put_mono_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00538                     GLint x, GLint y, const void *value, const GLubyte *mask)
00539 {
00540    /* note: incoming value is RGB+A! */
00541    const GLubyte val0 = ((const GLubyte *) value)[0];
00542    const GLubyte val1 = ((const GLubyte *) value)[1];
00543    const GLubyte val2 = ((const GLubyte *) value)[2];
00544    GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
00545    ASSERT(rb->_ActualFormat == GL_RGB8);
00546    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00547    if (!mask && val0 == val1 && val1 == val2) {
00548       /* optimized case */
00549       _mesa_memset(dst, val0, 3 * count);
00550    }
00551    else {
00552       GLuint i;
00553       for (i = 0; i < count; i++) {
00554          if (!mask || mask[i]) {
00555             dst[i * 3 + 0] = val0;
00556             dst[i * 3 + 1] = val1;
00557             dst[i * 3 + 2] = val2;
00558          }
00559       }
00560    }
00561 }
00562 
00563 
00564 static void
00565 put_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00566                   const GLint x[], const GLint y[], const void *values,
00567                   const GLubyte *mask)
00568 {
00569    /* note: incoming values are RGB+A! */
00570    const GLubyte *src = (const GLubyte *) values;
00571    GLuint i;
00572    ASSERT(rb->_ActualFormat == GL_RGB8);
00573    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00574    for (i = 0; i < count; i++) {
00575       if (!mask || mask[i]) {
00576          GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
00577          dst[0] = src[i * 4 + 0];
00578          dst[1] = src[i * 4 + 1];
00579          dst[2] = src[i * 4 + 2];
00580       }
00581    }
00582 }
00583 
00584 
00585 static void
00586 put_mono_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
00587                        GLuint count, const GLint x[], const GLint y[],
00588                        const void *value, const GLubyte *mask)
00589 {
00590    /* note: incoming value is RGB+A! */
00591    const GLubyte val0 = ((const GLubyte *) value)[0];
00592    const GLubyte val1 = ((const GLubyte *) value)[1];
00593    const GLubyte val2 = ((const GLubyte *) value)[2];
00594    GLuint i;
00595    ASSERT(rb->_ActualFormat == GL_RGB8);
00596    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00597    for (i = 0; i < count; i++) {
00598       if (!mask || mask[i]) {
00599          GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
00600          dst[0] = val0;
00601          dst[1] = val1;
00602          dst[2] = val2;
00603       }
00604    }
00605 }
00606 
00607 
00608 /**********************************************************************
00609  * Functions for buffers of 4 X GLubyte (or GLbyte) values.
00610  * Typically color buffers.
00611  */
00612 
00613 static void *
00614 get_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
00615                    GLint x, GLint y)
00616 {
00617    if (!rb->Data)
00618       return NULL;
00619    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00620    ASSERT(rb->_ActualFormat == GL_RGBA8);
00621    return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
00622 }
00623 
00624 
00625 static void
00626 get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00627                GLint x, GLint y, void *values)
00628 {
00629    const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x);
00630    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00631    ASSERT(rb->_ActualFormat == GL_RGBA8);
00632    _mesa_memcpy(values, src, 4 * count * sizeof(GLubyte));
00633 }
00634 
00635 
00636 static void
00637 get_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00638                   const GLint x[], const GLint y[], void *values)
00639 {
00640    /* treat 4*GLubyte as 1*GLuint */
00641    GLuint *dst = (GLuint *) values;
00642    GLuint i;
00643    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00644    ASSERT(rb->_ActualFormat == GL_RGBA8);
00645    for (i = 0; i < count; i++) {
00646       const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
00647       dst[i] = *src;
00648    }
00649 }
00650 
00651 
00652 static void
00653 put_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00654                GLint x, GLint y, const void *values, const GLubyte *mask)
00655 {
00656    /* treat 4*GLubyte as 1*GLuint */
00657    const GLuint *src = (const GLuint *) values;
00658    GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
00659    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00660    ASSERT(rb->_ActualFormat == GL_RGBA8);
00661    if (mask) {
00662       GLuint i;
00663       for (i = 0; i < count; i++) {
00664          if (mask[i]) {
00665             dst[i] = src[i];
00666          }
00667       }
00668    }
00669    else {
00670       _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte));
00671    }
00672 }
00673 
00674 
00675 static void
00676 put_row_rgb_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00677                    GLint x, GLint y, const void *values, const GLubyte *mask)
00678 {
00679    /* Store RGB values in RGBA buffer */
00680    const GLubyte *src = (const GLubyte *) values;
00681    GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
00682    GLuint i;
00683    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00684    ASSERT(rb->_ActualFormat == GL_RGBA8);
00685    for (i = 0; i < count; i++) {
00686       if (!mask || mask[i]) {
00687          dst[i * 4 + 0] = src[i * 3 + 0];
00688          dst[i * 4 + 1] = src[i * 3 + 1];
00689          dst[i * 4 + 2] = src[i * 3 + 2];
00690          dst[i * 4 + 3] = 0xff;
00691       }
00692    }
00693 }
00694 
00695 
00696 static void
00697 put_mono_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00698                     GLint x, GLint y, const void *value, const GLubyte *mask)
00699 {
00700    /* treat 4*GLubyte as 1*GLuint */
00701    const GLuint val = *((const GLuint *) value);
00702    GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
00703    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00704    ASSERT(rb->_ActualFormat == GL_RGBA8);
00705    if (!mask && val == 0) {
00706       /* common case */
00707       _mesa_bzero(dst, count * 4 * sizeof(GLubyte));
00708    }
00709    else {
00710       /* general case */
00711       if (mask) {
00712          GLuint i;
00713          for (i = 0; i < count; i++) {
00714             if (mask[i]) {
00715                dst[i] = val;
00716             }
00717          }
00718       }
00719       else {
00720          GLuint i;
00721          for (i = 0; i < count; i++) {
00722             dst[i] = val;
00723          }
00724       }
00725    }
00726 }
00727 
00728 
00729 static void
00730 put_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00731                   const GLint x[], const GLint y[], const void *values,
00732                   const GLubyte *mask)
00733 {
00734    /* treat 4*GLubyte as 1*GLuint */
00735    const GLuint *src = (const GLuint *) values;
00736    GLuint i;
00737    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00738    ASSERT(rb->_ActualFormat == GL_RGBA8);
00739    for (i = 0; i < count; i++) {
00740       if (!mask || mask[i]) {
00741          GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
00742          *dst = src[i];
00743       }
00744    }
00745 }
00746 
00747 
00748 static void
00749 put_mono_values_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb,
00750                        GLuint count, const GLint x[], const GLint y[],
00751                        const void *value, const GLubyte *mask)
00752 {
00753    /* treat 4*GLubyte as 1*GLuint */
00754    const GLuint val = *((const GLuint *) value);
00755    GLuint i;
00756    ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
00757    ASSERT(rb->_ActualFormat == GL_RGBA8);
00758    for (i = 0; i < count; i++) {
00759       if (!mask || mask[i]) {
00760          GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
00761          *dst = val;
00762       }
00763    }
00764 }
00765 
00766 
00767 /**********************************************************************
00768  * Functions for buffers of 4 X GLushort (or GLshort) values.
00769  * Typically accum buffer.
00770  */
00771 
00772 static void *
00773 get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
00774                     GLint x, GLint y)
00775 {
00776    if (!rb->Data)
00777       return NULL;
00778    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00779    return (GLushort *) rb->Data + 4 * (y * rb->Width + x);
00780 }
00781 
00782 
00783 static void
00784 get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00785                 GLint x, GLint y, void *values)
00786 {
00787    const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x);
00788    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00789    _mesa_memcpy(values, src, 4 * count * sizeof(GLshort));
00790 }
00791 
00792 
00793 static void
00794 get_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00795                    const GLint x[], const GLint y[], void *values)
00796 {
00797    GLushort *dst = (GLushort *) values;
00798    GLuint i;
00799    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00800    for (i = 0; i < count; i++) {
00801       const GLushort *src
00802          = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
00803       dst[i] = *src;
00804    }
00805 }
00806 
00807 
00808 static void
00809 put_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00810                 GLint x, GLint y, const void *values, const GLubyte *mask)
00811 {
00812    const GLushort *src = (const GLushort *) values;
00813    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
00814    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00815    if (mask) {
00816       GLuint i;
00817       for (i = 0; i < count; i++) {
00818          if (mask[i]) {
00819             dst[i * 4 + 0] = src[i * 4 + 0];
00820             dst[i * 4 + 1] = src[i * 4 + 1];
00821             dst[i * 4 + 2] = src[i * 4 + 2];
00822             dst[i * 4 + 3] = src[i * 4 + 3];
00823          }
00824       }
00825    }
00826    else {
00827       _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
00828    }
00829 }
00830 
00831 
00832 static void
00833 put_row_rgb_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00834                     GLint x, GLint y, const void *values, const GLubyte *mask)
00835 {
00836    /* Put RGB values in RGBA buffer */
00837    const GLushort *src = (const GLushort *) values;
00838    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
00839    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00840    if (mask) {
00841       GLuint i;
00842       for (i = 0; i < count; i++) {
00843          if (mask[i]) {
00844             dst[i * 4 + 0] = src[i * 3 + 0];
00845             dst[i * 4 + 1] = src[i * 3 + 1];
00846             dst[i * 4 + 2] = src[i * 3 + 2];
00847             dst[i * 4 + 3] = 0xffff;
00848          }
00849       }
00850    }
00851    else {
00852       _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort));
00853    }
00854 }
00855 
00856 
00857 static void
00858 put_mono_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00859                      GLint x, GLint y, const void *value, const GLubyte *mask)
00860 {
00861    const GLushort val0 = ((const GLushort *) value)[0];
00862    const GLushort val1 = ((const GLushort *) value)[1];
00863    const GLushort val2 = ((const GLushort *) value)[2];
00864    const GLushort val3 = ((const GLushort *) value)[3];
00865    GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->Width + x);
00866    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00867    if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) {
00868       /* common case for clearing accum buffer */
00869       _mesa_bzero(dst, count * 4 * sizeof(GLushort));
00870    }
00871    else {
00872       GLuint i;
00873       for (i = 0; i < count; i++) {
00874          if (!mask || mask[i]) {
00875             dst[i * 4 + 0] = val0;
00876             dst[i * 4 + 1] = val1;
00877             dst[i * 4 + 2] = val2;
00878             dst[i * 4 + 3] = val3;
00879          }
00880       }
00881    }
00882 }
00883 
00884 
00885 static void
00886 put_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
00887                    const GLint x[], const GLint y[], const void *values,
00888                    const GLubyte *mask)
00889 {
00890    const GLushort *src = (const GLushort *) values;
00891    GLuint i;
00892    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00893    for (i = 0; i < count; i++) {
00894       if (!mask || mask[i]) {
00895          GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
00896          dst[0] = src[i * 4 + 0];
00897          dst[1] = src[i * 4 + 1];
00898          dst[2] = src[i * 4 + 2];
00899          dst[3] = src[i * 4 + 3];
00900       }
00901    }
00902 }
00903 
00904 
00905 static void
00906 put_mono_values_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb,
00907                         GLuint count, const GLint x[], const GLint y[],
00908                         const void *value, const GLubyte *mask)
00909 {
00910    const GLushort val0 = ((const GLushort *) value)[0];
00911    const GLushort val1 = ((const GLushort *) value)[1];
00912    const GLushort val2 = ((const GLushort *) value)[2];
00913    const GLushort val3 = ((const GLushort *) value)[3];
00914    GLuint i;
00915    ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT);
00916    for (i = 0; i < count; i++) {
00917       if (!mask || mask[i]) {
00918          GLushort *dst = (GLushort *) rb->Data + 4 * (y[i] * rb->Width + x[i]);
00919          dst[0] = val0;
00920          dst[1] = val1;
00921          dst[2] = val2;
00922          dst[3] = val3;
00923       }
00924    }
00925 }
00926 
00927 
00928 
00943 GLboolean
00944 _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
00945                                 GLenum internalFormat,
00946                                 GLuint width, GLuint height)
00947 {
00948    GLuint pixelSize;
00949 
00950    /* first clear these fields */
00951    rb->RedBits =
00952    rb->GreenBits =
00953    rb->BlueBits =
00954    rb->AlphaBits =
00955    rb->IndexBits =
00956    rb->DepthBits =
00957    rb->StencilBits = 0;
00958 
00959    switch (internalFormat) {
00960    case GL_RGB:
00961    case GL_R3_G3_B2:
00962    case GL_RGB4:
00963    case GL_RGB5:
00964    case GL_RGB8:
00965    case GL_RGB10:
00966    case GL_RGB12:
00967    case GL_RGB16:
00968       rb->_ActualFormat = GL_RGB8;
00969       rb->_BaseFormat = GL_RGB;
00970       rb->DataType = GL_UNSIGNED_BYTE;
00971       rb->GetPointer = get_pointer_ubyte3;
00972       rb->GetRow = get_row_ubyte3;
00973       rb->GetValues = get_values_ubyte3;
00974       rb->PutRow = put_row_ubyte3;
00975       rb->PutRowRGB = put_row_rgb_ubyte3;
00976       rb->PutMonoRow = put_mono_row_ubyte3;
00977       rb->PutValues = put_values_ubyte3;
00978       rb->PutMonoValues = put_mono_values_ubyte3;
00979       rb->RedBits   = 8 * sizeof(GLubyte);
00980       rb->GreenBits = 8 * sizeof(GLubyte);
00981       rb->BlueBits  = 8 * sizeof(GLubyte);
00982       rb->AlphaBits = 0;
00983       pixelSize = 3 * sizeof(GLubyte);
00984       break;
00985    case GL_RGBA:
00986    case GL_RGBA2:
00987    case GL_RGBA4:
00988    case GL_RGB5_A1:
00989    case GL_RGBA8:
00990       rb->_ActualFormat = GL_RGBA8;
00991       rb->_BaseFormat = GL_RGBA;
00992       rb->DataType = GL_UNSIGNED_BYTE;
00993       rb->GetPointer = get_pointer_ubyte4;
00994       rb->GetRow = get_row_ubyte4;
00995       rb->GetValues = get_values_ubyte4;
00996       rb->PutRow = put_row_ubyte4;
00997       rb->PutRowRGB = put_row_rgb_ubyte4;
00998       rb->PutMonoRow = put_mono_row_ubyte4;
00999       rb->PutValues = put_values_ubyte4;
01000       rb->PutMonoValues = put_mono_values_ubyte4;
01001       rb->RedBits   = 8 * sizeof(GLubyte);
01002       rb->GreenBits = 8 * sizeof(GLubyte);
01003       rb->BlueBits  = 8 * sizeof(GLubyte);
01004       rb->AlphaBits = 8 * sizeof(GLubyte);
01005       pixelSize = 4 * sizeof(GLubyte);
01006       break;
01007    case GL_RGB10_A2:
01008    case GL_RGBA12:
01009    case GL_RGBA16:
01010       rb->_ActualFormat = GL_RGBA16;
01011       rb->_BaseFormat = GL_RGBA;
01012       rb->DataType = GL_UNSIGNED_SHORT;
01013       rb->GetPointer = get_pointer_ushort4;
01014       rb->GetRow = get_row_ushort4;
01015       rb->GetValues = get_values_ushort4;
01016       rb->PutRow = put_row_ushort4;
01017       rb->PutRowRGB = put_row_rgb_ushort4;
01018       rb->PutMonoRow = put_mono_row_ushort4;
01019       rb->PutValues = put_values_ushort4;
01020       rb->PutMonoValues = put_mono_values_ushort4;
01021       rb->RedBits   = 8 * sizeof(GLushort);
01022       rb->GreenBits = 8 * sizeof(GLushort);
01023       rb->BlueBits  = 8 * sizeof(GLushort);
01024       rb->AlphaBits = 8 * sizeof(GLushort);
01025       pixelSize = 4 * sizeof(GLushort);
01026       break;
01027 #if 00
01028    case GL_ALPHA8:
01029       rb->_ActualFormat = GL_ALPHA8;
01030       rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
01031       rb->DataType = GL_UNSIGNED_BYTE;
01032       rb->GetPointer = get_pointer_alpha8;
01033       rb->GetRow = get_row_alpha8;
01034       rb->GetValues = get_values_alpha8;
01035       rb->PutRow = put_row_alpha8;
01036       rb->PutRowRGB = NULL;
01037       rb->PutMonoRow = put_mono_row_alpha8;
01038       rb->PutValues = put_values_alpha8;
01039       rb->PutMonoValues = put_mono_values_alpha8;
01040       rb->RedBits   = 0; /*red*/
01041       rb->GreenBits = 0; /*green*/
01042       rb->BlueBits  = 0; /*blue*/
01043       rb->AlphaBits = 8 * sizeof(GLubyte);
01044       pixelSize = sizeof(GLubyte);
01045       break;
01046 #endif
01047    case GL_STENCIL_INDEX:
01048    case GL_STENCIL_INDEX1_EXT:
01049    case GL_STENCIL_INDEX4_EXT:
01050    case GL_STENCIL_INDEX8_EXT:
01051       rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
01052       rb->_BaseFormat = GL_STENCIL_INDEX;
01053       rb->DataType = GL_UNSIGNED_BYTE;
01054       rb->GetPointer = get_pointer_ubyte;
01055       rb->GetRow = get_row_ubyte;
01056       rb->GetValues = get_values_ubyte;
01057       rb->PutRow = put_row_ubyte;
01058       rb->PutRowRGB = NULL;
01059       rb->PutMonoRow = put_mono_row_ubyte;
01060       rb->PutValues = put_values_ubyte;
01061       rb->PutMonoValues = put_mono_values_ubyte;
01062       rb->StencilBits = 8 * sizeof(GLubyte);
01063       pixelSize = sizeof(GLubyte);
01064       break;
01065    case GL_STENCIL_INDEX16_EXT:
01066       rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
01067       rb->_BaseFormat = GL_STENCIL_INDEX;
01068       rb->DataType = GL_UNSIGNED_SHORT;
01069       rb->GetPointer = get_pointer_ushort;
01070       rb->GetRow = get_row_ushort;
01071       rb->GetValues = get_values_ushort;
01072       rb->PutRow = put_row_ushort;
01073       rb->PutRowRGB = NULL;
01074       rb->PutMonoRow = put_mono_row_ushort;
01075       rb->PutValues = put_values_ushort;
01076       rb->PutMonoValues = put_mono_values_ushort;
01077       rb->StencilBits = 8 * sizeof(GLushort);
01078       pixelSize = sizeof(GLushort);
01079       break;
01080    case GL_DEPTH_COMPONENT:
01081    case GL_DEPTH_COMPONENT16:
01082       rb->_ActualFormat = GL_DEPTH_COMPONENT16;
01083       rb->_BaseFormat = GL_DEPTH_COMPONENT;
01084       rb->DataType = GL_UNSIGNED_SHORT;
01085       rb->GetPointer = get_pointer_ushort;
01086       rb->GetRow = get_row_ushort;
01087       rb->GetValues = get_values_ushort;
01088       rb->PutRow = put_row_ushort;
01089       rb->PutRowRGB = NULL;
01090       rb->PutMonoRow = put_mono_row_ushort;
01091       rb->PutValues = put_values_ushort;
01092       rb->PutMonoValues = put_mono_values_ushort;
01093       rb->DepthBits = 8 * sizeof(GLushort);
01094       pixelSize = sizeof(GLushort);
01095       break;
01096    case GL_DEPTH_COMPONENT24:
01097    case GL_DEPTH_COMPONENT32:
01098       rb->_BaseFormat = GL_DEPTH_COMPONENT;
01099       rb->DataType = GL_UNSIGNED_INT;
01100       rb->GetPointer = get_pointer_uint;
01101       rb->GetRow = get_row_uint;
01102       rb->GetValues = get_values_uint;
01103       rb->PutRow = put_row_uint;
01104       rb->PutRowRGB = NULL;
01105       rb->PutMonoRow = put_mono_row_uint;
01106       rb->PutValues = put_values_uint;
01107       rb->PutMonoValues = put_mono_values_uint;
01108       if (internalFormat == GL_DEPTH_COMPONENT24) {
01109          rb->_ActualFormat = GL_DEPTH_COMPONENT24;
01110          rb->DepthBits = 24;
01111       }
01112       else {
01113          rb->_ActualFormat = GL_DEPTH_COMPONENT32;
01114          rb->DepthBits = 32;
01115       }
01116       pixelSize = sizeof(GLuint);
01117       break;
01118    case GL_DEPTH_STENCIL_EXT:
01119    case GL_DEPTH24_STENCIL8_EXT:
01120       rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
01121       rb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
01122       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
01123       rb->GetPointer = get_pointer_uint;
01124       rb->GetRow = get_row_uint;
01125       rb->GetValues = get_values_uint;
01126       rb->PutRow = put_row_uint;
01127       rb->PutRowRGB = NULL;
01128       rb->PutMonoRow = put_mono_row_uint;
01129       rb->PutValues = put_values_uint;
01130       rb->PutMonoValues = put_mono_values_uint;
01131       rb->DepthBits = 24;
01132       rb->StencilBits = 8;
01133       pixelSize = sizeof(GLuint);
01134       break;
01135    case GL_COLOR_INDEX8_EXT:
01136       rb->_ActualFormat = GL_COLOR_INDEX8_EXT;
01137       rb->_BaseFormat = GL_COLOR_INDEX;
01138       rb->DataType = GL_UNSIGNED_BYTE;
01139       rb->GetPointer = get_pointer_ubyte;
01140       rb->GetRow = get_row_ubyte;
01141       rb->GetValues = get_values_ubyte;
01142       rb->PutRow = put_row_ubyte;
01143       rb->PutRowRGB = NULL;
01144       rb->PutMonoRow = put_mono_row_ubyte;
01145       rb->PutValues = put_values_ubyte;
01146       rb->PutMonoValues = put_mono_values_ubyte;
01147       rb->IndexBits = 8 * sizeof(GLubyte);
01148       pixelSize = sizeof(GLubyte);
01149       break;
01150    case GL_COLOR_INDEX16_EXT:
01151       rb->_ActualFormat = GL_COLOR_INDEX16_EXT;
01152       rb->_BaseFormat = GL_COLOR_INDEX;
01153       rb->DataType = GL_UNSIGNED_SHORT;
01154       rb->GetPointer = get_pointer_ushort;
01155       rb->GetRow = get_row_ushort;
01156       rb->GetValues = get_values_ushort;
01157       rb->PutRow = put_row_ushort;
01158       rb->PutRowRGB = NULL;
01159       rb->PutMonoRow = put_mono_row_ushort;
01160       rb->PutValues = put_values_ushort;
01161       rb->PutMonoValues = put_mono_values_ushort;
01162       rb->IndexBits = 8 * sizeof(GLushort);
01163       pixelSize = sizeof(GLushort);
01164       break;
01165    case COLOR_INDEX32:
01166       rb->_ActualFormat = COLOR_INDEX32;
01167       rb->_BaseFormat = GL_COLOR_INDEX;
01168       rb->DataType = GL_UNSIGNED_INT;
01169       rb->GetPointer = get_pointer_uint;
01170       rb->GetRow = get_row_uint;
01171       rb->GetValues = get_values_uint;
01172       rb->PutRow = put_row_uint;
01173       rb->PutRowRGB = NULL;
01174       rb->PutMonoRow = put_mono_row_uint;
01175       rb->PutValues = put_values_uint;
01176       rb->PutMonoValues = put_mono_values_uint;
01177       rb->IndexBits = 8 * sizeof(GLuint);
01178       pixelSize = sizeof(GLuint);
01179       break;
01180    default:
01181       _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
01182       return GL_FALSE;
01183    }
01184 
01185    ASSERT(rb->DataType);
01186    ASSERT(rb->GetPointer);
01187    ASSERT(rb->GetRow);
01188    ASSERT(rb->GetValues);
01189    ASSERT(rb->PutRow);
01190    ASSERT(rb->PutMonoRow);
01191    ASSERT(rb->PutValues);
01192    ASSERT(rb->PutMonoValues);
01193 
01194    /* free old buffer storage */
01195    if (rb->Data) {
01196       _mesa_free(rb->Data);
01197       rb->Data = NULL;
01198    }
01199 
01200    if (width > 0 && height > 0) {
01201       /* allocate new buffer storage */
01202       rb->Data = _mesa_malloc(width * height * pixelSize);
01203       if (rb->Data == NULL) {
01204          rb->Width = 0;
01205          rb->Height = 0;
01206          _mesa_error(ctx, GL_OUT_OF_MEMORY,
01207                      "software renderbuffer allocation (%d x %d x %d)",
01208                      width, height, pixelSize);
01209          return GL_FALSE;
01210       }
01211    }
01212 
01213    rb->Width = width;
01214    rb->Height = height;
01215 
01216    return GL_TRUE;
01217 }
01218 
01219 
01220 
01221 /**********************************************************************/
01222 /**********************************************************************/
01223 /**********************************************************************/
01224 
01225 
01236 static GLboolean
01237 alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
01238                      GLenum internalFormat, GLuint width, GLuint height)
01239 {
01240    ASSERT(arb != arb->Wrapped);
01241    ASSERT(arb->_ActualFormat == GL_ALPHA8);
01242 
01243    /* first, pass the call to the wrapped RGB buffer */
01244    if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
01245                                   width, height)) {
01246       return GL_FALSE;
01247    }
01248 
01249    /* next, resize my alpha buffer */
01250    if (arb->Data) {
01251       _mesa_free(arb->Data);
01252    }
01253 
01254    arb->Data = _mesa_malloc(width * height * sizeof(GLubyte));
01255    if (arb->Data == NULL) {
01256       arb->Width = 0;
01257       arb->Height = 0;
01258       _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
01259       return GL_FALSE;
01260    }
01261 
01262    arb->Width = width;
01263    arb->Height = height;
01264 
01265    return GL_TRUE;
01266 }
01267 
01268 
01272 static void
01273 delete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
01274 {
01275    if (arb->Data) {
01276       _mesa_free(arb->Data);
01277    }
01278    ASSERT(arb->Wrapped);
01279    ASSERT(arb != arb->Wrapped);
01280    arb->Wrapped->Delete(arb->Wrapped);
01281    arb->Wrapped = NULL;
01282    _mesa_free(arb);
01283 }
01284 
01285 
01286 static void *
01287 get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
01288                    GLint x, GLint y)
01289 {
01290    return NULL;   /* don't allow direct access! */
01291 }
01292 
01293 
01294 static void
01295 get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01296                GLint x, GLint y, void *values)
01297 {
01298    /* NOTE: 'values' is RGBA format! */
01299    const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x;
01300    GLubyte *dst = (GLubyte *) values;
01301    GLuint i;
01302    ASSERT(arb != arb->Wrapped);
01303    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01304    /* first, pass the call to the wrapped RGB buffer */
01305    arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
01306    /* second, fill in alpha values from this buffer! */
01307    for (i = 0; i < count; i++) {
01308       dst[i * 4 + 3] = src[i];
01309    }
01310 }
01311 
01312 
01313 static void
01314 get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01315                   const GLint x[], const GLint y[], void *values)
01316 {
01317    GLubyte *dst = (GLubyte *) values;
01318    GLuint i;
01319    ASSERT(arb != arb->Wrapped);
01320    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01321    /* first, pass the call to the wrapped RGB buffer */
01322    arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
01323    /* second, fill in alpha values from this buffer! */
01324    for (i = 0; i < count; i++) {
01325       const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
01326       dst[i * 4 + 3] = *src;
01327    }
01328 }
01329 
01330 
01331 static void
01332 put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01333                GLint x, GLint y, const void *values, const GLubyte *mask)
01334 {
01335    const GLubyte *src = (const GLubyte *) values;
01336    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
01337    GLuint i;
01338    ASSERT(arb != arb->Wrapped);
01339    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01340    /* first, pass the call to the wrapped RGB buffer */
01341    arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
01342    /* second, store alpha in our buffer */
01343    for (i = 0; i < count; i++) {
01344       if (!mask || mask[i]) {
01345          dst[i] = src[i * 4 + 3];
01346       }
01347    }
01348 }
01349 
01350 
01351 static void
01352 put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01353                    GLint x, GLint y, const void *values, const GLubyte *mask)
01354 {
01355    const GLubyte *src = (const GLubyte *) values;
01356    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
01357    GLuint i;
01358    ASSERT(arb != arb->Wrapped);
01359    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01360    /* first, pass the call to the wrapped RGB buffer */
01361    arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
01362    /* second, store alpha in our buffer */
01363    for (i = 0; i < count; i++) {
01364       if (!mask || mask[i]) {
01365          dst[i] = src[i * 4 + 3];
01366       }
01367    }
01368 }
01369 
01370 
01371 static void
01372 put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01373                     GLint x, GLint y, const void *value, const GLubyte *mask)
01374 {
01375    const GLubyte val = ((const GLubyte *) value)[3];
01376    GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
01377    ASSERT(arb != arb->Wrapped);
01378    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01379    /* first, pass the call to the wrapped RGB buffer */
01380    arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
01381    /* second, store alpha in our buffer */
01382    if (mask) {
01383       GLuint i;
01384       for (i = 0; i < count; i++) {
01385          if (mask[i]) {
01386             dst[i] = val;
01387          }
01388       }
01389    }
01390    else {
01391       _mesa_memset(dst, val, count);
01392    }
01393 }
01394 
01395 
01396 static void
01397 put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
01398                   const GLint x[], const GLint y[],
01399                   const void *values, const GLubyte *mask)
01400 {
01401    const GLubyte *src = (const GLubyte *) values;
01402    GLuint i;
01403    ASSERT(arb != arb->Wrapped);
01404    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01405    /* first, pass the call to the wrapped RGB buffer */
01406    arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
01407    /* second, store alpha in our buffer */
01408    for (i = 0; i < count; i++) {
01409       if (!mask || mask[i]) {
01410          GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
01411          *dst = src[i * 4 + 3];
01412       }
01413    }
01414 }
01415 
01416 
01417 static void
01418 put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
01419                        GLuint count, const GLint x[], const GLint y[],
01420                        const void *value, const GLubyte *mask)
01421 {
01422    const GLubyte val = ((const GLubyte *) value)[3];
01423    GLuint i;
01424    ASSERT(arb != arb->Wrapped);
01425    ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
01426    /* first, pass the call to the wrapped RGB buffer */
01427    arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
01428    /* second, store alpha in our buffer */
01429    for (i = 0; i < count; i++) {
01430       if (!mask || mask[i]) {
01431          GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
01432          *dst = val;
01433       }
01434    }
01435 }
01436 
01437 
01438 static void
01439 copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
01440 {
01441    ASSERT(dst->_ActualFormat == GL_ALPHA8);
01442    ASSERT(src->_ActualFormat == GL_ALPHA8);
01443    ASSERT(dst->Width == src->Width);
01444    ASSERT(dst->Height == src->Height);
01445 
01446    _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
01447 }
01448 
01449 
01450 /**********************************************************************/
01451 /**********************************************************************/
01452 /**********************************************************************/
01453 
01454 
01459 static void *
01460 nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
01461 {
01462    return NULL;
01463 }
01464 
01465 
01469 void
01470 _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
01471 {
01472    _glthread_INIT_MUTEX(rb->Mutex);
01473 
01474    rb->Magic = RB_MAGIC;
01475    rb->ClassID = 0;
01476    rb->Name = name;
01477    rb->RefCount = 0;
01478    rb->Delete = _mesa_delete_renderbuffer;
01479 
01480    /* The rest of these should be set later by the caller of this function or
01481     * the AllocStorage method:
01482     */
01483    rb->AllocStorage = NULL;
01484 
01485    rb->Width = 0;
01486    rb->Height = 0;
01487    rb->InternalFormat = GL_NONE;
01488    rb->_ActualFormat = GL_NONE;
01489    rb->_BaseFormat = GL_NONE;
01490    rb->DataType = GL_NONE;
01491    rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
01492    rb->IndexBits = 0;
01493    rb->DepthBits = 0;
01494    rb->StencilBits = 0;
01495    rb->Data = NULL;
01496 
01497    /* Point back to ourself so that we don't have to check for Wrapped==NULL
01498     * all over the drivers.
01499     */
01500    rb->Wrapped = rb;
01501 
01502    rb->GetPointer = nop_get_pointer;
01503    rb->GetRow = NULL;
01504    rb->GetValues = NULL;
01505    rb->PutRow = NULL;
01506    rb->PutRowRGB = NULL;
01507    rb->PutMonoRow = NULL;
01508    rb->PutValues = NULL;
01509    rb->PutMonoValues = NULL;
01510 }
01511 
01512 
01517 struct gl_renderbuffer *
01518 _mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
01519 {
01520    struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
01521    if (rb) {
01522       _mesa_init_renderbuffer(rb, name);
01523    }
01524    return rb;
01525 }
01526 
01527 
01532 void
01533 _mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
01534 {
01535    if (rb->Data) {
01536       _mesa_free(rb->Data);
01537    }
01538    _mesa_free(rb);
01539 }
01540 
01541 
01548 struct gl_renderbuffer *
01549 _mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
01550 {
01551    struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
01552    if (rb) {
01553       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01554       /* Normally, one would setup the PutRow, GetRow, etc functions here.
01555        * But we're doing that in the _mesa_soft_renderbuffer_storage() function
01556        * instead.
01557        */
01558    }
01559    return rb;
01560 }
01561 
01562 
01571 GLboolean
01572 _mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
01573                               GLuint rgbBits, GLuint alphaBits,
01574                               GLboolean frontLeft, GLboolean backLeft,
01575                               GLboolean frontRight, GLboolean backRight)
01576 {
01577    GLuint b;
01578 
01579    if (rgbBits > 16 || alphaBits > 16) {
01580       _mesa_problem(ctx,
01581                     "Unsupported bit depth in _mesa_add_color_renderbuffers");
01582       return GL_FALSE;
01583    }
01584 
01585    assert(MAX_COLOR_ATTACHMENTS >= 4);
01586 
01587    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
01588       struct gl_renderbuffer *rb;
01589 
01590       if (b == BUFFER_FRONT_LEFT && !frontLeft)
01591          continue;
01592       else if (b == BUFFER_BACK_LEFT && !backLeft)
01593          continue;
01594       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
01595          continue;
01596       else if (b == BUFFER_BACK_RIGHT && !backRight)
01597          continue;
01598 
01599       assert(fb->Attachment[b].Renderbuffer == NULL);
01600 
01601       rb = _mesa_new_renderbuffer(ctx, 0);
01602       if (!rb) {
01603          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
01604          return GL_FALSE;
01605       }
01606 
01607       if (rgbBits <= 8) {
01608          if (alphaBits)
01609             rb->_ActualFormat = GL_RGBA8;
01610          else
01611             rb->_ActualFormat = GL_RGB8;
01612       }
01613       else {
01614          assert(rgbBits <= 16);
01615          if (alphaBits)
01616             rb->_ActualFormat = GL_RGBA16;
01617          else
01618             rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */
01619       }
01620       rb->InternalFormat = rb->_ActualFormat;
01621 
01622       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01623       _mesa_add_renderbuffer(fb, b, rb);
01624    }
01625 
01626    return GL_TRUE;
01627 }
01628 
01629 
01638 GLboolean
01639 _mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
01640                                     GLuint indexBits,
01641                                     GLboolean frontLeft, GLboolean backLeft,
01642                                     GLboolean frontRight, GLboolean backRight)
01643 {
01644    GLuint b;
01645 
01646    if (indexBits > 8) {
01647       _mesa_problem(ctx,
01648                 "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
01649       return GL_FALSE;
01650    }
01651 
01652    assert(MAX_COLOR_ATTACHMENTS >= 4);
01653 
01654    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
01655       struct gl_renderbuffer *rb;
01656 
01657       if (b == BUFFER_FRONT_LEFT && !frontLeft)
01658          continue;
01659       else if (b == BUFFER_BACK_LEFT && !backLeft)
01660          continue;
01661       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
01662          continue;
01663       else if (b == BUFFER_BACK_RIGHT && !backRight)
01664          continue;
01665 
01666       assert(fb->Attachment[b].Renderbuffer == NULL);
01667 
01668       rb = _mesa_new_renderbuffer(ctx, 0);
01669       if (!rb) {
01670          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
01671          return GL_FALSE;
01672       }
01673 
01674       if (indexBits <= 8) {
01675          /* only support GLuint for now */
01676          /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
01677          rb->_ActualFormat = COLOR_INDEX32;
01678       }
01679       else {
01680          rb->_ActualFormat = COLOR_INDEX32;
01681       }
01682       rb->InternalFormat = rb->_ActualFormat;
01683 
01684       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01685       _mesa_add_renderbuffer(fb, b, rb);
01686    }
01687 
01688    return GL_TRUE;
01689 }
01690 
01691 
01700 GLboolean
01701 _mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
01702                               GLuint alphaBits,
01703                               GLboolean frontLeft, GLboolean backLeft,
01704                               GLboolean frontRight, GLboolean backRight)
01705 {
01706    GLuint b;
01707 
01708    /* for window system framebuffers only! */
01709    assert(fb->Name == 0);
01710 
01711    if (alphaBits > 8) {
01712       _mesa_problem(ctx,
01713                     "Unsupported bit depth in _mesa_add_alpha_renderbuffers");
01714       return GL_FALSE;
01715    }
01716 
01717    assert(MAX_COLOR_ATTACHMENTS >= 4);
01718 
01719    /* Wrap each of the RGB color buffers with an alpha renderbuffer.
01720     */
01721    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
01722       struct gl_renderbuffer *arb;
01723 
01724       if (b == BUFFER_FRONT_LEFT && !frontLeft)
01725          continue;
01726       else if (b == BUFFER_BACK_LEFT && !backLeft)
01727          continue;
01728       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
01729          continue;
01730       else if (b == BUFFER_BACK_RIGHT && !backRight)
01731          continue;
01732 
01733       /* the RGB buffer to wrap must already exist!! */
01734       assert(fb->Attachment[b].Renderbuffer);
01735 
01736       /* only GLubyte supported for now */
01737       assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
01738 
01739       /* allocate alpha renderbuffer */
01740       arb = _mesa_new_renderbuffer(ctx, 0);
01741       if (!arb) {
01742          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
01743          return GL_FALSE;
01744       }
01745 
01746       /* wrap the alpha renderbuffer around the RGB renderbuffer */
01747       arb->Wrapped = fb->Attachment[b].Renderbuffer;
01748 
01749       /* Set up my alphabuffer fields and plug in my functions.
01750        * The functions will put/get the alpha values from/to RGBA arrays
01751        * and then call the wrapped buffer's functions to handle the RGB
01752        * values.
01753        */
01754       arb->InternalFormat = arb->Wrapped->InternalFormat;
01755       arb->_ActualFormat  = GL_ALPHA8;
01756       arb->_BaseFormat    = arb->Wrapped->_BaseFormat;
01757       arb->DataType       = arb->Wrapped->DataType;
01758       arb->AllocStorage   = alloc_storage_alpha8;
01759       arb->Delete         = delete_renderbuffer_alpha8;
01760       arb->GetPointer     = get_pointer_alpha8;
01761       arb->GetRow         = get_row_alpha8;
01762       arb->GetValues      = get_values_alpha8;
01763       arb->PutRow         = put_row_alpha8;
01764       arb->PutRowRGB      = put_row_rgb_alpha8;
01765       arb->PutMonoRow     = put_mono_row_alpha8;
01766       arb->PutValues      = put_values_alpha8;
01767       arb->PutMonoValues  = put_mono_values_alpha8;
01768 
01769       /* clear the pointer to avoid assertion/sanity check failure later */
01770       fb->Attachment[b].Renderbuffer = NULL;
01771 
01772       /* plug the alpha renderbuffer into the colorbuffer attachment */
01773       _mesa_add_renderbuffer(fb, b, arb);
01774    }
01775 
01776    return GL_TRUE;
01777 }
01778 
01779 
01785 void
01786 _mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
01787 {
01788    if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
01789        fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
01790       copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
01791                          fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
01792 
01793 
01794    if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
01795        fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
01796       copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
01797                          fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
01798 }
01799 
01800 
01809 GLboolean
01810 _mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
01811                              GLuint depthBits)
01812 {
01813    struct gl_renderbuffer *rb;
01814 
01815    if (depthBits > 32) {
01816       _mesa_problem(ctx,
01817                     "Unsupported depthBits in _mesa_add_depth_renderbuffer");
01818       return GL_FALSE;
01819    }
01820 
01821    assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
01822 
01823    rb = _mesa_new_renderbuffer(ctx, 0);
01824    if (!rb) {
01825       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
01826       return GL_FALSE;
01827    }
01828 
01829    if (depthBits <= 16) {
01830       rb->_ActualFormat = GL_DEPTH_COMPONENT16;
01831    }
01832    else if (depthBits <= 24) {
01833       rb->_ActualFormat = GL_DEPTH_COMPONENT24;
01834    }
01835    else {
01836       rb->_ActualFormat = GL_DEPTH_COMPONENT32;
01837    }
01838    rb->InternalFormat = rb->_ActualFormat;
01839 
01840    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01841    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
01842 
01843    return GL_TRUE;
01844 }
01845 
01846 
01855 GLboolean
01856 _mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
01857                                GLuint stencilBits)
01858 {
01859    struct gl_renderbuffer *rb;
01860 
01861    if (stencilBits > 16) {
01862       _mesa_problem(ctx,
01863                   "Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
01864       return GL_FALSE;
01865    }
01866 
01867    assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
01868 
01869    rb = _mesa_new_renderbuffer(ctx, 0);
01870    if (!rb) {
01871       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
01872       return GL_FALSE;
01873    }
01874 
01875    if (stencilBits <= 8) {
01876       rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
01877    }
01878    else {
01879       /* not really supported (see s_stencil.c code) */
01880       rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
01881    }
01882    rb->InternalFormat = rb->_ActualFormat;
01883 
01884    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01885    _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
01886 
01887    return GL_TRUE;
01888 }
01889 
01890 
01899 GLboolean
01900 _mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
01901                              GLuint redBits, GLuint greenBits,
01902                              GLuint blueBits, GLuint alphaBits)
01903 {
01904    struct gl_renderbuffer *rb;
01905 
01906    if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
01907       _mesa_problem(ctx,
01908                     "Unsupported accumBits in _mesa_add_accum_renderbuffer");
01909       return GL_FALSE;
01910    }
01911 
01912    assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
01913 
01914    rb = _mesa_new_renderbuffer(ctx, 0);
01915    if (!rb) {
01916       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
01917       return GL_FALSE;
01918    }
01919 
01920    rb->_ActualFormat = GL_RGBA16;
01921    rb->InternalFormat = GL_RGBA16;
01922    rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01923    _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
01924 
01925    return GL_TRUE;
01926 }
01927 
01928 
01929 
01940 GLboolean
01941 _mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
01942                             GLuint colorBits, GLuint numBuffers)
01943 {
01944    GLuint i;
01945 
01946    if (colorBits > 16) {
01947       _mesa_problem(ctx,
01948                     "Unsupported accumBits in _mesa_add_aux_renderbuffers");
01949       return GL_FALSE;
01950    }
01951 
01952    assert(numBuffers < MAX_AUX_BUFFERS);
01953 
01954    for (i = 0; i < numBuffers; i++) {
01955       struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
01956 
01957       assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
01958 
01959       if (!rb) {
01960          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
01961          return GL_FALSE;
01962       }
01963 
01964       if (colorBits <= 8) {
01965          rb->_ActualFormat = GL_RGBA8;
01966       }
01967       else {
01968          rb->_ActualFormat = GL_RGBA16;
01969       }
01970       rb->InternalFormat = rb->_ActualFormat;
01971 
01972       rb->AllocStorage = _mesa_soft_renderbuffer_storage;
01973       _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
01974    }
01975    return GL_TRUE;
01976 }
01977 
01978 
01984 void
01985 _mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
01986                              GLboolean color,
01987                              GLboolean depth,
01988                              GLboolean stencil,
01989                              GLboolean accum,
01990                              GLboolean alpha,
01991                              GLboolean aux)
01992 {
01993    GLboolean frontLeft = GL_TRUE;
01994    GLboolean backLeft = fb->Visual.doubleBufferMode;
01995    GLboolean frontRight = fb->Visual.stereoMode;
01996    GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
01997 
01998    if (color) {
01999       if (fb->Visual.rgbMode) {
02000          assert(fb->Visual.redBits == fb->Visual.greenBits);
02001          assert(fb->Visual.redBits == fb->Visual.blueBits);
02002          _mesa_add_color_renderbuffers(NULL, fb,
02003                                        fb->Visual.redBits,
02004                                        fb->Visual.alphaBits,
02005                                        frontLeft, backLeft,
02006                                        frontRight, backRight);
02007       }
02008       else {
02009          _mesa_add_color_index_renderbuffers(NULL, fb,
02010                                              fb->Visual.indexBits,
02011                                              frontLeft, backLeft,
02012                                              frontRight, backRight);
02013       }
02014    }
02015 
02016    if (depth) {
02017       assert(fb->Visual.depthBits > 0);
02018       _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
02019    }
02020 
02021    if (stencil) {
02022       assert(fb->Visual.stencilBits > 0);
02023       _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
02024    }
02025 
02026    if (accum) {
02027       assert(fb->Visual.rgbMode);
02028       assert(fb->Visual.accumRedBits > 0);
02029       assert(fb->Visual.accumGreenBits > 0);
02030       assert(fb->Visual.accumBlueBits > 0);
02031       _mesa_add_accum_renderbuffer(NULL, fb,
02032                                    fb->Visual.accumRedBits,
02033                                    fb->Visual.accumGreenBits,
02034                                    fb->Visual.accumBlueBits,
02035                                    fb->Visual.accumAlphaBits);
02036    }
02037 
02038    if (aux) {
02039       assert(fb->Visual.rgbMode);
02040       assert(fb->Visual.numAuxBuffers > 0);
02041       _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
02042                                   fb->Visual.numAuxBuffers);
02043    }
02044 
02045    if (alpha) {
02046       assert(fb->Visual.rgbMode);
02047       assert(fb->Visual.alphaBits > 0);
02048       _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
02049                                     frontLeft, backLeft,
02050                                     frontRight, backRight);
02051    }
02052 
02053 #if 0
02054    if (multisample) {
02055       /* maybe someday */
02056    }
02057 #endif
02058 }
02059 
02060 
02064 void
02065 _mesa_add_renderbuffer(struct gl_framebuffer *fb,
02066                        GLuint bufferName, struct gl_renderbuffer *rb)
02067 {
02068    assert(fb);
02069    assert(rb);
02070    assert(bufferName < BUFFER_COUNT);
02071 
02072    /* There should be no previous renderbuffer on this attachment point,
02073     * with the exception of depth/stencil since the same renderbuffer may
02074     * be used for both.
02075     */
02076    assert(bufferName == BUFFER_DEPTH ||
02077           bufferName == BUFFER_STENCIL ||
02078           fb->Attachment[bufferName].Renderbuffer == NULL);
02079 
02080    /* winsys vs. user-created buffer cross check */
02081    if (fb->Name) {
02082       assert(rb->Name);
02083    }
02084    else {
02085       assert(!rb->Name);
02086    }
02087 
02088    /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
02089     * and the device driver is expecting 8-bit values (GLubyte), we can
02090     * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
02091     */
02092    if (rb->_BaseFormat == GL_RGBA) {
02093       if (CHAN_BITS == 16 && rb->DataType == GL_UNSIGNED_BYTE) {
02094          GET_CURRENT_CONTEXT(ctx);
02095          rb = _mesa_new_renderbuffer_16wrap8(ctx, rb);
02096       }
02097       else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_BYTE) {
02098          GET_CURRENT_CONTEXT(ctx);
02099          rb = _mesa_new_renderbuffer_32wrap8(ctx, rb);
02100       }
02101       else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_SHORT) {
02102          GET_CURRENT_CONTEXT(ctx);
02103          rb = _mesa_new_renderbuffer_32wrap16(ctx, rb);
02104       }
02105    }
02106 
02107    fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
02108    fb->Attachment[bufferName].Complete = GL_TRUE;
02109    _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
02110 }
02111 
02112 
02116 void
02117 _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
02118 {
02119    struct gl_renderbuffer *rb;
02120 
02121    assert(bufferName < BUFFER_COUNT);
02122 
02123    rb = fb->Attachment[bufferName].Renderbuffer;
02124    if (!rb)
02125       return;
02126 
02127    _mesa_reference_renderbuffer(&rb, NULL);
02128 
02129    fb->Attachment[bufferName].Renderbuffer = NULL;
02130 }
02131 
02132 
02138 void
02139 _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
02140                              struct gl_renderbuffer *rb)
02141 {
02142    assert(ptr);
02143    if (*ptr == rb) {
02144       /* no change */
02145       return;
02146    }
02147 
02148    if (*ptr) {
02149       /* Unreference the old renderbuffer */
02150       GLboolean deleteFlag = GL_FALSE;
02151       struct gl_renderbuffer *oldRb = *ptr;
02152 
02153       assert(oldRb->Magic == RB_MAGIC);
02154       _glthread_LOCK_MUTEX(oldRb->Mutex);
02155       assert(oldRb->Magic == RB_MAGIC);
02156       ASSERT(oldRb->RefCount > 0);
02157       oldRb->RefCount--;
02158       /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
02159       deleteFlag = (oldRb->RefCount == 0);
02160       _glthread_UNLOCK_MUTEX(oldRb->Mutex);
02161 
02162       if (deleteFlag) {
02163          oldRb->Magic = 0; /* now invalid memory! */
02164          oldRb->Delete(oldRb);
02165       }
02166 
02167       *ptr = NULL;
02168    }
02169    assert(!*ptr);
02170 
02171    if (rb) {
02172       assert(rb->Magic == RB_MAGIC);
02173       /* reference new renderbuffer */
02174       _glthread_LOCK_MUTEX(rb->Mutex);
02175       rb->RefCount++;
02176       /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
02177       _glthread_UNLOCK_MUTEX(rb->Mutex);
02178       *ptr = rb;
02179    }
02180 }
02181 
02182 
02188 struct gl_renderbuffer *
02189 _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
02190 {
02191    struct gl_renderbuffer *dsrb;
02192 
02193    dsrb = _mesa_new_renderbuffer(ctx, name);
02194    if (!dsrb)
02195       return NULL;
02196 
02197    /* init fields not covered by _mesa_new_renderbuffer() */
02198    dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
02199    dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
02200    dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
02201 
02202    return dsrb;
02203 }

Generated on Fri May 25 2012 04:18:33 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.