Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrenderbuffer.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
1.7.6.1
|