renderbuffer.c revision 76d1275474d7b5ac2f0edf5856ae1c5fc234f0d9
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * Functions for allocating/managing renderbuffers. 28 * Also, routines for reading/writing software-based renderbuffer data as 29 * ubytes, ushorts, uints, etc. 30 * 31 * The 'alpha8' renderbuffer is interesting. It's used to add a software-based 32 * alpha channel to RGB renderbuffers. This is done by wrapping the RGB 33 * renderbuffer with the alpha renderbuffer. We can do this because of the 34 * OO-nature of renderbuffers. 35 * 36 * Down the road we'll use this for run-time support of 8, 16 and 32-bit 37 * color channels. For example, Mesa may use 32-bit/float color channels 38 * internally (swrast) and use wrapper renderbuffers to convert 32-bit 39 * values down to 16 or 8-bit values for whatever kind of framebuffer we have. 40 */ 41 42 43#include "glheader.h" 44#include "imports.h" 45#include "context.h" 46#include "fbobject.h" 47#include "formats.h" 48#include "mtypes.h" 49#include "renderbuffer.h" 50 51 52/* 53 * Routines for get/put values in common buffer formats follow. 54 */ 55 56/* Returns a bytes per pixel of the DataType in the get/put span 57 * functions for at least a subset of the available combinations a 58 * renderbuffer can have. 59 * 60 * It would be nice to see gl_renderbuffer start talking about a 61 * gl_format instead of a GLenum DataType. 62 */ 63static int 64get_datatype_bytes(struct gl_renderbuffer *rb) 65{ 66 int component_size; 67 68 switch (rb->DataType) { 69 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 70 component_size = 8; 71 break; 72 case GL_FLOAT: 73 case GL_UNSIGNED_INT: 74 case GL_UNSIGNED_INT_24_8_EXT: 75 component_size = 4; 76 break; 77 case GL_UNSIGNED_SHORT: 78 component_size = 2; 79 break; 80 case GL_UNSIGNED_BYTE: 81 component_size = 1; 82 break; 83 default: 84 component_size = 1; 85 assert(0); 86 } 87 88 switch (rb->_BaseFormat) { 89 case GL_DEPTH_COMPONENT: 90 case GL_DEPTH_STENCIL: 91 return component_size; 92 default: 93 return 4 * component_size; 94 } 95} 96 97/* This is commonly used by most of the accessors. */ 98static void * 99get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 100 GLint x, GLint y) 101{ 102 if (!rb->Data) 103 return NULL; 104 105 return ((char *) rb->Data + 106 (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format)); 107} 108 109/* GetRow() implementation for formats where DataType matches the rb->Format. 110 */ 111static void 112get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 113 GLuint count, GLint x, GLint y, void *values) 114{ 115 void *src = rb->GetPointer(ctx, rb, x, y); 116 memcpy(values, src, count * _mesa_get_format_bytes(rb->Format)); 117} 118 119/* Only used for float textures currently, but might also be used for 120 * RGBA8888, RGBA16, etc. 121 */ 122static void 123get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 124 GLuint count, const GLint x[], const GLint y[], void *values) 125{ 126 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 127 GLuint i; 128 129 for (i = 0; i < count; i++) { 130 const void *src = rb->GetPointer(ctx, rb, x[i], y[i]); 131 char *dst = (char *) values + i * format_bytes; 132 memcpy(dst, src, format_bytes); 133 } 134} 135 136/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and 137 * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of 138 * storing those initial components of the value per pixel into the 139 * destination. 140 */ 141static void 142put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 143 GLuint count, GLint x, GLint y, 144 const void *values, const GLubyte *mask) 145{ 146 void *row = rb->GetPointer(ctx, rb, x, y); 147 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 148 int datatype_bytes = get_datatype_bytes(rb); 149 unsigned int i; 150 151 if (mask) { 152 for (i = 0; i < count; i++) { 153 char *dst = (char *) row + i * format_bytes; 154 const char *src = (const char *) values + i * datatype_bytes; 155 156 if (mask[i]) { 157 memcpy(dst, src, format_bytes); 158 } 159 } 160 } 161 else { 162 for (i = 0; i < count; i++) { 163 char *dst = (char *) row + i * format_bytes; 164 const char *src = (const char *) values + i * datatype_bytes; 165 memcpy(dst, src, format_bytes); 166 } 167 } 168} 169 170static void 171put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 172 GLuint count, GLint x, GLint y, 173 const void *value, const GLubyte *mask) 174{ 175 void *row = rb->GetPointer(ctx, rb, x, y); 176 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 177 unsigned int i; 178 179 if (mask) { 180 for (i = 0; i < count; i++) { 181 char *dst = (char *) row + i * format_bytes; 182 if (mask[i]) { 183 memcpy(dst, value, format_bytes); 184 } 185 } 186 } 187 else { 188 for (i = 0; i < count; i++) { 189 char *dst = (char *) row + i * format_bytes; 190 memcpy(dst, value, format_bytes); 191 } 192 } 193} 194 195 196static void 197put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, 198 GLuint count, const GLint x[], const GLint y[], 199 const void *values, const GLubyte *mask) 200{ 201 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 202 int datatype_bytes = get_datatype_bytes(rb); 203 unsigned int i; 204 205 for (i = 0; i < count; i++) { 206 if (!mask || mask[i]) { 207 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 208 const char *src = (const char *) values + i * datatype_bytes; 209 memcpy(dst, src, format_bytes); 210 } 211 } 212} 213 214 215static void 216put_mono_values_generic(struct gl_context *ctx, 217 struct gl_renderbuffer *rb, 218 GLuint count, const GLint x[], const GLint y[], 219 const void *value, const GLubyte *mask) 220{ 221 int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); 222 unsigned int i; 223 224 for (i = 0; i < count; i++) { 225 if (!mask || mask[i]) { 226 void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 227 memcpy(dst, value, format_bytes); 228 } 229 } 230} 231 232/********************************************************************** 233 * Functions for buffers of 1 X GLubyte values. 234 * Typically stencil. 235 */ 236 237static void 238get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 239 const GLint x[], const GLint y[], void *values) 240{ 241 GLubyte *dst = (GLubyte *) values; 242 GLuint i; 243 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 244 for (i = 0; i < count; i++) { 245 const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 246 dst[i] = *src; 247 } 248} 249 250 251static void 252put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 253 GLint x, GLint y, const void *values, const GLubyte *mask) 254{ 255 const GLubyte *src = (const GLubyte *) values; 256 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 257 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 258 if (mask) { 259 GLuint i; 260 for (i = 0; i < count; i++) { 261 if (mask[i]) { 262 dst[i] = src[i]; 263 } 264 } 265 } 266 else { 267 memcpy(dst, values, count * sizeof(GLubyte)); 268 } 269} 270 271 272static void 273put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 274 GLint x, GLint y, const void *value, const GLubyte *mask) 275{ 276 const GLubyte val = *((const GLubyte *) value); 277 GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; 278 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 279 if (mask) { 280 GLuint i; 281 for (i = 0; i < count; i++) { 282 if (mask[i]) { 283 dst[i] = val; 284 } 285 } 286 } 287 else { 288 GLuint i; 289 for (i = 0; i < count; i++) { 290 dst[i] = val; 291 } 292 } 293} 294 295 296static void 297put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 298 const GLint x[], const GLint y[], 299 const void *values, const GLubyte *mask) 300{ 301 const GLubyte *src = (const GLubyte *) values; 302 GLuint i; 303 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 304 for (i = 0; i < count; i++) { 305 if (!mask || mask[i]) { 306 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 307 *dst = src[i]; 308 } 309 } 310} 311 312 313static void 314put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 315 const GLint x[], const GLint y[], 316 const void *value, const GLubyte *mask) 317{ 318 const GLubyte val = *((const GLubyte *) value); 319 GLuint i; 320 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 321 for (i = 0; i < count; i++) { 322 if (!mask || mask[i]) { 323 GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; 324 *dst = val; 325 } 326 } 327} 328 329 330/********************************************************************** 331 * Functions for buffers of 1 X GLushort values. 332 * Typically depth/Z. 333 */ 334 335static void 336get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 337 const GLint x[], const GLint y[], void *values) 338{ 339 GLushort *dst = (GLushort *) values; 340 GLuint i; 341 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 342 for (i = 0; i < count; i++) { 343 const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 344 dst[i] = *src; 345 } 346} 347 348 349static void 350put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 351 GLint x, GLint y, const void *values, const GLubyte *mask) 352{ 353 const GLushort *src = (const GLushort *) values; 354 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 355 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 356 if (mask) { 357 GLuint i; 358 for (i = 0; i < count; i++) { 359 if (mask[i]) { 360 dst[i] = src[i]; 361 } 362 } 363 } 364 else { 365 memcpy(dst, src, count * sizeof(GLushort)); 366 } 367} 368 369 370static void 371put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 372 GLint x, GLint y, const void *value, const GLubyte *mask) 373{ 374 const GLushort val = *((const GLushort *) value); 375 GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; 376 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 377 if (mask) { 378 GLuint i; 379 for (i = 0; i < count; i++) { 380 if (mask[i]) { 381 dst[i] = val; 382 } 383 } 384 } 385 else { 386 GLuint i; 387 for (i = 0; i < count; i++) { 388 dst[i] = val; 389 } 390 } 391} 392 393 394static void 395put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 396 const GLint x[], const GLint y[], const void *values, 397 const GLubyte *mask) 398{ 399 const GLushort *src = (const GLushort *) values; 400 GLuint i; 401 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 402 for (i = 0; i < count; i++) { 403 if (!mask || mask[i]) { 404 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 405 *dst = src[i]; 406 } 407 } 408} 409 410 411static void 412put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, 413 GLuint count, const GLint x[], const GLint y[], 414 const void *value, const GLubyte *mask) 415{ 416 const GLushort val = *((const GLushort *) value); 417 ASSERT(rb->DataType == GL_UNSIGNED_SHORT); 418 if (mask) { 419 GLuint i; 420 for (i = 0; i < count; i++) { 421 if (mask[i]) { 422 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 423 *dst = val; 424 } 425 } 426 } 427 else { 428 GLuint i; 429 for (i = 0; i < count; i++) { 430 GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; 431 *dst = val; 432 } 433 } 434} 435 436 437/********************************************************************** 438 * Functions for buffers of 1 X GLuint values. 439 * Typically depth/Z or color index. 440 */ 441 442static void 443get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 444 const GLint x[], const GLint y[], void *values) 445{ 446 GLuint *dst = (GLuint *) values; 447 GLuint i; 448 ASSERT(rb->DataType == GL_UNSIGNED_INT || 449 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 450 for (i = 0; i < count; i++) { 451 const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 452 dst[i] = *src; 453 } 454} 455 456 457static void 458put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 459 GLint x, GLint y, const void *values, const GLubyte *mask) 460{ 461 const GLuint *src = (const GLuint *) values; 462 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 463 ASSERT(rb->DataType == GL_UNSIGNED_INT || 464 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 465 if (mask) { 466 GLuint i; 467 for (i = 0; i < count; i++) { 468 if (mask[i]) { 469 dst[i] = src[i]; 470 } 471 } 472 } 473 else { 474 memcpy(dst, src, count * sizeof(GLuint)); 475 } 476} 477 478 479static void 480put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 481 GLint x, GLint y, const void *value, const GLubyte *mask) 482{ 483 const GLuint val = *((const GLuint *) value); 484 GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; 485 ASSERT(rb->DataType == GL_UNSIGNED_INT || 486 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 487 if (mask) { 488 GLuint i; 489 for (i = 0; i < count; i++) { 490 if (mask[i]) { 491 dst[i] = val; 492 } 493 } 494 } 495 else { 496 GLuint i; 497 for (i = 0; i < count; i++) { 498 dst[i] = val; 499 } 500 } 501} 502 503 504static void 505put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 506 const GLint x[], const GLint y[], const void *values, 507 const GLubyte *mask) 508{ 509 const GLuint *src = (const GLuint *) values; 510 GLuint i; 511 ASSERT(rb->DataType == GL_UNSIGNED_INT || 512 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 513 for (i = 0; i < count; i++) { 514 if (!mask || mask[i]) { 515 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 516 *dst = src[i]; 517 } 518 } 519} 520 521 522static void 523put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 524 const GLint x[], const GLint y[], const void *value, 525 const GLubyte *mask) 526{ 527 const GLuint val = *((const GLuint *) value); 528 GLuint i; 529 ASSERT(rb->DataType == GL_UNSIGNED_INT || 530 rb->DataType == GL_UNSIGNED_INT_24_8_EXT); 531 for (i = 0; i < count; i++) { 532 if (!mask || mask[i]) { 533 GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; 534 *dst = val; 535 } 536 } 537} 538 539 540/********************************************************************** 541 * Functions for buffers of 3 X GLubyte (or GLbyte) values. 542 * Typically color buffers. 543 * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming 544 * alpha values and return 255 for outgoing alpha values. 545 */ 546 547static void * 548get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 549 GLint x, GLint y) 550{ 551 ASSERT(rb->Format == MESA_FORMAT_RGB888); 552 /* No direct access since this buffer is RGB but caller will be 553 * treating it as if it were RGBA. 554 */ 555 return NULL; 556} 557 558 559static void 560get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 561 GLint x, GLint y, void *values) 562{ 563 const GLubyte *src = ((const GLubyte *) rb->Data) + 564 3 * (y * rb->RowStride + x); 565 GLubyte *dst = (GLubyte *) values; 566 GLuint i; 567 ASSERT(rb->Format == MESA_FORMAT_RGB888); 568 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 569 for (i = 0; i < count; i++) { 570 dst[i * 4 + 0] = src[i * 3 + 0]; 571 dst[i * 4 + 1] = src[i * 3 + 1]; 572 dst[i * 4 + 2] = src[i * 3 + 2]; 573 dst[i * 4 + 3] = 255; 574 } 575} 576 577 578static void 579get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 580 const GLint x[], const GLint y[], void *values) 581{ 582 GLubyte *dst = (GLubyte *) values; 583 GLuint i; 584 ASSERT(rb->Format == MESA_FORMAT_RGB888); 585 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 586 for (i = 0; i < count; i++) { 587 const GLubyte *src 588 = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 589 dst[i * 4 + 0] = src[0]; 590 dst[i * 4 + 1] = src[1]; 591 dst[i * 4 + 2] = src[2]; 592 dst[i * 4 + 3] = 255; 593 } 594} 595 596 597static void 598put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 599 GLint x, GLint y, const void *values, const GLubyte *mask) 600{ 601 /* note: incoming values are RGB+A! */ 602 const GLubyte *src = (const GLubyte *) values; 603 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 604 GLuint i; 605 ASSERT(rb->Format == MESA_FORMAT_RGB888); 606 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 607 for (i = 0; i < count; i++) { 608 if (!mask || mask[i]) { 609 dst[i * 3 + 0] = src[i * 4 + 0]; 610 dst[i * 3 + 1] = src[i * 4 + 1]; 611 dst[i * 3 + 2] = src[i * 4 + 2]; 612 } 613 } 614} 615 616 617static void 618put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 619 GLint x, GLint y, const void *values, const GLubyte *mask) 620{ 621 /* note: incoming values are RGB+A! */ 622 const GLubyte *src = (const GLubyte *) values; 623 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 624 GLuint i; 625 ASSERT(rb->Format == MESA_FORMAT_RGB888); 626 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 627 for (i = 0; i < count; i++) { 628 if (!mask || mask[i]) { 629 dst[i * 3 + 0] = src[i * 3 + 0]; 630 dst[i * 3 + 1] = src[i * 3 + 1]; 631 dst[i * 3 + 2] = src[i * 3 + 2]; 632 } 633 } 634} 635 636 637static void 638put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 639 GLint x, GLint y, const void *value, const GLubyte *mask) 640{ 641 /* note: incoming value is RGB+A! */ 642 const GLubyte val0 = ((const GLubyte *) value)[0]; 643 const GLubyte val1 = ((const GLubyte *) value)[1]; 644 const GLubyte val2 = ((const GLubyte *) value)[2]; 645 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); 646 ASSERT(rb->Format == MESA_FORMAT_RGB888); 647 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 648 if (!mask && val0 == val1 && val1 == val2) { 649 /* optimized case */ 650 memset(dst, val0, 3 * count); 651 } 652 else { 653 GLuint i; 654 for (i = 0; i < count; i++) { 655 if (!mask || mask[i]) { 656 dst[i * 3 + 0] = val0; 657 dst[i * 3 + 1] = val1; 658 dst[i * 3 + 2] = val2; 659 } 660 } 661 } 662} 663 664 665static void 666put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 667 const GLint x[], const GLint y[], const void *values, 668 const GLubyte *mask) 669{ 670 /* note: incoming values are RGB+A! */ 671 const GLubyte *src = (const GLubyte *) values; 672 GLuint i; 673 ASSERT(rb->Format == MESA_FORMAT_RGB888); 674 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 675 for (i = 0; i < count; i++) { 676 if (!mask || mask[i]) { 677 GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); 678 dst[0] = src[i * 4 + 0]; 679 dst[1] = src[i * 4 + 1]; 680 dst[2] = src[i * 4 + 2]; 681 } 682 } 683} 684 685 686static void 687put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, 688 GLuint count, const GLint x[], const GLint y[], 689 const void *value, const GLubyte *mask) 690{ 691 /* note: incoming value is RGB+A! */ 692 const GLubyte val0 = ((const GLubyte *) value)[0]; 693 const GLubyte val1 = ((const GLubyte *) value)[1]; 694 const GLubyte val2 = ((const GLubyte *) value)[2]; 695 GLuint i; 696 ASSERT(rb->Format == MESA_FORMAT_RGB888); 697 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 698 for (i = 0; i < count; i++) { 699 if (!mask || mask[i]) { 700 GLubyte *dst = ((GLubyte *) rb->Data) + 701 3 * (y[i] * rb->RowStride + x[i]); 702 dst[0] = val0; 703 dst[1] = val1; 704 dst[2] = val2; 705 } 706 } 707} 708 709 710/********************************************************************** 711 * Functions for buffers of 4 X GLubyte (or GLbyte) values. 712 * Typically color buffers. 713 */ 714 715static void 716get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 717 const GLint x[], const GLint y[], void *values) 718{ 719 /* treat 4*GLubyte as 1*GLuint */ 720 GLuint *dst = (GLuint *) values; 721 GLuint i; 722 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 723 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 724 for (i = 0; i < count; i++) { 725 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 726 dst[i] = *src; 727 } 728} 729 730 731static void 732put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 733 GLint x, GLint y, const void *values, const GLubyte *mask) 734{ 735 /* treat 4*GLubyte as 1*GLuint */ 736 const GLuint *src = (const GLuint *) values; 737 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 738 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 739 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 740 if (mask) { 741 GLuint i; 742 for (i = 0; i < count; i++) { 743 if (mask[i]) { 744 dst[i] = src[i]; 745 } 746 } 747 } 748 else { 749 memcpy(dst, src, 4 * count * sizeof(GLubyte)); 750 } 751} 752 753 754static void 755put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 756 GLint x, GLint y, const void *values, const GLubyte *mask) 757{ 758 /* Store RGB values in RGBA buffer */ 759 const GLubyte *src = (const GLubyte *) values; 760 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); 761 GLuint i; 762 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 763 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 764 for (i = 0; i < count; i++) { 765 if (!mask || mask[i]) { 766 dst[i * 4 + 0] = src[i * 3 + 0]; 767 dst[i * 4 + 1] = src[i * 3 + 1]; 768 dst[i * 4 + 2] = src[i * 3 + 2]; 769 dst[i * 4 + 3] = 0xff; 770 } 771 } 772} 773 774 775static void 776put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 777 GLint x, GLint y, const void *value, const GLubyte *mask) 778{ 779 /* treat 4*GLubyte as 1*GLuint */ 780 const GLuint val = *((const GLuint *) value); 781 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 782 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 783 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 784 if (!mask && val == 0) { 785 /* common case */ 786 memset(dst, 0, count * 4 * sizeof(GLubyte)); 787 } 788 else { 789 /* general case */ 790 if (mask) { 791 GLuint i; 792 for (i = 0; i < count; i++) { 793 if (mask[i]) { 794 dst[i] = val; 795 } 796 } 797 } 798 else { 799 GLuint i; 800 for (i = 0; i < count; i++) { 801 dst[i] = val; 802 } 803 } 804 } 805} 806 807 808static void 809put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 810 const GLint x[], const GLint y[], const void *values, 811 const GLubyte *mask) 812{ 813 /* treat 4*GLubyte as 1*GLuint */ 814 const GLuint *src = (const GLuint *) values; 815 GLuint i; 816 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 817 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 818 for (i = 0; i < count; i++) { 819 if (!mask || mask[i]) { 820 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 821 *dst = src[i]; 822 } 823 } 824} 825 826 827static void 828put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, 829 GLuint count, const GLint x[], const GLint y[], 830 const void *value, const GLubyte *mask) 831{ 832 /* treat 4*GLubyte as 1*GLuint */ 833 const GLuint val = *((const GLuint *) value); 834 GLuint i; 835 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 836 ASSERT(rb->Format == MESA_FORMAT_RGBA8888); 837 for (i = 0; i < count; i++) { 838 if (!mask || mask[i]) { 839 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 840 *dst = val; 841 } 842 } 843} 844 845 846/********************************************************************** 847 * Functions for buffers of 4 X GLushort (or GLshort) values. 848 * Typically accum buffer. 849 */ 850 851static void 852get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 853 const GLint x[], const GLint y[], void *values) 854{ 855 GLushort *dst = (GLushort *) values; 856 GLuint i; 857 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 858 for (i = 0; i < count; i++) { 859 const GLushort *src 860 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); 861 dst[i] = *src; 862 } 863} 864 865 866static void 867put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 868 GLint x, GLint y, const void *values, const GLubyte *mask) 869{ 870 const GLushort *src = (const GLushort *) values; 871 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 872 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 873 if (mask) { 874 GLuint i; 875 for (i = 0; i < count; i++) { 876 if (mask[i]) { 877 dst[i * 4 + 0] = src[i * 4 + 0]; 878 dst[i * 4 + 1] = src[i * 4 + 1]; 879 dst[i * 4 + 2] = src[i * 4 + 2]; 880 dst[i * 4 + 3] = src[i * 4 + 3]; 881 } 882 } 883 } 884 else { 885 memcpy(dst, src, 4 * count * sizeof(GLushort)); 886 } 887} 888 889 890static void 891put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 892 GLint x, GLint y, const void *values, const GLubyte *mask) 893{ 894 /* Put RGB values in RGBA buffer */ 895 const GLushort *src = (const GLushort *) values; 896 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 897 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 898 if (mask) { 899 GLuint i; 900 for (i = 0; i < count; i++) { 901 if (mask[i]) { 902 dst[i * 4 + 0] = src[i * 3 + 0]; 903 dst[i * 4 + 1] = src[i * 3 + 1]; 904 dst[i * 4 + 2] = src[i * 3 + 2]; 905 dst[i * 4 + 3] = 0xffff; 906 } 907 } 908 } 909 else { 910 memcpy(dst, src, 4 * count * sizeof(GLushort)); 911 } 912} 913 914 915static void 916put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 917 GLint x, GLint y, const void *value, const GLubyte *mask) 918{ 919 const GLushort val0 = ((const GLushort *) value)[0]; 920 const GLushort val1 = ((const GLushort *) value)[1]; 921 const GLushort val2 = ((const GLushort *) value)[2]; 922 const GLushort val3 = ((const GLushort *) value)[3]; 923 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 924 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 925 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 926 /* common case for clearing accum buffer */ 927 memset(dst, 0, count * 4 * sizeof(GLushort)); 928 } 929 else { 930 GLuint i; 931 for (i = 0; i < count; i++) { 932 if (!mask || mask[i]) { 933 dst[i * 4 + 0] = val0; 934 dst[i * 4 + 1] = val1; 935 dst[i * 4 + 2] = val2; 936 dst[i * 4 + 3] = val3; 937 } 938 } 939 } 940} 941 942 943static void 944put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 945 const GLint x[], const GLint y[], const void *values, 946 const GLubyte *mask) 947{ 948 const GLushort *src = (const GLushort *) values; 949 GLuint i; 950 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 951 for (i = 0; i < count; i++) { 952 if (!mask || mask[i]) { 953 GLushort *dst = 954 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); 955 dst[0] = src[i * 4 + 0]; 956 dst[1] = src[i * 4 + 1]; 957 dst[2] = src[i * 4 + 2]; 958 dst[3] = src[i * 4 + 3]; 959 } 960 } 961} 962 963 964static void 965put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, 966 GLuint count, const GLint x[], const GLint y[], 967 const void *value, const GLubyte *mask) 968{ 969 const GLushort val0 = ((const GLushort *) value)[0]; 970 const GLushort val1 = ((const GLushort *) value)[1]; 971 const GLushort val2 = ((const GLushort *) value)[2]; 972 const GLushort val3 = ((const GLushort *) value)[3]; 973 GLuint i; 974 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 975 for (i = 0; i < count; i++) { 976 if (!mask || mask[i]) { 977 GLushort *dst = ((GLushort *) rb->Data) + 978 4 * (y[i] * rb->RowStride + x[i]); 979 dst[0] = val0; 980 dst[1] = val1; 981 dst[2] = val2; 982 dst[3] = val3; 983 } 984 } 985} 986 987/********************************************************************** 988 * Functions for MESA_FORMAT_R8. 989 */ 990static void 991get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 992 GLint x, GLint y, void *values) 993{ 994 const GLubyte *src = rb->GetPointer(ctx, rb, x, y); 995 GLuint *dst = values; 996 GLuint i; 997 998 for (i = 0; i < count; i++) { 999 dst[i] = 0xff000000 | src[i]; 1000 } 1001} 1002 1003static void 1004get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1005 const GLint x[], const GLint y[], void *values) 1006{ 1007 GLuint *dst = (GLuint *) values; 1008 GLuint i; 1009 1010 for (i = 0; i < count; i++) { 1011 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1012 dst[i] = 0xff000000 | *src; 1013 } 1014} 1015 1016/********************************************************************** 1017 * Functions for MESA_FORMAT_RG88. 1018 */ 1019static void 1020get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1021 GLint x, GLint y, void *values) 1022{ 1023 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1024 GLuint *dst = values; 1025 GLuint i; 1026 1027 for (i = 0; i < count; i++) { 1028 dst[i] = 0xff000000 | src[i]; 1029 } 1030} 1031 1032static void 1033get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, 1034 GLuint count, const GLint x[], const GLint y[], void *values) 1035{ 1036 GLuint *dst = (GLuint *) values; 1037 GLuint i; 1038 1039 for (i = 0; i < count; i++) { 1040 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1041 dst[i] = 0xff000000 | *src; 1042 } 1043} 1044 1045/********************************************************************** 1046 * Functions for MESA_FORMAT_R16. 1047 */ 1048static void 1049get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1050 GLint x, GLint y, void *values) 1051{ 1052 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1053 GLushort *dst = values; 1054 GLuint i; 1055 1056 for (i = 0; i < count; i++) { 1057 dst[i * 4 + RCOMP] = src[i]; 1058 dst[i * 4 + GCOMP] = 0; 1059 dst[i * 4 + BCOMP] = 0; 1060 dst[i * 4 + ACOMP] = 0xffff; 1061 } 1062} 1063 1064static void 1065get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1066 const GLint x[], const GLint y[], void *values) 1067{ 1068 GLushort *dst = values; 1069 GLuint i; 1070 1071 for (i = 0; i < count; i++) { 1072 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1073 dst[i * 4 + RCOMP] = *src; 1074 dst[i * 4 + GCOMP] = 0; 1075 dst[i * 4 + BCOMP] = 0; 1076 dst[i * 4 + ACOMP] = 0xffff; 1077 } 1078} 1079 1080/********************************************************************** 1081 * Functions for MESA_FORMAT_RG1616. 1082 */ 1083static void 1084get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1085 GLint x, GLint y, void *values) 1086{ 1087 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1088 GLushort *dst = values; 1089 GLuint i; 1090 1091 for (i = 0; i < count; i++) { 1092 dst[i * 4 + RCOMP] = src[i * 2]; 1093 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1094 dst[i * 4 + BCOMP] = 0; 1095 dst[i * 4 + ACOMP] = 0xffff; 1096 } 1097} 1098 1099static void 1100get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, 1101 GLuint count, const GLint x[], const GLint y[], void *values) 1102{ 1103 GLushort *dst = values; 1104 GLuint i; 1105 1106 for (i = 0; i < count; i++) { 1107 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1108 dst[i * 4 + RCOMP] = src[0]; 1109 dst[i * 4 + GCOMP] = src[1]; 1110 dst[i * 4 + BCOMP] = 0; 1111 dst[i * 4 + ACOMP] = 0xffff; 1112 } 1113} 1114 1115/********************************************************************** 1116 * Functions for MESA_FORMAT_INTENSITY_FLOAT32. 1117 */ 1118static void 1119get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1120 GLuint count, GLint x, GLint y, void *values) 1121{ 1122 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1123 GLfloat *dst = values; 1124 GLuint i; 1125 1126 for (i = 0; i < count; i++) { 1127 dst[i * 4 + RCOMP] = 1128 dst[i * 4 + GCOMP] = 1129 dst[i * 4 + BCOMP] = 1130 dst[i * 4 + ACOMP] = src[i]; 1131 } 1132} 1133 1134static void 1135get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1136 GLuint count, const GLint x[], const GLint y[], 1137 void *values) 1138{ 1139 GLfloat *dst = values; 1140 GLuint i; 1141 1142 for (i = 0; i < count; i++) { 1143 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1144 dst[i * 4 + RCOMP] = 1145 dst[i * 4 + GCOMP] = 1146 dst[i * 4 + BCOMP] = 1147 dst[i * 4 + ACOMP] = src[0]; 1148 } 1149} 1150 1151/********************************************************************** 1152 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. 1153 */ 1154static void 1155get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1156 GLuint count, GLint x, GLint y, void *values) 1157{ 1158 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1159 GLfloat *dst = values; 1160 GLuint i; 1161 1162 for (i = 0; i < count; i++) { 1163 dst[i * 4 + RCOMP] = 1164 dst[i * 4 + GCOMP] = 1165 dst[i * 4 + BCOMP] = src[i]; 1166 dst[i * 4 + ACOMP] = 1.0; 1167 } 1168} 1169 1170static void 1171get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1172 GLuint count, const GLint x[], const GLint y[], 1173 void *values) 1174{ 1175 GLfloat *dst = values; 1176 GLuint i; 1177 1178 for (i = 0; i < count; i++) { 1179 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1180 dst[i * 4 + RCOMP] = 1181 dst[i * 4 + GCOMP] = 1182 dst[i * 4 + BCOMP] = src[0]; 1183 dst[i * 4 + ACOMP] = 1.0; 1184 } 1185} 1186 1187/********************************************************************** 1188 * Functions for MESA_FORMAT_ALPHA_FLOAT32. 1189 */ 1190static void 1191get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1192 GLuint count, GLint x, GLint y, void *values) 1193{ 1194 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1195 GLfloat *dst = values; 1196 GLuint i; 1197 1198 for (i = 0; i < count; i++) { 1199 dst[i * 4 + RCOMP] = 0.0; 1200 dst[i * 4 + GCOMP] = 0.0; 1201 dst[i * 4 + BCOMP] = 0.0; 1202 dst[i * 4 + ACOMP] = src[i]; 1203 } 1204} 1205 1206static void 1207get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1208 GLuint count, const GLint x[], const GLint y[], 1209 void *values) 1210{ 1211 GLfloat *dst = values; 1212 GLuint i; 1213 1214 for (i = 0; i < count; i++) { 1215 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1216 dst[i * 4 + RCOMP] = 0.0; 1217 dst[i * 4 + GCOMP] = 0.0; 1218 dst[i * 4 + BCOMP] = 0.0; 1219 dst[i * 4 + ACOMP] = src[0]; 1220 } 1221} 1222 1223static void 1224put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1225 GLuint count, GLint x, GLint y, 1226 const void *values, const GLubyte *mask) 1227{ 1228 float *dst = rb->GetPointer(ctx, rb, x, y); 1229 const float *src = values; 1230 unsigned int i; 1231 1232 if (mask) { 1233 for (i = 0; i < count; i++) { 1234 if (mask[i]) { 1235 dst[i] = src[i * 4 + ACOMP]; 1236 } 1237 } 1238 } 1239 else { 1240 for (i = 0; i < count; i++) { 1241 dst[i] = src[i * 4 + ACOMP]; 1242 } 1243 } 1244} 1245 1246static void 1247put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1248 GLuint count, GLint x, GLint y, 1249 const void *value, const GLubyte *mask) 1250{ 1251 float *dst = rb->GetPointer(ctx, rb, x, y); 1252 const float *src = value; 1253 unsigned int i; 1254 1255 if (mask) { 1256 for (i = 0; i < count; i++) { 1257 if (mask[i]) { 1258 dst[i] = src[ACOMP]; 1259 } 1260 } 1261 } 1262 else { 1263 for (i = 0; i < count; i++) { 1264 dst[i] = src[ACOMP]; 1265 } 1266 } 1267} 1268 1269static void 1270put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1271 GLuint count, const GLint x[], const GLint y[], 1272 const void *values, const GLubyte *mask) 1273{ 1274 const float *src = values; 1275 unsigned int i; 1276 1277 for (i = 0; i < count; i++) { 1278 if (!mask || mask[i]) { 1279 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1280 1281 *dst = src[i * 4 + ACOMP]; 1282 } 1283 } 1284} 1285 1286static void 1287put_mono_values_a_float32(struct gl_context *ctx, 1288 struct gl_renderbuffer *rb, 1289 GLuint count, const GLint x[], const GLint y[], 1290 const void *value, const GLubyte *mask) 1291{ 1292 const float *src = value; 1293 unsigned int i; 1294 1295 for (i = 0; i < count; i++) { 1296 if (!mask || mask[i]) { 1297 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1298 *dst = src[ACOMP]; 1299 } 1300 } 1301} 1302 1303/********************************************************************** 1304 * Functions for MESA_FORMAT_R_FLOAT32. 1305 */ 1306static void 1307get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1308 GLuint count, GLint x, GLint y, void *values) 1309{ 1310 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1311 GLfloat *dst = values; 1312 GLuint i; 1313 1314 for (i = 0; i < count; i++) { 1315 dst[i * 4 + RCOMP] = src[i]; 1316 dst[i * 4 + GCOMP] = 0.0; 1317 dst[i * 4 + BCOMP] = 0.0; 1318 dst[i * 4 + ACOMP] = 1.0; 1319 } 1320} 1321 1322static void 1323get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1324 GLuint count, const GLint x[], const GLint y[], 1325 void *values) 1326{ 1327 GLfloat *dst = values; 1328 GLuint i; 1329 1330 for (i = 0; i < count; i++) { 1331 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1332 dst[i * 4 + RCOMP] = src[0]; 1333 dst[i * 4 + GCOMP] = 0.0; 1334 dst[i * 4 + BCOMP] = 0.0; 1335 dst[i * 4 + ACOMP] = 1.0; 1336 } 1337} 1338 1339/********************************************************************** 1340 * Functions for MESA_FORMAT_RG_FLOAT32. 1341 */ 1342static void 1343get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1344 GLuint count, GLint x, GLint y, void *values) 1345{ 1346 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1347 GLfloat *dst = values; 1348 GLuint i; 1349 1350 for (i = 0; i < count; i++) { 1351 dst[i * 4 + RCOMP] = src[i * 2 + 0]; 1352 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1353 dst[i * 4 + BCOMP] = 0.0; 1354 dst[i * 4 + ACOMP] = 1.0; 1355 } 1356} 1357 1358static void 1359get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1360 GLuint count, const GLint x[], const GLint y[], 1361 void *values) 1362{ 1363 GLfloat *dst = values; 1364 GLuint i; 1365 1366 for (i = 0; i < count; i++) { 1367 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1368 dst[i * 4 + RCOMP] = src[0]; 1369 dst[i * 4 + GCOMP] = src[1]; 1370 dst[i * 4 + BCOMP] = 0.0; 1371 dst[i * 4 + ACOMP] = 1.0; 1372 } 1373} 1374 1375/** 1376 * This is the default software fallback for gl_renderbuffer's span 1377 * access functions. 1378 * 1379 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels 1380 * are packed in the type of rb->Format, and that subsequent rows appear 1381 * rb->RowStride pixels later. 1382 */ 1383void 1384_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb) 1385{ 1386 rb->GetPointer = get_pointer_generic; 1387 rb->GetRow = get_row_generic; 1388 1389 switch (rb->Format) { 1390 case MESA_FORMAT_RGB888: 1391 rb->DataType = GL_UNSIGNED_BYTE; 1392 rb->GetPointer = get_pointer_ubyte3; 1393 rb->GetRow = get_row_ubyte3; 1394 rb->GetValues = get_values_ubyte3; 1395 rb->PutRow = put_row_ubyte3; 1396 rb->PutRowRGB = put_row_rgb_ubyte3; 1397 rb->PutMonoRow = put_mono_row_ubyte3; 1398 rb->PutValues = put_values_ubyte3; 1399 rb->PutMonoValues = put_mono_values_ubyte3; 1400 break; 1401 1402 case MESA_FORMAT_RGBA8888: 1403 rb->DataType = GL_UNSIGNED_BYTE; 1404 rb->GetValues = get_values_ubyte4; 1405 rb->PutRow = put_row_ubyte4; 1406 rb->PutRowRGB = put_row_rgb_ubyte4; 1407 rb->PutMonoRow = put_mono_row_ubyte4; 1408 rb->PutValues = put_values_ubyte4; 1409 rb->PutMonoValues = put_mono_values_ubyte4; 1410 break; 1411 1412 case MESA_FORMAT_R8: 1413 rb->DataType = GL_UNSIGNED_BYTE; 1414 rb->GetValues = get_values_r8; 1415 rb->GetRow = get_row_r8; 1416 rb->PutRow = put_row_generic; 1417 rb->PutRowRGB = put_row_generic; 1418 rb->PutMonoRow = put_mono_row_generic; 1419 rb->PutValues = put_values_generic; 1420 rb->PutMonoValues = put_mono_values_generic; 1421 break; 1422 1423 case MESA_FORMAT_RG88: 1424 rb->DataType = GL_UNSIGNED_BYTE; 1425 rb->GetValues = get_values_rg88; 1426 rb->GetRow = get_row_rg88; 1427 rb->PutRow = put_row_generic; 1428 rb->PutRowRGB = put_row_generic; 1429 rb->PutMonoRow = put_mono_row_generic; 1430 rb->PutValues = put_values_generic; 1431 rb->PutMonoValues = put_mono_values_generic; 1432 break; 1433 1434 case MESA_FORMAT_R16: 1435 rb->DataType = GL_UNSIGNED_SHORT; 1436 rb->GetValues = get_values_r16; 1437 rb->GetRow = get_row_r16; 1438 rb->PutRow = put_row_generic; 1439 rb->PutRowRGB = put_row_generic; 1440 rb->PutMonoRow = put_mono_row_generic; 1441 rb->PutValues = put_values_generic; 1442 rb->PutMonoValues = put_mono_values_generic; 1443 break; 1444 1445 case MESA_FORMAT_RG1616: 1446 rb->DataType = GL_UNSIGNED_SHORT; 1447 rb->GetValues = get_values_rg1616; 1448 rb->GetRow = get_row_rg1616; 1449 rb->PutRow = put_row_generic; 1450 rb->PutRowRGB = put_row_generic; 1451 rb->PutMonoRow = put_mono_row_generic; 1452 rb->PutValues = put_values_generic; 1453 rb->PutMonoValues = put_mono_values_generic; 1454 break; 1455 1456 case MESA_FORMAT_SIGNED_RGBA_16: 1457 rb->DataType = GL_SHORT; 1458 rb->GetValues = get_values_ushort4; 1459 rb->PutRow = put_row_ushort4; 1460 rb->PutRowRGB = put_row_rgb_ushort4; 1461 rb->PutMonoRow = put_mono_row_ushort4; 1462 rb->PutValues = put_values_ushort4; 1463 rb->PutMonoValues = put_mono_values_ushort4; 1464 break; 1465 1466#if 0 1467 case MESA_FORMAT_A8: 1468 rb->DataType = GL_UNSIGNED_BYTE; 1469 rb->GetValues = get_values_alpha8; 1470 rb->PutRow = put_row_alpha8; 1471 rb->PutRowRGB = NULL; 1472 rb->PutMonoRow = put_mono_row_alpha8; 1473 rb->PutValues = put_values_alpha8; 1474 rb->PutMonoValues = put_mono_values_alpha8; 1475 break; 1476#endif 1477 1478 case MESA_FORMAT_S8: 1479 rb->DataType = GL_UNSIGNED_BYTE; 1480 rb->GetValues = get_values_ubyte; 1481 rb->PutRow = put_row_ubyte; 1482 rb->PutRowRGB = NULL; 1483 rb->PutMonoRow = put_mono_row_ubyte; 1484 rb->PutValues = put_values_ubyte; 1485 rb->PutMonoValues = put_mono_values_ubyte; 1486 break; 1487 1488 case MESA_FORMAT_Z16: 1489 rb->DataType = GL_UNSIGNED_SHORT; 1490 rb->GetValues = get_values_ushort; 1491 rb->PutRow = put_row_ushort; 1492 rb->PutRowRGB = NULL; 1493 rb->PutMonoRow = put_mono_row_ushort; 1494 rb->PutValues = put_values_ushort; 1495 rb->PutMonoValues = put_mono_values_ushort; 1496 break; 1497 1498 case MESA_FORMAT_Z32: 1499 case MESA_FORMAT_X8_Z24: 1500 case MESA_FORMAT_Z24_X8: 1501 rb->DataType = GL_UNSIGNED_INT; 1502 rb->GetValues = get_values_uint; 1503 rb->PutRow = put_row_uint; 1504 rb->PutRowRGB = NULL; 1505 rb->PutMonoRow = put_mono_row_uint; 1506 rb->PutValues = put_values_uint; 1507 rb->PutMonoValues = put_mono_values_uint; 1508 break; 1509 1510 case MESA_FORMAT_Z24_S8: 1511 case MESA_FORMAT_S8_Z24: 1512 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 1513 rb->GetValues = get_values_uint; 1514 rb->PutRow = put_row_uint; 1515 rb->PutRowRGB = NULL; 1516 rb->PutMonoRow = put_mono_row_uint; 1517 rb->PutValues = put_values_uint; 1518 rb->PutMonoValues = put_mono_values_uint; 1519 break; 1520 1521 case MESA_FORMAT_RGBA_FLOAT32: 1522 rb->GetRow = get_row_generic; 1523 rb->GetValues = get_values_generic; 1524 rb->PutRow = put_row_generic; 1525 rb->PutRowRGB = NULL; 1526 rb->PutMonoRow = put_mono_row_generic; 1527 rb->PutValues = put_values_generic; 1528 rb->PutMonoValues = put_mono_values_generic; 1529 break; 1530 1531 case MESA_FORMAT_INTENSITY_FLOAT32: 1532 rb->GetRow = get_row_i_float32; 1533 rb->GetValues = get_values_i_float32; 1534 rb->PutRow = put_row_generic; 1535 rb->PutRowRGB = NULL; 1536 rb->PutMonoRow = put_mono_row_generic; 1537 rb->PutValues = put_values_generic; 1538 rb->PutMonoValues = put_mono_values_generic; 1539 break; 1540 1541 case MESA_FORMAT_LUMINANCE_FLOAT32: 1542 rb->GetRow = get_row_l_float32; 1543 rb->GetValues = get_values_l_float32; 1544 rb->PutRow = put_row_generic; 1545 rb->PutRowRGB = NULL; 1546 rb->PutMonoRow = put_mono_row_generic; 1547 rb->PutValues = put_values_generic; 1548 rb->PutMonoValues = put_mono_values_generic; 1549 break; 1550 1551 case MESA_FORMAT_ALPHA_FLOAT32: 1552 rb->GetRow = get_row_a_float32; 1553 rb->GetValues = get_values_a_float32; 1554 rb->PutRow = put_row_a_float32; 1555 rb->PutRowRGB = NULL; 1556 rb->PutMonoRow = put_mono_row_a_float32; 1557 rb->PutValues = put_values_a_float32; 1558 rb->PutMonoValues = put_mono_values_a_float32; 1559 break; 1560 1561 case MESA_FORMAT_RG_FLOAT32: 1562 rb->GetRow = get_row_rg_float32; 1563 rb->GetValues = get_values_rg_float32; 1564 rb->PutRow = put_row_generic; 1565 rb->PutRowRGB = NULL; 1566 rb->PutMonoRow = put_mono_row_generic; 1567 rb->PutValues = put_values_generic; 1568 rb->PutMonoValues = put_mono_values_generic; 1569 break; 1570 1571 case MESA_FORMAT_R_FLOAT32: 1572 rb->GetRow = get_row_r_float32; 1573 rb->GetValues = get_values_r_float32; 1574 rb->PutRow = put_row_generic; 1575 rb->PutRowRGB = NULL; 1576 rb->PutMonoRow = put_mono_row_generic; 1577 rb->PutValues = put_values_generic; 1578 rb->PutMonoValues = put_mono_values_generic; 1579 break; 1580 1581 default: 1582 break; 1583 } 1584} 1585 1586/** 1587 * This is a software fallback for the gl_renderbuffer->AllocStorage 1588 * function. 1589 * Device drivers will typically override this function for the buffers 1590 * which it manages (typically color buffers, Z and stencil). 1591 * Other buffers (like software accumulation and aux buffers) which the driver 1592 * doesn't manage can be handled with this function. 1593 * 1594 * This one multi-purpose function can allocate stencil, depth, accum, color 1595 * or color-index buffers! 1596 * 1597 * This function also plugs in the appropriate GetPointer, Get/PutRow and 1598 * Get/PutValues functions. 1599 */ 1600GLboolean 1601_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 1602 GLenum internalFormat, 1603 GLuint width, GLuint height) 1604{ 1605 switch (internalFormat) { 1606 case GL_RGB: 1607 case GL_R3_G3_B2: 1608 case GL_RGB4: 1609 case GL_RGB5: 1610 case GL_RGB8: 1611 case GL_RGB10: 1612 case GL_RGB12: 1613 case GL_RGB16: 1614 rb->Format = MESA_FORMAT_RGB888; 1615 break; 1616 case GL_RGBA: 1617 case GL_RGBA2: 1618 case GL_RGBA4: 1619 case GL_RGB5_A1: 1620 case GL_RGBA8: 1621#if 1 1622 case GL_RGB10_A2: 1623 case GL_RGBA12: 1624#endif 1625 rb->Format = MESA_FORMAT_RGBA8888; 1626 break; 1627 case GL_RGBA16: 1628 case GL_RGBA16_SNORM: 1629 /* for accum buffer */ 1630 rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 1631 break; 1632#if 0 1633 case GL_ALPHA8: 1634 rb->Format = MESA_FORMAT_A8; 1635 break; 1636#endif 1637 case GL_STENCIL_INDEX: 1638 case GL_STENCIL_INDEX1_EXT: 1639 case GL_STENCIL_INDEX4_EXT: 1640 case GL_STENCIL_INDEX8_EXT: 1641 case GL_STENCIL_INDEX16_EXT: 1642 rb->Format = MESA_FORMAT_S8; 1643 break; 1644 case GL_DEPTH_COMPONENT: 1645 case GL_DEPTH_COMPONENT16: 1646 rb->Format = MESA_FORMAT_Z16; 1647 break; 1648 case GL_DEPTH_COMPONENT24: 1649 rb->Format = MESA_FORMAT_X8_Z24; 1650 break; 1651 case GL_DEPTH_COMPONENT32: 1652 rb->Format = MESA_FORMAT_Z32; 1653 break; 1654 case GL_DEPTH_STENCIL_EXT: 1655 case GL_DEPTH24_STENCIL8_EXT: 1656 rb->Format = MESA_FORMAT_Z24_S8; 1657 break; 1658 default: 1659 /* unsupported format */ 1660 return GL_FALSE; 1661 } 1662 1663 _mesa_set_renderbuffer_accessors(rb); 1664 1665 ASSERT(rb->DataType); 1666 ASSERT(rb->GetPointer); 1667 ASSERT(rb->GetRow); 1668 ASSERT(rb->GetValues); 1669 ASSERT(rb->PutRow); 1670 ASSERT(rb->PutMonoRow); 1671 ASSERT(rb->PutValues); 1672 ASSERT(rb->PutMonoValues); 1673 1674 /* free old buffer storage */ 1675 if (rb->Data) { 1676 free(rb->Data); 1677 rb->Data = NULL; 1678 } 1679 1680 rb->RowStride = width; 1681 1682 if (width > 0 && height > 0) { 1683 /* allocate new buffer storage */ 1684 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); 1685 1686 if (rb->Data == NULL) { 1687 rb->Width = 0; 1688 rb->Height = 0; 1689 rb->RowStride = 0; 1690 _mesa_error(ctx, GL_OUT_OF_MEMORY, 1691 "software renderbuffer allocation (%d x %d x %d)", 1692 width, height, _mesa_get_format_bytes(rb->Format)); 1693 return GL_FALSE; 1694 } 1695 } 1696 1697 rb->Width = width; 1698 rb->Height = height; 1699 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 1700 1701 if (rb->Name == 0 && 1702 internalFormat == GL_RGBA16_SNORM && 1703 rb->_BaseFormat == 0) { 1704 /* NOTE: This is a special case just for accumulation buffers. 1705 * This is a very limited use case- there's no snorm texturing or 1706 * rendering going on. 1707 */ 1708 rb->_BaseFormat = GL_RGBA; 1709 } 1710 else { 1711 /* the internalFormat should have been error checked long ago */ 1712 ASSERT(rb->_BaseFormat); 1713 } 1714 1715 return GL_TRUE; 1716} 1717 1718 1719void 1720_mesa_map_soft_renderbuffer(struct gl_context *ctx, 1721 struct gl_renderbuffer *rb, 1722 GLuint x, GLuint y, GLuint w, GLuint h, 1723 GLbitfield mode, 1724 GLubyte **out_map, 1725 GLint *out_stride) 1726{ 1727 GLubyte *map = rb->Data; 1728 int cpp = _mesa_get_format_bytes(rb->Format); 1729 int stride = rb->RowStride * cpp; 1730 1731 ASSERT(rb->Data); 1732 1733 map += y * stride; 1734 map += x * cpp; 1735 1736 *out_map = map; 1737 *out_stride = stride; 1738} 1739 1740void 1741_mesa_unmap_soft_renderbuffer(struct gl_context *ctx, 1742 struct gl_renderbuffer *rb) 1743{ 1744} 1745 1746 1747/**********************************************************************/ 1748/**********************************************************************/ 1749/**********************************************************************/ 1750 1751 1752/** 1753 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha 1754 * buffer wrapper around an existing RGB renderbuffer (hw or sw). 1755 * 1756 * When PutRow is called (for example), we store the alpha values in 1757 * this buffer, then pass on the PutRow call to the wrapped RGB 1758 * buffer. 1759 */ 1760 1761 1762static GLboolean 1763alloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1764 GLenum internalFormat, GLuint width, GLuint height) 1765{ 1766 ASSERT(arb != arb->Wrapped); 1767 ASSERT(arb->Format == MESA_FORMAT_A8); 1768 1769 /* first, pass the call to the wrapped RGB buffer */ 1770 if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat, 1771 width, height)) { 1772 return GL_FALSE; 1773 } 1774 1775 /* next, resize my alpha buffer */ 1776 if (arb->Data) { 1777 free(arb->Data); 1778 } 1779 1780 arb->Data = malloc(width * height * sizeof(GLubyte)); 1781 if (arb->Data == NULL) { 1782 arb->Width = 0; 1783 arb->Height = 0; 1784 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 1785 return GL_FALSE; 1786 } 1787 1788 arb->Width = width; 1789 arb->Height = height; 1790 arb->RowStride = width; 1791 1792 return GL_TRUE; 1793} 1794 1795 1796/** 1797 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 1798 */ 1799static void 1800delete_renderbuffer_alpha8(struct gl_renderbuffer *arb) 1801{ 1802 if (arb->Data) { 1803 free(arb->Data); 1804 } 1805 ASSERT(arb->Wrapped); 1806 ASSERT(arb != arb->Wrapped); 1807 arb->Wrapped->Delete(arb->Wrapped); 1808 arb->Wrapped = NULL; 1809 free(arb); 1810} 1811 1812 1813static void * 1814get_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1815 GLint x, GLint y) 1816{ 1817 return NULL; /* don't allow direct access! */ 1818} 1819 1820 1821static void 1822get_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1823 GLint x, GLint y, void *values) 1824{ 1825 /* NOTE: 'values' is RGBA format! */ 1826 const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x; 1827 GLubyte *dst = (GLubyte *) values; 1828 GLuint i; 1829 ASSERT(arb != arb->Wrapped); 1830 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1831 /* first, pass the call to the wrapped RGB buffer */ 1832 arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values); 1833 /* second, fill in alpha values from this buffer! */ 1834 for (i = 0; i < count; i++) { 1835 dst[i * 4 + 3] = src[i]; 1836 } 1837} 1838 1839 1840static void 1841get_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1842 const GLint x[], const GLint y[], void *values) 1843{ 1844 GLubyte *dst = (GLubyte *) values; 1845 GLuint i; 1846 ASSERT(arb != arb->Wrapped); 1847 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1848 /* first, pass the call to the wrapped RGB buffer */ 1849 arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values); 1850 /* second, fill in alpha values from this buffer! */ 1851 for (i = 0; i < count; i++) { 1852 const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1853 dst[i * 4 + 3] = *src; 1854 } 1855} 1856 1857 1858static void 1859put_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1860 GLint x, GLint y, const void *values, const GLubyte *mask) 1861{ 1862 const GLubyte *src = (const GLubyte *) values; 1863 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1864 GLuint i; 1865 ASSERT(arb != arb->Wrapped); 1866 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1867 /* first, pass the call to the wrapped RGB buffer */ 1868 arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask); 1869 /* second, store alpha in our buffer */ 1870 for (i = 0; i < count; i++) { 1871 if (!mask || mask[i]) { 1872 dst[i] = src[i * 4 + 3]; 1873 } 1874 } 1875} 1876 1877 1878static void 1879put_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1880 GLint x, GLint y, const void *values, const GLubyte *mask) 1881{ 1882 const GLubyte *src = (const GLubyte *) values; 1883 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1884 GLuint i; 1885 ASSERT(arb != arb->Wrapped); 1886 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1887 /* first, pass the call to the wrapped RGB buffer */ 1888 arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask); 1889 /* second, store alpha in our buffer */ 1890 for (i = 0; i < count; i++) { 1891 if (!mask || mask[i]) { 1892 dst[i] = src[i * 4 + 3]; 1893 } 1894 } 1895} 1896 1897 1898static void 1899put_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1900 GLint x, GLint y, const void *value, const GLubyte *mask) 1901{ 1902 const GLubyte val = ((const GLubyte *) value)[3]; 1903 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1904 ASSERT(arb != arb->Wrapped); 1905 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1906 /* first, pass the call to the wrapped RGB buffer */ 1907 arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask); 1908 /* second, store alpha in our buffer */ 1909 if (mask) { 1910 GLuint i; 1911 for (i = 0; i < count; i++) { 1912 if (mask[i]) { 1913 dst[i] = val; 1914 } 1915 } 1916 } 1917 else { 1918 memset(dst, val, count); 1919 } 1920} 1921 1922 1923static void 1924put_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1925 const GLint x[], const GLint y[], 1926 const void *values, const GLubyte *mask) 1927{ 1928 const GLubyte *src = (const GLubyte *) values; 1929 GLuint i; 1930 ASSERT(arb != arb->Wrapped); 1931 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1932 /* first, pass the call to the wrapped RGB buffer */ 1933 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask); 1934 /* second, store alpha in our buffer */ 1935 for (i = 0; i < count; i++) { 1936 if (!mask || mask[i]) { 1937 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1938 *dst = src[i * 4 + 3]; 1939 } 1940 } 1941} 1942 1943 1944static void 1945put_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1946 GLuint count, const GLint x[], const GLint y[], 1947 const void *value, const GLubyte *mask) 1948{ 1949 const GLubyte val = ((const GLubyte *) value)[3]; 1950 GLuint i; 1951 ASSERT(arb != arb->Wrapped); 1952 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1953 /* first, pass the call to the wrapped RGB buffer */ 1954 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask); 1955 /* second, store alpha in our buffer */ 1956 for (i = 0; i < count; i++) { 1957 if (!mask || mask[i]) { 1958 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1959 *dst = val; 1960 } 1961 } 1962} 1963 1964 1965static void 1966copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) 1967{ 1968 ASSERT(dst->Format == MESA_FORMAT_A8); 1969 ASSERT(src->Format == MESA_FORMAT_A8); 1970 ASSERT(dst->Width == src->Width); 1971 ASSERT(dst->Height == src->Height); 1972 ASSERT(dst->RowStride == src->RowStride); 1973 1974 memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte)); 1975} 1976 1977 1978/**********************************************************************/ 1979/**********************************************************************/ 1980/**********************************************************************/ 1981 1982 1983/** 1984 * Default GetPointer routine. Always return NULL to indicate that 1985 * direct buffer access is not supported. 1986 */ 1987static void * 1988nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 1989{ 1990 return NULL; 1991} 1992 1993 1994/** 1995 * Initialize the fields of a gl_renderbuffer to default values. 1996 */ 1997void 1998_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 1999{ 2000 _glthread_INIT_MUTEX(rb->Mutex); 2001 2002 rb->ClassID = 0; 2003 rb->Name = name; 2004 rb->RefCount = 0; 2005 rb->Delete = _mesa_delete_renderbuffer; 2006 2007 /* The rest of these should be set later by the caller of this function or 2008 * the AllocStorage method: 2009 */ 2010 rb->AllocStorage = NULL; 2011 2012 rb->Width = 0; 2013 rb->Height = 0; 2014 rb->InternalFormat = GL_NONE; 2015 rb->Format = MESA_FORMAT_NONE; 2016 2017 rb->DataType = GL_NONE; 2018 rb->Data = NULL; 2019 2020 /* Point back to ourself so that we don't have to check for Wrapped==NULL 2021 * all over the drivers. 2022 */ 2023 rb->Wrapped = rb; 2024 2025 rb->GetPointer = nop_get_pointer; 2026 rb->GetRow = NULL; 2027 rb->GetValues = NULL; 2028 rb->PutRow = NULL; 2029 rb->PutRowRGB = NULL; 2030 rb->PutMonoRow = NULL; 2031 rb->PutValues = NULL; 2032 rb->PutMonoValues = NULL; 2033} 2034 2035 2036/** 2037 * Allocate a new gl_renderbuffer object. This can be used for user-created 2038 * renderbuffers or window-system renderbuffers. 2039 */ 2040struct gl_renderbuffer * 2041_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name) 2042{ 2043 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 2044 if (rb) { 2045 _mesa_init_renderbuffer(rb, name); 2046 } 2047 return rb; 2048} 2049 2050 2051/** 2052 * Delete a gl_framebuffer. 2053 * This is the default function for renderbuffer->Delete(). 2054 */ 2055void 2056_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 2057{ 2058 if (rb->Data) { 2059 free(rb->Data); 2060 } 2061 free(rb); 2062} 2063 2064 2065/** 2066 * Allocate a software-based renderbuffer. This is called via the 2067 * ctx->Driver.NewRenderbuffer() function when the user creates a new 2068 * renderbuffer. 2069 * This would not be used for hardware-based renderbuffers. 2070 */ 2071struct gl_renderbuffer * 2072_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) 2073{ 2074 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 2075 if (rb) { 2076 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2077 /* Normally, one would setup the PutRow, GetRow, etc functions here. 2078 * But we're doing that in the _mesa_soft_renderbuffer_storage() function 2079 * instead. 2080 */ 2081 } 2082 return rb; 2083} 2084 2085 2086/** 2087 * Add software-based color renderbuffers to the given framebuffer. 2088 * This is a helper routine for device drivers when creating a 2089 * window system framebuffer (not a user-created render/framebuffer). 2090 * Once this function is called, you can basically forget about this 2091 * renderbuffer; core Mesa will handle all the buffer management and 2092 * rendering! 2093 */ 2094GLboolean 2095_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2096 GLuint rgbBits, GLuint alphaBits, 2097 GLboolean frontLeft, GLboolean backLeft, 2098 GLboolean frontRight, GLboolean backRight) 2099{ 2100 gl_buffer_index b; 2101 2102 if (rgbBits > 16 || alphaBits > 16) { 2103 _mesa_problem(ctx, 2104 "Unsupported bit depth in _mesa_add_color_renderbuffers"); 2105 return GL_FALSE; 2106 } 2107 2108 assert(MAX_COLOR_ATTACHMENTS >= 4); 2109 2110 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 2111 struct gl_renderbuffer *rb; 2112 2113 if (b == BUFFER_FRONT_LEFT && !frontLeft) 2114 continue; 2115 else if (b == BUFFER_BACK_LEFT && !backLeft) 2116 continue; 2117 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 2118 continue; 2119 else if (b == BUFFER_BACK_RIGHT && !backRight) 2120 continue; 2121 2122 assert(fb->Attachment[b].Renderbuffer == NULL); 2123 2124 rb = _mesa_new_renderbuffer(ctx, 0); 2125 if (!rb) { 2126 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 2127 return GL_FALSE; 2128 } 2129 2130 if (rgbBits <= 8) { 2131 if (alphaBits) 2132 rb->Format = MESA_FORMAT_RGBA8888; 2133 else 2134 rb->Format = MESA_FORMAT_RGB888; 2135 } 2136 else { 2137 assert(rgbBits <= 16); 2138 rb->Format = MESA_FORMAT_NONE; /*XXX RGBA16;*/ 2139 } 2140 rb->InternalFormat = GL_RGBA; 2141 2142 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2143 _mesa_add_renderbuffer(fb, b, rb); 2144 } 2145 2146 return GL_TRUE; 2147} 2148 2149 2150/** 2151 * Add software-based alpha renderbuffers to the given framebuffer. 2152 * This is a helper routine for device drivers when creating a 2153 * window system framebuffer (not a user-created render/framebuffer). 2154 * Once this function is called, you can basically forget about this 2155 * renderbuffer; core Mesa will handle all the buffer management and 2156 * rendering! 2157 */ 2158GLboolean 2159_mesa_add_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2160 GLuint alphaBits, 2161 GLboolean frontLeft, GLboolean backLeft, 2162 GLboolean frontRight, GLboolean backRight) 2163{ 2164 gl_buffer_index b; 2165 2166 /* for window system framebuffers only! */ 2167 assert(fb->Name == 0); 2168 2169 if (alphaBits > 8) { 2170 _mesa_problem(ctx, 2171 "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); 2172 return GL_FALSE; 2173 } 2174 2175 assert(MAX_COLOR_ATTACHMENTS >= 4); 2176 2177 /* Wrap each of the RGB color buffers with an alpha renderbuffer. 2178 */ 2179 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 2180 struct gl_renderbuffer *arb; 2181 2182 if (b == BUFFER_FRONT_LEFT && !frontLeft) 2183 continue; 2184 else if (b == BUFFER_BACK_LEFT && !backLeft) 2185 continue; 2186 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 2187 continue; 2188 else if (b == BUFFER_BACK_RIGHT && !backRight) 2189 continue; 2190 2191 /* the RGB buffer to wrap must already exist!! */ 2192 assert(fb->Attachment[b].Renderbuffer); 2193 2194 /* only GLubyte supported for now */ 2195 assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); 2196 2197 /* allocate alpha renderbuffer */ 2198 arb = _mesa_new_renderbuffer(ctx, 0); 2199 if (!arb) { 2200 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); 2201 return GL_FALSE; 2202 } 2203 2204 /* wrap the alpha renderbuffer around the RGB renderbuffer */ 2205 arb->Wrapped = fb->Attachment[b].Renderbuffer; 2206 2207 /* Set up my alphabuffer fields and plug in my functions. 2208 * The functions will put/get the alpha values from/to RGBA arrays 2209 * and then call the wrapped buffer's functions to handle the RGB 2210 * values. 2211 */ 2212 arb->InternalFormat = arb->Wrapped->InternalFormat; 2213 arb->Format = MESA_FORMAT_A8; 2214 arb->DataType = arb->Wrapped->DataType; 2215 arb->AllocStorage = alloc_storage_alpha8; 2216 arb->Delete = delete_renderbuffer_alpha8; 2217 arb->GetPointer = get_pointer_alpha8; 2218 arb->GetRow = get_row_alpha8; 2219 arb->GetValues = get_values_alpha8; 2220 arb->PutRow = put_row_alpha8; 2221 arb->PutRowRGB = put_row_rgb_alpha8; 2222 arb->PutMonoRow = put_mono_row_alpha8; 2223 arb->PutValues = put_values_alpha8; 2224 arb->PutMonoValues = put_mono_values_alpha8; 2225 2226 /* clear the pointer to avoid assertion/sanity check failure later */ 2227 fb->Attachment[b].Renderbuffer = NULL; 2228 2229 /* plug the alpha renderbuffer into the colorbuffer attachment */ 2230 _mesa_add_renderbuffer(fb, b, arb); 2231 } 2232 2233 return GL_TRUE; 2234} 2235 2236 2237/** 2238 * For framebuffers that use a software alpha channel wrapper 2239 * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers, 2240 * copy the back buffer alpha channel into the front buffer alpha channel. 2241 */ 2242void 2243_mesa_copy_soft_alpha_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb) 2244{ 2245 if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && 2246 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) 2247 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer, 2248 fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); 2249 2250 2251 if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && 2252 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) 2253 copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer, 2254 fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); 2255} 2256 2257 2258/** 2259 * Add a software-based depth renderbuffer to the given framebuffer. 2260 * This is a helper routine for device drivers when creating a 2261 * window system framebuffer (not a user-created render/framebuffer). 2262 * Once this function is called, you can basically forget about this 2263 * renderbuffer; core Mesa will handle all the buffer management and 2264 * rendering! 2265 */ 2266GLboolean 2267_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2268 GLuint depthBits) 2269{ 2270 struct gl_renderbuffer *rb; 2271 2272 if (depthBits > 32) { 2273 _mesa_problem(ctx, 2274 "Unsupported depthBits in _mesa_add_depth_renderbuffer"); 2275 return GL_FALSE; 2276 } 2277 2278 assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); 2279 2280 rb = _mesa_new_renderbuffer(ctx, 0); 2281 if (!rb) { 2282 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); 2283 return GL_FALSE; 2284 } 2285 2286 if (depthBits <= 16) { 2287 rb->Format = MESA_FORMAT_Z16; 2288 rb->InternalFormat = GL_DEPTH_COMPONENT16; 2289 } 2290 else if (depthBits <= 24) { 2291 rb->Format = MESA_FORMAT_X8_Z24; 2292 rb->InternalFormat = GL_DEPTH_COMPONENT24; 2293 } 2294 else { 2295 rb->Format = MESA_FORMAT_Z32; 2296 rb->InternalFormat = GL_DEPTH_COMPONENT32; 2297 } 2298 2299 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2300 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 2301 2302 return GL_TRUE; 2303} 2304 2305 2306/** 2307 * Add a software-based stencil renderbuffer to the given framebuffer. 2308 * This is a helper routine for device drivers when creating a 2309 * window system framebuffer (not a user-created render/framebuffer). 2310 * Once this function is called, you can basically forget about this 2311 * renderbuffer; core Mesa will handle all the buffer management and 2312 * rendering! 2313 */ 2314GLboolean 2315_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2316 GLuint stencilBits) 2317{ 2318 struct gl_renderbuffer *rb; 2319 2320 if (stencilBits > 16) { 2321 _mesa_problem(ctx, 2322 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 2323 return GL_FALSE; 2324 } 2325 2326 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 2327 2328 rb = _mesa_new_renderbuffer(ctx, 0); 2329 if (!rb) { 2330 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 2331 return GL_FALSE; 2332 } 2333 2334 assert(stencilBits <= 8); 2335 rb->Format = MESA_FORMAT_S8; 2336 rb->InternalFormat = GL_STENCIL_INDEX8; 2337 2338 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2339 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 2340 2341 return GL_TRUE; 2342} 2343 2344 2345/** 2346 * Add a software-based accumulation renderbuffer to the given framebuffer. 2347 * This is a helper routine for device drivers when creating a 2348 * window system framebuffer (not a user-created render/framebuffer). 2349 * Once this function is called, you can basically forget about this 2350 * renderbuffer; core Mesa will handle all the buffer management and 2351 * rendering! 2352 */ 2353GLboolean 2354_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2355 GLuint redBits, GLuint greenBits, 2356 GLuint blueBits, GLuint alphaBits) 2357{ 2358 struct gl_renderbuffer *rb; 2359 2360 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 2361 _mesa_problem(ctx, 2362 "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 2363 return GL_FALSE; 2364 } 2365 2366 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 2367 2368 rb = _mesa_new_renderbuffer(ctx, 0); 2369 if (!rb) { 2370 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 2371 return GL_FALSE; 2372 } 2373 2374 rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 2375 rb->InternalFormat = GL_RGBA16_SNORM; 2376 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2377 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 2378 2379 return GL_TRUE; 2380} 2381 2382 2383 2384/** 2385 * Add a software-based aux renderbuffer to the given framebuffer. 2386 * This is a helper routine for device drivers when creating a 2387 * window system framebuffer (not a user-created render/framebuffer). 2388 * Once this function is called, you can basically forget about this 2389 * renderbuffer; core Mesa will handle all the buffer management and 2390 * rendering! 2391 * 2392 * NOTE: color-index aux buffers not supported. 2393 */ 2394GLboolean 2395_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2396 GLuint colorBits, GLuint numBuffers) 2397{ 2398 GLuint i; 2399 2400 if (colorBits > 16) { 2401 _mesa_problem(ctx, 2402 "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 2403 return GL_FALSE; 2404 } 2405 2406 assert(numBuffers <= MAX_AUX_BUFFERS); 2407 2408 for (i = 0; i < numBuffers; i++) { 2409 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 2410 2411 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 2412 2413 if (!rb) { 2414 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); 2415 return GL_FALSE; 2416 } 2417 2418 assert (colorBits <= 8); 2419 rb->Format = MESA_FORMAT_RGBA8888; 2420 rb->InternalFormat = GL_RGBA; 2421 2422 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2423 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 2424 } 2425 return GL_TRUE; 2426} 2427 2428 2429/** 2430 * Create/attach software-based renderbuffers to the given framebuffer. 2431 * This is a helper routine for device drivers. Drivers can just as well 2432 * call the individual _mesa_add_*_renderbuffer() routines directly. 2433 */ 2434void 2435_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 2436 GLboolean color, 2437 GLboolean depth, 2438 GLboolean stencil, 2439 GLboolean accum, 2440 GLboolean alpha, 2441 GLboolean aux) 2442{ 2443 GLboolean frontLeft = GL_TRUE; 2444 GLboolean backLeft = fb->Visual.doubleBufferMode; 2445 GLboolean frontRight = fb->Visual.stereoMode; 2446 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 2447 2448 if (color) { 2449 assert(fb->Visual.redBits == fb->Visual.greenBits); 2450 assert(fb->Visual.redBits == fb->Visual.blueBits); 2451 _mesa_add_color_renderbuffers(NULL, fb, 2452 fb->Visual.redBits, 2453 fb->Visual.alphaBits, 2454 frontLeft, backLeft, 2455 frontRight, backRight); 2456 } 2457 2458 if (depth) { 2459 assert(fb->Visual.depthBits > 0); 2460 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 2461 } 2462 2463 if (stencil) { 2464 assert(fb->Visual.stencilBits > 0); 2465 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 2466 } 2467 2468 if (accum) { 2469 assert(fb->Visual.accumRedBits > 0); 2470 assert(fb->Visual.accumGreenBits > 0); 2471 assert(fb->Visual.accumBlueBits > 0); 2472 _mesa_add_accum_renderbuffer(NULL, fb, 2473 fb->Visual.accumRedBits, 2474 fb->Visual.accumGreenBits, 2475 fb->Visual.accumBlueBits, 2476 fb->Visual.accumAlphaBits); 2477 } 2478 2479 if (aux) { 2480 assert(fb->Visual.numAuxBuffers > 0); 2481 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 2482 fb->Visual.numAuxBuffers); 2483 } 2484 2485 if (alpha) { 2486 assert(fb->Visual.alphaBits > 0); 2487 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 2488 frontLeft, backLeft, 2489 frontRight, backRight); 2490 } 2491 2492#if 0 2493 if (multisample) { 2494 /* maybe someday */ 2495 } 2496#endif 2497} 2498 2499 2500/** 2501 * Attach a renderbuffer to a framebuffer. 2502 * \param bufferName one of the BUFFER_x tokens 2503 */ 2504void 2505_mesa_add_renderbuffer(struct gl_framebuffer *fb, 2506 gl_buffer_index bufferName, struct gl_renderbuffer *rb) 2507{ 2508 assert(fb); 2509 assert(rb); 2510 assert(bufferName < BUFFER_COUNT); 2511 2512 /* There should be no previous renderbuffer on this attachment point, 2513 * with the exception of depth/stencil since the same renderbuffer may 2514 * be used for both. 2515 */ 2516 assert(bufferName == BUFFER_DEPTH || 2517 bufferName == BUFFER_STENCIL || 2518 fb->Attachment[bufferName].Renderbuffer == NULL); 2519 2520 /* winsys vs. user-created buffer cross check */ 2521 if (fb->Name) { 2522 assert(rb->Name); 2523 } 2524 else { 2525 assert(!rb->Name); 2526 } 2527 2528 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 2529 fb->Attachment[bufferName].Complete = GL_TRUE; 2530 _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); 2531} 2532 2533 2534/** 2535 * Remove the named renderbuffer from the given framebuffer. 2536 * \param bufferName one of the BUFFER_x tokens 2537 */ 2538void 2539_mesa_remove_renderbuffer(struct gl_framebuffer *fb, 2540 gl_buffer_index bufferName) 2541{ 2542 struct gl_renderbuffer *rb; 2543 2544 assert(bufferName < BUFFER_COUNT); 2545 2546 rb = fb->Attachment[bufferName].Renderbuffer; 2547 if (!rb) 2548 return; 2549 2550 _mesa_reference_renderbuffer(&rb, NULL); 2551 2552 fb->Attachment[bufferName].Renderbuffer = NULL; 2553} 2554 2555 2556/** 2557 * Set *ptr to point to rb. If *ptr points to another renderbuffer, 2558 * dereference that buffer first. The new renderbuffer's refcount will 2559 * be incremented. The old renderbuffer's refcount will be decremented. 2560 * This is normally only called from the _mesa_reference_renderbuffer() macro 2561 * when there's a real pointer change. 2562 */ 2563void 2564_mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr, 2565 struct gl_renderbuffer *rb) 2566{ 2567 if (*ptr) { 2568 /* Unreference the old renderbuffer */ 2569 GLboolean deleteFlag = GL_FALSE; 2570 struct gl_renderbuffer *oldRb = *ptr; 2571 2572 _glthread_LOCK_MUTEX(oldRb->Mutex); 2573 ASSERT(oldRb->RefCount > 0); 2574 oldRb->RefCount--; 2575 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/ 2576 deleteFlag = (oldRb->RefCount == 0); 2577 _glthread_UNLOCK_MUTEX(oldRb->Mutex); 2578 2579 if (deleteFlag) { 2580 oldRb->Delete(oldRb); 2581 } 2582 2583 *ptr = NULL; 2584 } 2585 assert(!*ptr); 2586 2587 if (rb) { 2588 /* reference new renderbuffer */ 2589 _glthread_LOCK_MUTEX(rb->Mutex); 2590 rb->RefCount++; 2591 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/ 2592 _glthread_UNLOCK_MUTEX(rb->Mutex); 2593 *ptr = rb; 2594 } 2595} 2596