renderbuffer.c revision f4fb0be605790c55abd7d66564486e5860721c21
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 rb->Format == MESA_FORMAT_RGBA8888_REV); 725 for (i = 0; i < count; i++) { 726 const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 727 dst[i] = *src; 728 } 729} 730 731 732static void 733put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 734 GLint x, GLint y, const void *values, const GLubyte *mask) 735{ 736 /* treat 4*GLubyte as 1*GLuint */ 737 const GLuint *src = (const GLuint *) values; 738 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 739 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 740 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || 741 rb->Format == MESA_FORMAT_RGBA8888_REV); 742 if (mask) { 743 GLuint i; 744 for (i = 0; i < count; i++) { 745 if (mask[i]) { 746 dst[i] = src[i]; 747 } 748 } 749 } 750 else { 751 memcpy(dst, src, 4 * count * sizeof(GLubyte)); 752 } 753} 754 755 756static void 757put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 758 GLint x, GLint y, const void *values, const GLubyte *mask) 759{ 760 /* Store RGB values in RGBA buffer */ 761 const GLubyte *src = (const GLubyte *) values; 762 GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); 763 GLuint i; 764 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 765 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || 766 rb->Format == MESA_FORMAT_RGBA8888_REV); 767 for (i = 0; i < count; i++) { 768 if (!mask || mask[i]) { 769 dst[i * 4 + 0] = src[i * 3 + 0]; 770 dst[i * 4 + 1] = src[i * 3 + 1]; 771 dst[i * 4 + 2] = src[i * 3 + 2]; 772 dst[i * 4 + 3] = 0xff; 773 } 774 } 775} 776 777 778static void 779put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 780 GLint x, GLint y, const void *value, const GLubyte *mask) 781{ 782 /* treat 4*GLubyte as 1*GLuint */ 783 const GLuint val = *((const GLuint *) value); 784 GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); 785 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 786 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || 787 rb->Format == MESA_FORMAT_RGBA8888_REV); 788 if (!mask && val == 0) { 789 /* common case */ 790 memset(dst, 0, count * 4 * sizeof(GLubyte)); 791 } 792 else { 793 /* general case */ 794 if (mask) { 795 GLuint i; 796 for (i = 0; i < count; i++) { 797 if (mask[i]) { 798 dst[i] = val; 799 } 800 } 801 } 802 else { 803 GLuint i; 804 for (i = 0; i < count; i++) { 805 dst[i] = val; 806 } 807 } 808 } 809} 810 811 812static void 813put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 814 const GLint x[], const GLint y[], const void *values, 815 const GLubyte *mask) 816{ 817 /* treat 4*GLubyte as 1*GLuint */ 818 const GLuint *src = (const GLuint *) values; 819 GLuint i; 820 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 821 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || 822 rb->Format == MESA_FORMAT_RGBA8888_REV); 823 for (i = 0; i < count; i++) { 824 if (!mask || mask[i]) { 825 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 826 *dst = src[i]; 827 } 828 } 829} 830 831 832static void 833put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, 834 GLuint count, const GLint x[], const GLint y[], 835 const void *value, const GLubyte *mask) 836{ 837 /* treat 4*GLubyte as 1*GLuint */ 838 const GLuint val = *((const GLuint *) value); 839 GLuint i; 840 ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 841 ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || 842 rb->Format == MESA_FORMAT_RGBA8888_REV); 843 for (i = 0; i < count; i++) { 844 if (!mask || mask[i]) { 845 GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); 846 *dst = val; 847 } 848 } 849} 850 851 852/********************************************************************** 853 * Functions for buffers of 4 X GLushort (or GLshort) values. 854 * Typically accum buffer. 855 */ 856 857static void 858get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 859 const GLint x[], const GLint y[], void *values) 860{ 861 GLushort *dst = (GLushort *) values; 862 GLuint i; 863 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 864 for (i = 0; i < count; i++) { 865 const GLushort *src 866 = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); 867 dst[i] = *src; 868 } 869} 870 871 872static void 873put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 874 GLint x, GLint y, const void *values, const GLubyte *mask) 875{ 876 const GLushort *src = (const GLushort *) values; 877 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 878 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 879 if (mask) { 880 GLuint i; 881 for (i = 0; i < count; i++) { 882 if (mask[i]) { 883 dst[i * 4 + 0] = src[i * 4 + 0]; 884 dst[i * 4 + 1] = src[i * 4 + 1]; 885 dst[i * 4 + 2] = src[i * 4 + 2]; 886 dst[i * 4 + 3] = src[i * 4 + 3]; 887 } 888 } 889 } 890 else { 891 memcpy(dst, src, 4 * count * sizeof(GLushort)); 892 } 893} 894 895 896static void 897put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 898 GLint x, GLint y, const void *values, const GLubyte *mask) 899{ 900 /* Put RGB values in RGBA buffer */ 901 const GLushort *src = (const GLushort *) values; 902 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 903 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 904 if (mask) { 905 GLuint i; 906 for (i = 0; i < count; i++) { 907 if (mask[i]) { 908 dst[i * 4 + 0] = src[i * 3 + 0]; 909 dst[i * 4 + 1] = src[i * 3 + 1]; 910 dst[i * 4 + 2] = src[i * 3 + 2]; 911 dst[i * 4 + 3] = 0xffff; 912 } 913 } 914 } 915 else { 916 memcpy(dst, src, 4 * count * sizeof(GLushort)); 917 } 918} 919 920 921static void 922put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 923 GLint x, GLint y, const void *value, const GLubyte *mask) 924{ 925 const GLushort val0 = ((const GLushort *) value)[0]; 926 const GLushort val1 = ((const GLushort *) value)[1]; 927 const GLushort val2 = ((const GLushort *) value)[2]; 928 const GLushort val3 = ((const GLushort *) value)[3]; 929 GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); 930 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 931 if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { 932 /* common case for clearing accum buffer */ 933 memset(dst, 0, count * 4 * sizeof(GLushort)); 934 } 935 else { 936 GLuint i; 937 for (i = 0; i < count; i++) { 938 if (!mask || mask[i]) { 939 dst[i * 4 + 0] = val0; 940 dst[i * 4 + 1] = val1; 941 dst[i * 4 + 2] = val2; 942 dst[i * 4 + 3] = val3; 943 } 944 } 945 } 946} 947 948 949static void 950put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 951 const GLint x[], const GLint y[], const void *values, 952 const GLubyte *mask) 953{ 954 const GLushort *src = (const GLushort *) values; 955 GLuint i; 956 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 957 for (i = 0; i < count; i++) { 958 if (!mask || mask[i]) { 959 GLushort *dst = 960 ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); 961 dst[0] = src[i * 4 + 0]; 962 dst[1] = src[i * 4 + 1]; 963 dst[2] = src[i * 4 + 2]; 964 dst[3] = src[i * 4 + 3]; 965 } 966 } 967} 968 969 970static void 971put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, 972 GLuint count, const GLint x[], const GLint y[], 973 const void *value, const GLubyte *mask) 974{ 975 const GLushort val0 = ((const GLushort *) value)[0]; 976 const GLushort val1 = ((const GLushort *) value)[1]; 977 const GLushort val2 = ((const GLushort *) value)[2]; 978 const GLushort val3 = ((const GLushort *) value)[3]; 979 GLuint i; 980 ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); 981 for (i = 0; i < count; i++) { 982 if (!mask || mask[i]) { 983 GLushort *dst = ((GLushort *) rb->Data) + 984 4 * (y[i] * rb->RowStride + x[i]); 985 dst[0] = val0; 986 dst[1] = val1; 987 dst[2] = val2; 988 dst[3] = val3; 989 } 990 } 991} 992 993/********************************************************************** 994 * Functions for MESA_FORMAT_R8. 995 */ 996static void 997get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 998 GLint x, GLint y, void *values) 999{ 1000 const GLubyte *src = rb->GetPointer(ctx, rb, x, y); 1001 GLuint *dst = values; 1002 GLuint i; 1003 1004 for (i = 0; i < count; i++) { 1005 dst[i] = 0xff000000 | src[i]; 1006 } 1007} 1008 1009static void 1010get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1011 const GLint x[], const GLint y[], void *values) 1012{ 1013 GLuint *dst = (GLuint *) values; 1014 GLuint i; 1015 1016 for (i = 0; i < count; i++) { 1017 const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1018 dst[i] = 0xff000000 | *src; 1019 } 1020} 1021 1022/********************************************************************** 1023 * Functions for MESA_FORMAT_RG88. 1024 */ 1025static void 1026get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1027 GLint x, GLint y, void *values) 1028{ 1029 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1030 GLuint *dst = values; 1031 GLuint i; 1032 1033 for (i = 0; i < count; i++) { 1034 dst[i] = 0xff000000 | src[i]; 1035 } 1036} 1037 1038static void 1039get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, 1040 GLuint count, const GLint x[], const GLint y[], void *values) 1041{ 1042 GLuint *dst = (GLuint *) values; 1043 GLuint i; 1044 1045 for (i = 0; i < count; i++) { 1046 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1047 dst[i] = 0xff000000 | *src; 1048 } 1049} 1050 1051/********************************************************************** 1052 * Functions for MESA_FORMAT_R16. 1053 */ 1054static void 1055get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1056 GLint x, GLint y, void *values) 1057{ 1058 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1059 GLushort *dst = values; 1060 GLuint i; 1061 1062 for (i = 0; i < count; i++) { 1063 dst[i * 4 + RCOMP] = src[i]; 1064 dst[i * 4 + GCOMP] = 0; 1065 dst[i * 4 + BCOMP] = 0; 1066 dst[i * 4 + ACOMP] = 0xffff; 1067 } 1068} 1069 1070static void 1071get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1072 const GLint x[], const GLint y[], void *values) 1073{ 1074 GLushort *dst = values; 1075 GLuint i; 1076 1077 for (i = 0; i < count; i++) { 1078 const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1079 dst[i * 4 + RCOMP] = *src; 1080 dst[i * 4 + GCOMP] = 0; 1081 dst[i * 4 + BCOMP] = 0; 1082 dst[i * 4 + ACOMP] = 0xffff; 1083 } 1084} 1085 1086/********************************************************************** 1087 * Functions for MESA_FORMAT_RG1616. 1088 */ 1089static void 1090get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, 1091 GLint x, GLint y, void *values) 1092{ 1093 const GLushort *src = rb->GetPointer(ctx, rb, x, y); 1094 GLushort *dst = values; 1095 GLuint i; 1096 1097 for (i = 0; i < count; i++) { 1098 dst[i * 4 + RCOMP] = src[i * 2]; 1099 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1100 dst[i * 4 + BCOMP] = 0; 1101 dst[i * 4 + ACOMP] = 0xffff; 1102 } 1103} 1104 1105static void 1106get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, 1107 GLuint count, const GLint x[], const GLint y[], void *values) 1108{ 1109 GLushort *dst = values; 1110 GLuint i; 1111 1112 for (i = 0; i < count; i++) { 1113 const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1114 dst[i * 4 + RCOMP] = src[0]; 1115 dst[i * 4 + GCOMP] = src[1]; 1116 dst[i * 4 + BCOMP] = 0; 1117 dst[i * 4 + ACOMP] = 0xffff; 1118 } 1119} 1120 1121/********************************************************************** 1122 * Functions for MESA_FORMAT_INTENSITY_FLOAT32. 1123 */ 1124static void 1125get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1126 GLuint count, GLint x, GLint y, void *values) 1127{ 1128 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1129 GLfloat *dst = values; 1130 GLuint i; 1131 1132 for (i = 0; i < count; i++) { 1133 dst[i * 4 + RCOMP] = 1134 dst[i * 4 + GCOMP] = 1135 dst[i * 4 + BCOMP] = 1136 dst[i * 4 + ACOMP] = src[i]; 1137 } 1138} 1139 1140static void 1141get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1142 GLuint count, const GLint x[], const GLint y[], 1143 void *values) 1144{ 1145 GLfloat *dst = values; 1146 GLuint i; 1147 1148 for (i = 0; i < count; i++) { 1149 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1150 dst[i * 4 + RCOMP] = 1151 dst[i * 4 + GCOMP] = 1152 dst[i * 4 + BCOMP] = 1153 dst[i * 4 + ACOMP] = src[0]; 1154 } 1155} 1156 1157/********************************************************************** 1158 * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. 1159 */ 1160static void 1161get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1162 GLuint count, GLint x, GLint y, void *values) 1163{ 1164 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1165 GLfloat *dst = values; 1166 GLuint i; 1167 1168 for (i = 0; i < count; i++) { 1169 dst[i * 4 + RCOMP] = 1170 dst[i * 4 + GCOMP] = 1171 dst[i * 4 + BCOMP] = src[i]; 1172 dst[i * 4 + ACOMP] = 1.0; 1173 } 1174} 1175 1176static void 1177get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1178 GLuint count, const GLint x[], const GLint y[], 1179 void *values) 1180{ 1181 GLfloat *dst = values; 1182 GLuint i; 1183 1184 for (i = 0; i < count; i++) { 1185 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1186 dst[i * 4 + RCOMP] = 1187 dst[i * 4 + GCOMP] = 1188 dst[i * 4 + BCOMP] = src[0]; 1189 dst[i * 4 + ACOMP] = 1.0; 1190 } 1191} 1192 1193/********************************************************************** 1194 * Functions for MESA_FORMAT_ALPHA_FLOAT32. 1195 */ 1196static void 1197get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1198 GLuint count, GLint x, GLint y, void *values) 1199{ 1200 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1201 GLfloat *dst = values; 1202 GLuint i; 1203 1204 for (i = 0; i < count; i++) { 1205 dst[i * 4 + RCOMP] = 0.0; 1206 dst[i * 4 + GCOMP] = 0.0; 1207 dst[i * 4 + BCOMP] = 0.0; 1208 dst[i * 4 + ACOMP] = src[i]; 1209 } 1210} 1211 1212static void 1213get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1214 GLuint count, const GLint x[], const GLint y[], 1215 void *values) 1216{ 1217 GLfloat *dst = values; 1218 GLuint i; 1219 1220 for (i = 0; i < count; i++) { 1221 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1222 dst[i * 4 + RCOMP] = 0.0; 1223 dst[i * 4 + GCOMP] = 0.0; 1224 dst[i * 4 + BCOMP] = 0.0; 1225 dst[i * 4 + ACOMP] = src[0]; 1226 } 1227} 1228 1229static void 1230put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1231 GLuint count, GLint x, GLint y, 1232 const void *values, const GLubyte *mask) 1233{ 1234 float *dst = rb->GetPointer(ctx, rb, x, y); 1235 const float *src = values; 1236 unsigned int i; 1237 1238 if (mask) { 1239 for (i = 0; i < count; i++) { 1240 if (mask[i]) { 1241 dst[i] = src[i * 4 + ACOMP]; 1242 } 1243 } 1244 } 1245 else { 1246 for (i = 0; i < count; i++) { 1247 dst[i] = src[i * 4 + ACOMP]; 1248 } 1249 } 1250} 1251 1252static void 1253put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1254 GLuint count, GLint x, GLint y, 1255 const void *value, const GLubyte *mask) 1256{ 1257 float *dst = rb->GetPointer(ctx, rb, x, y); 1258 const float *src = value; 1259 unsigned int i; 1260 1261 if (mask) { 1262 for (i = 0; i < count; i++) { 1263 if (mask[i]) { 1264 dst[i] = src[ACOMP]; 1265 } 1266 } 1267 } 1268 else { 1269 for (i = 0; i < count; i++) { 1270 dst[i] = src[ACOMP]; 1271 } 1272 } 1273} 1274 1275static void 1276put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1277 GLuint count, const GLint x[], const GLint y[], 1278 const void *values, const GLubyte *mask) 1279{ 1280 const float *src = values; 1281 unsigned int i; 1282 1283 for (i = 0; i < count; i++) { 1284 if (!mask || mask[i]) { 1285 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1286 1287 *dst = src[i * 4 + ACOMP]; 1288 } 1289 } 1290} 1291 1292static void 1293put_mono_values_a_float32(struct gl_context *ctx, 1294 struct gl_renderbuffer *rb, 1295 GLuint count, const GLint x[], const GLint y[], 1296 const void *value, const GLubyte *mask) 1297{ 1298 const float *src = value; 1299 unsigned int i; 1300 1301 for (i = 0; i < count; i++) { 1302 if (!mask || mask[i]) { 1303 float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); 1304 *dst = src[ACOMP]; 1305 } 1306 } 1307} 1308 1309/********************************************************************** 1310 * Functions for MESA_FORMAT_R_FLOAT32. 1311 */ 1312static void 1313get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1314 GLuint count, GLint x, GLint y, void *values) 1315{ 1316 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1317 GLfloat *dst = values; 1318 GLuint i; 1319 1320 for (i = 0; i < count; i++) { 1321 dst[i * 4 + RCOMP] = src[i]; 1322 dst[i * 4 + GCOMP] = 0.0; 1323 dst[i * 4 + BCOMP] = 0.0; 1324 dst[i * 4 + ACOMP] = 1.0; 1325 } 1326} 1327 1328static void 1329get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1330 GLuint count, const GLint x[], const GLint y[], 1331 void *values) 1332{ 1333 GLfloat *dst = values; 1334 GLuint i; 1335 1336 for (i = 0; i < count; i++) { 1337 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1338 dst[i * 4 + RCOMP] = src[0]; 1339 dst[i * 4 + GCOMP] = 0.0; 1340 dst[i * 4 + BCOMP] = 0.0; 1341 dst[i * 4 + ACOMP] = 1.0; 1342 } 1343} 1344 1345/********************************************************************** 1346 * Functions for MESA_FORMAT_RG_FLOAT32. 1347 */ 1348static void 1349get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1350 GLuint count, GLint x, GLint y, void *values) 1351{ 1352 const GLfloat *src = rb->GetPointer(ctx, rb, x, y); 1353 GLfloat *dst = values; 1354 GLuint i; 1355 1356 for (i = 0; i < count; i++) { 1357 dst[i * 4 + RCOMP] = src[i * 2 + 0]; 1358 dst[i * 4 + GCOMP] = src[i * 2 + 1]; 1359 dst[i * 4 + BCOMP] = 0.0; 1360 dst[i * 4 + ACOMP] = 1.0; 1361 } 1362} 1363 1364static void 1365get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, 1366 GLuint count, const GLint x[], const GLint y[], 1367 void *values) 1368{ 1369 GLfloat *dst = values; 1370 GLuint i; 1371 1372 for (i = 0; i < count; i++) { 1373 const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); 1374 dst[i * 4 + RCOMP] = src[0]; 1375 dst[i * 4 + GCOMP] = src[1]; 1376 dst[i * 4 + BCOMP] = 0.0; 1377 dst[i * 4 + ACOMP] = 1.0; 1378 } 1379} 1380 1381/** 1382 * This is the default software fallback for gl_renderbuffer's span 1383 * access functions. 1384 * 1385 * The assumptions are that rb->Data will be a pointer to (0,0), that pixels 1386 * are packed in the type of rb->Format, and that subsequent rows appear 1387 * rb->RowStride pixels later. 1388 */ 1389void 1390_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb) 1391{ 1392 rb->GetPointer = get_pointer_generic; 1393 rb->GetRow = get_row_generic; 1394 1395 switch (rb->Format) { 1396 case MESA_FORMAT_RGB888: 1397 rb->DataType = GL_UNSIGNED_BYTE; 1398 rb->GetPointer = get_pointer_ubyte3; 1399 rb->GetRow = get_row_ubyte3; 1400 rb->GetValues = get_values_ubyte3; 1401 rb->PutRow = put_row_ubyte3; 1402 rb->PutRowRGB = put_row_rgb_ubyte3; 1403 rb->PutMonoRow = put_mono_row_ubyte3; 1404 rb->PutValues = put_values_ubyte3; 1405 rb->PutMonoValues = put_mono_values_ubyte3; 1406 break; 1407 1408 case MESA_FORMAT_RGBA8888: 1409 case MESA_FORMAT_RGBA8888_REV: 1410 rb->DataType = GL_UNSIGNED_BYTE; 1411 rb->GetValues = get_values_ubyte4; 1412 rb->PutRow = put_row_ubyte4; 1413 rb->PutRowRGB = put_row_rgb_ubyte4; 1414 rb->PutMonoRow = put_mono_row_ubyte4; 1415 rb->PutValues = put_values_ubyte4; 1416 rb->PutMonoValues = put_mono_values_ubyte4; 1417 break; 1418 1419 case MESA_FORMAT_R8: 1420 rb->DataType = GL_UNSIGNED_BYTE; 1421 rb->GetValues = get_values_r8; 1422 rb->GetRow = get_row_r8; 1423 rb->PutRow = put_row_generic; 1424 rb->PutRowRGB = put_row_generic; 1425 rb->PutMonoRow = put_mono_row_generic; 1426 rb->PutValues = put_values_generic; 1427 rb->PutMonoValues = put_mono_values_generic; 1428 break; 1429 1430 case MESA_FORMAT_RG88: 1431 rb->DataType = GL_UNSIGNED_BYTE; 1432 rb->GetValues = get_values_rg88; 1433 rb->GetRow = get_row_rg88; 1434 rb->PutRow = put_row_generic; 1435 rb->PutRowRGB = put_row_generic; 1436 rb->PutMonoRow = put_mono_row_generic; 1437 rb->PutValues = put_values_generic; 1438 rb->PutMonoValues = put_mono_values_generic; 1439 break; 1440 1441 case MESA_FORMAT_R16: 1442 rb->DataType = GL_UNSIGNED_SHORT; 1443 rb->GetValues = get_values_r16; 1444 rb->GetRow = get_row_r16; 1445 rb->PutRow = put_row_generic; 1446 rb->PutRowRGB = put_row_generic; 1447 rb->PutMonoRow = put_mono_row_generic; 1448 rb->PutValues = put_values_generic; 1449 rb->PutMonoValues = put_mono_values_generic; 1450 break; 1451 1452 case MESA_FORMAT_RG1616: 1453 rb->DataType = GL_UNSIGNED_SHORT; 1454 rb->GetValues = get_values_rg1616; 1455 rb->GetRow = get_row_rg1616; 1456 rb->PutRow = put_row_generic; 1457 rb->PutRowRGB = put_row_generic; 1458 rb->PutMonoRow = put_mono_row_generic; 1459 rb->PutValues = put_values_generic; 1460 rb->PutMonoValues = put_mono_values_generic; 1461 break; 1462 1463 case MESA_FORMAT_SIGNED_RGBA_16: 1464 rb->DataType = GL_SHORT; 1465 rb->GetValues = get_values_ushort4; 1466 rb->PutRow = put_row_ushort4; 1467 rb->PutRowRGB = put_row_rgb_ushort4; 1468 rb->PutMonoRow = put_mono_row_ushort4; 1469 rb->PutValues = put_values_ushort4; 1470 rb->PutMonoValues = put_mono_values_ushort4; 1471 break; 1472 1473#if 0 1474 case MESA_FORMAT_A8: 1475 rb->DataType = GL_UNSIGNED_BYTE; 1476 rb->GetValues = get_values_alpha8; 1477 rb->PutRow = put_row_alpha8; 1478 rb->PutRowRGB = NULL; 1479 rb->PutMonoRow = put_mono_row_alpha8; 1480 rb->PutValues = put_values_alpha8; 1481 rb->PutMonoValues = put_mono_values_alpha8; 1482 break; 1483#endif 1484 1485 case MESA_FORMAT_S8: 1486 rb->DataType = GL_UNSIGNED_BYTE; 1487 rb->GetValues = get_values_ubyte; 1488 rb->PutRow = put_row_ubyte; 1489 rb->PutRowRGB = NULL; 1490 rb->PutMonoRow = put_mono_row_ubyte; 1491 rb->PutValues = put_values_ubyte; 1492 rb->PutMonoValues = put_mono_values_ubyte; 1493 break; 1494 1495 case MESA_FORMAT_Z16: 1496 rb->DataType = GL_UNSIGNED_SHORT; 1497 rb->GetValues = get_values_ushort; 1498 rb->PutRow = put_row_ushort; 1499 rb->PutRowRGB = NULL; 1500 rb->PutMonoRow = put_mono_row_ushort; 1501 rb->PutValues = put_values_ushort; 1502 rb->PutMonoValues = put_mono_values_ushort; 1503 break; 1504 1505 case MESA_FORMAT_Z32: 1506 case MESA_FORMAT_X8_Z24: 1507 case MESA_FORMAT_Z24_X8: 1508 rb->DataType = GL_UNSIGNED_INT; 1509 rb->GetValues = get_values_uint; 1510 rb->PutRow = put_row_uint; 1511 rb->PutRowRGB = NULL; 1512 rb->PutMonoRow = put_mono_row_uint; 1513 rb->PutValues = put_values_uint; 1514 rb->PutMonoValues = put_mono_values_uint; 1515 break; 1516 1517 case MESA_FORMAT_Z24_S8: 1518 case MESA_FORMAT_S8_Z24: 1519 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 1520 rb->GetValues = get_values_uint; 1521 rb->PutRow = put_row_uint; 1522 rb->PutRowRGB = NULL; 1523 rb->PutMonoRow = put_mono_row_uint; 1524 rb->PutValues = put_values_uint; 1525 rb->PutMonoValues = put_mono_values_uint; 1526 break; 1527 1528 case MESA_FORMAT_RGBA_FLOAT32: 1529 rb->GetRow = get_row_generic; 1530 rb->GetValues = get_values_generic; 1531 rb->PutRow = put_row_generic; 1532 rb->PutRowRGB = NULL; 1533 rb->PutMonoRow = put_mono_row_generic; 1534 rb->PutValues = put_values_generic; 1535 rb->PutMonoValues = put_mono_values_generic; 1536 break; 1537 1538 case MESA_FORMAT_INTENSITY_FLOAT32: 1539 rb->GetRow = get_row_i_float32; 1540 rb->GetValues = get_values_i_float32; 1541 rb->PutRow = put_row_generic; 1542 rb->PutRowRGB = NULL; 1543 rb->PutMonoRow = put_mono_row_generic; 1544 rb->PutValues = put_values_generic; 1545 rb->PutMonoValues = put_mono_values_generic; 1546 break; 1547 1548 case MESA_FORMAT_LUMINANCE_FLOAT32: 1549 rb->GetRow = get_row_l_float32; 1550 rb->GetValues = get_values_l_float32; 1551 rb->PutRow = put_row_generic; 1552 rb->PutRowRGB = NULL; 1553 rb->PutMonoRow = put_mono_row_generic; 1554 rb->PutValues = put_values_generic; 1555 rb->PutMonoValues = put_mono_values_generic; 1556 break; 1557 1558 case MESA_FORMAT_ALPHA_FLOAT32: 1559 rb->GetRow = get_row_a_float32; 1560 rb->GetValues = get_values_a_float32; 1561 rb->PutRow = put_row_a_float32; 1562 rb->PutRowRGB = NULL; 1563 rb->PutMonoRow = put_mono_row_a_float32; 1564 rb->PutValues = put_values_a_float32; 1565 rb->PutMonoValues = put_mono_values_a_float32; 1566 break; 1567 1568 case MESA_FORMAT_RG_FLOAT32: 1569 rb->GetRow = get_row_rg_float32; 1570 rb->GetValues = get_values_rg_float32; 1571 rb->PutRow = put_row_generic; 1572 rb->PutRowRGB = NULL; 1573 rb->PutMonoRow = put_mono_row_generic; 1574 rb->PutValues = put_values_generic; 1575 rb->PutMonoValues = put_mono_values_generic; 1576 break; 1577 1578 case MESA_FORMAT_R_FLOAT32: 1579 rb->GetRow = get_row_r_float32; 1580 rb->GetValues = get_values_r_float32; 1581 rb->PutRow = put_row_generic; 1582 rb->PutRowRGB = NULL; 1583 rb->PutMonoRow = put_mono_row_generic; 1584 rb->PutValues = put_values_generic; 1585 rb->PutMonoValues = put_mono_values_generic; 1586 break; 1587 1588 default: 1589 break; 1590 } 1591} 1592 1593/** 1594 * This is a software fallback for the gl_renderbuffer->AllocStorage 1595 * function. 1596 * Device drivers will typically override this function for the buffers 1597 * which it manages (typically color buffers, Z and stencil). 1598 * Other buffers (like software accumulation and aux buffers) which the driver 1599 * doesn't manage can be handled with this function. 1600 * 1601 * This one multi-purpose function can allocate stencil, depth, accum, color 1602 * or color-index buffers! 1603 * 1604 * This function also plugs in the appropriate GetPointer, Get/PutRow and 1605 * Get/PutValues functions. 1606 */ 1607GLboolean 1608_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, 1609 GLenum internalFormat, 1610 GLuint width, GLuint height) 1611{ 1612 switch (internalFormat) { 1613 case GL_RGB: 1614 case GL_R3_G3_B2: 1615 case GL_RGB4: 1616 case GL_RGB5: 1617 case GL_RGB8: 1618 case GL_RGB10: 1619 case GL_RGB12: 1620 case GL_RGB16: 1621 rb->Format = MESA_FORMAT_RGB888; 1622 break; 1623 case GL_RGBA: 1624 case GL_RGBA2: 1625 case GL_RGBA4: 1626 case GL_RGB5_A1: 1627 case GL_RGBA8: 1628#if 1 1629 case GL_RGB10_A2: 1630 case GL_RGBA12: 1631#endif 1632 if (_mesa_little_endian()) 1633 rb->Format = MESA_FORMAT_RGBA8888_REV; 1634 else 1635 rb->Format = MESA_FORMAT_RGBA8888; 1636 break; 1637 case GL_RGBA16: 1638 case GL_RGBA16_SNORM: 1639 /* for accum buffer */ 1640 rb->Format = MESA_FORMAT_SIGNED_RGBA_16; 1641 break; 1642#if 0 1643 case GL_ALPHA8: 1644 rb->Format = MESA_FORMAT_A8; 1645 break; 1646#endif 1647 case GL_STENCIL_INDEX: 1648 case GL_STENCIL_INDEX1_EXT: 1649 case GL_STENCIL_INDEX4_EXT: 1650 case GL_STENCIL_INDEX8_EXT: 1651 case GL_STENCIL_INDEX16_EXT: 1652 rb->Format = MESA_FORMAT_S8; 1653 break; 1654 case GL_DEPTH_COMPONENT: 1655 case GL_DEPTH_COMPONENT16: 1656 rb->Format = MESA_FORMAT_Z16; 1657 break; 1658 case GL_DEPTH_COMPONENT24: 1659 rb->Format = MESA_FORMAT_X8_Z24; 1660 break; 1661 case GL_DEPTH_COMPONENT32: 1662 rb->Format = MESA_FORMAT_Z32; 1663 break; 1664 case GL_DEPTH_STENCIL_EXT: 1665 case GL_DEPTH24_STENCIL8_EXT: 1666 rb->Format = MESA_FORMAT_Z24_S8; 1667 break; 1668 default: 1669 /* unsupported format */ 1670 return GL_FALSE; 1671 } 1672 1673 _mesa_set_renderbuffer_accessors(rb); 1674 1675 ASSERT(rb->DataType); 1676 ASSERT(rb->GetPointer); 1677 ASSERT(rb->GetRow); 1678 ASSERT(rb->GetValues); 1679 ASSERT(rb->PutRow); 1680 ASSERT(rb->PutMonoRow); 1681 ASSERT(rb->PutValues); 1682 ASSERT(rb->PutMonoValues); 1683 1684 /* free old buffer storage */ 1685 if (rb->Data) { 1686 free(rb->Data); 1687 rb->Data = NULL; 1688 } 1689 1690 rb->RowStride = width; 1691 1692 if (width > 0 && height > 0) { 1693 /* allocate new buffer storage */ 1694 rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); 1695 1696 if (rb->Data == NULL) { 1697 rb->Width = 0; 1698 rb->Height = 0; 1699 rb->RowStride = 0; 1700 _mesa_error(ctx, GL_OUT_OF_MEMORY, 1701 "software renderbuffer allocation (%d x %d x %d)", 1702 width, height, _mesa_get_format_bytes(rb->Format)); 1703 return GL_FALSE; 1704 } 1705 } 1706 1707 rb->Width = width; 1708 rb->Height = height; 1709 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 1710 1711 if (rb->Name == 0 && 1712 internalFormat == GL_RGBA16_SNORM && 1713 rb->_BaseFormat == 0) { 1714 /* NOTE: This is a special case just for accumulation buffers. 1715 * This is a very limited use case- there's no snorm texturing or 1716 * rendering going on. 1717 */ 1718 rb->_BaseFormat = GL_RGBA; 1719 } 1720 else { 1721 /* the internalFormat should have been error checked long ago */ 1722 ASSERT(rb->_BaseFormat); 1723 } 1724 1725 return GL_TRUE; 1726} 1727 1728 1729void 1730_mesa_map_soft_renderbuffer(struct gl_context *ctx, 1731 struct gl_renderbuffer *rb, 1732 GLuint x, GLuint y, GLuint w, GLuint h, 1733 GLbitfield mode, 1734 GLubyte **out_map, 1735 GLint *out_stride) 1736{ 1737 GLubyte *map = rb->Data; 1738 int cpp = _mesa_get_format_bytes(rb->Format); 1739 int stride = rb->RowStride * cpp; 1740 1741 ASSERT(rb->Data); 1742 1743 map += y * stride; 1744 map += x * cpp; 1745 1746 *out_map = map; 1747 *out_stride = stride; 1748} 1749 1750void 1751_mesa_unmap_soft_renderbuffer(struct gl_context *ctx, 1752 struct gl_renderbuffer *rb) 1753{ 1754} 1755 1756 1757/**********************************************************************/ 1758/**********************************************************************/ 1759/**********************************************************************/ 1760 1761 1762/** 1763 * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha 1764 * buffer wrapper around an existing RGB renderbuffer (hw or sw). 1765 * 1766 * When PutRow is called (for example), we store the alpha values in 1767 * this buffer, then pass on the PutRow call to the wrapped RGB 1768 * buffer. 1769 */ 1770 1771 1772static GLboolean 1773alloc_storage_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1774 GLenum internalFormat, GLuint width, GLuint height) 1775{ 1776 ASSERT(arb != arb->Wrapped); 1777 ASSERT(arb->Format == MESA_FORMAT_A8); 1778 1779 /* first, pass the call to the wrapped RGB buffer */ 1780 if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat, 1781 width, height)) { 1782 return GL_FALSE; 1783 } 1784 1785 /* next, resize my alpha buffer */ 1786 if (arb->Data) { 1787 free(arb->Data); 1788 } 1789 1790 arb->Data = malloc(width * height * sizeof(GLubyte)); 1791 if (arb->Data == NULL) { 1792 arb->Width = 0; 1793 arb->Height = 0; 1794 _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); 1795 return GL_FALSE; 1796 } 1797 1798 arb->Width = width; 1799 arb->Height = height; 1800 arb->RowStride = width; 1801 1802 return GL_TRUE; 1803} 1804 1805 1806/** 1807 * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. 1808 */ 1809static void 1810delete_renderbuffer_alpha8(struct gl_renderbuffer *arb) 1811{ 1812 if (arb->Data) { 1813 free(arb->Data); 1814 } 1815 ASSERT(arb->Wrapped); 1816 ASSERT(arb != arb->Wrapped); 1817 arb->Wrapped->Delete(arb->Wrapped); 1818 arb->Wrapped = NULL; 1819 free(arb); 1820} 1821 1822 1823static void * 1824get_pointer_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1825 GLint x, GLint y) 1826{ 1827 return NULL; /* don't allow direct access! */ 1828} 1829 1830 1831static void 1832get_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1833 GLint x, GLint y, void *values) 1834{ 1835 /* NOTE: 'values' is RGBA format! */ 1836 const GLubyte *src = (const GLubyte *) arb->Data + y * arb->RowStride + x; 1837 GLubyte *dst = (GLubyte *) values; 1838 GLuint i; 1839 ASSERT(arb != arb->Wrapped); 1840 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1841 /* first, pass the call to the wrapped RGB buffer */ 1842 arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values); 1843 /* second, fill in alpha values from this buffer! */ 1844 for (i = 0; i < count; i++) { 1845 dst[i * 4 + 3] = src[i]; 1846 } 1847} 1848 1849 1850static void 1851get_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1852 const GLint x[], const GLint y[], void *values) 1853{ 1854 GLubyte *dst = (GLubyte *) values; 1855 GLuint i; 1856 ASSERT(arb != arb->Wrapped); 1857 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1858 /* first, pass the call to the wrapped RGB buffer */ 1859 arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values); 1860 /* second, fill in alpha values from this buffer! */ 1861 for (i = 0; i < count; i++) { 1862 const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1863 dst[i * 4 + 3] = *src; 1864 } 1865} 1866 1867 1868static void 1869put_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1870 GLint x, GLint y, const void *values, const GLubyte *mask) 1871{ 1872 const GLubyte *src = (const GLubyte *) values; 1873 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1874 GLuint i; 1875 ASSERT(arb != arb->Wrapped); 1876 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1877 /* first, pass the call to the wrapped RGB buffer */ 1878 arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask); 1879 /* second, store alpha in our buffer */ 1880 for (i = 0; i < count; i++) { 1881 if (!mask || mask[i]) { 1882 dst[i] = src[i * 4 + 3]; 1883 } 1884 } 1885} 1886 1887 1888static void 1889put_row_rgb_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1890 GLint x, GLint y, const void *values, const GLubyte *mask) 1891{ 1892 const GLubyte *src = (const GLubyte *) values; 1893 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1894 GLuint i; 1895 ASSERT(arb != arb->Wrapped); 1896 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1897 /* first, pass the call to the wrapped RGB buffer */ 1898 arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask); 1899 /* second, store alpha in our buffer */ 1900 for (i = 0; i < count; i++) { 1901 if (!mask || mask[i]) { 1902 dst[i] = src[i * 4 + 3]; 1903 } 1904 } 1905} 1906 1907 1908static void 1909put_mono_row_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1910 GLint x, GLint y, const void *value, const GLubyte *mask) 1911{ 1912 const GLubyte val = ((const GLubyte *) value)[3]; 1913 GLubyte *dst = (GLubyte *) arb->Data + y * arb->RowStride + x; 1914 ASSERT(arb != arb->Wrapped); 1915 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1916 /* first, pass the call to the wrapped RGB buffer */ 1917 arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask); 1918 /* second, store alpha in our buffer */ 1919 if (mask) { 1920 GLuint i; 1921 for (i = 0; i < count; i++) { 1922 if (mask[i]) { 1923 dst[i] = val; 1924 } 1925 } 1926 } 1927 else { 1928 memset(dst, val, count); 1929 } 1930} 1931 1932 1933static void 1934put_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, GLuint count, 1935 const GLint x[], const GLint y[], 1936 const void *values, const GLubyte *mask) 1937{ 1938 const GLubyte *src = (const GLubyte *) values; 1939 GLuint i; 1940 ASSERT(arb != arb->Wrapped); 1941 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1942 /* first, pass the call to the wrapped RGB buffer */ 1943 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask); 1944 /* second, store alpha in our buffer */ 1945 for (i = 0; i < count; i++) { 1946 if (!mask || mask[i]) { 1947 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1948 *dst = src[i * 4 + 3]; 1949 } 1950 } 1951} 1952 1953 1954static void 1955put_mono_values_alpha8(struct gl_context *ctx, struct gl_renderbuffer *arb, 1956 GLuint count, const GLint x[], const GLint y[], 1957 const void *value, const GLubyte *mask) 1958{ 1959 const GLubyte val = ((const GLubyte *) value)[3]; 1960 GLuint i; 1961 ASSERT(arb != arb->Wrapped); 1962 ASSERT(arb->DataType == GL_UNSIGNED_BYTE); 1963 /* first, pass the call to the wrapped RGB buffer */ 1964 arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask); 1965 /* second, store alpha in our buffer */ 1966 for (i = 0; i < count; i++) { 1967 if (!mask || mask[i]) { 1968 GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->RowStride + x[i]; 1969 *dst = val; 1970 } 1971 } 1972} 1973 1974 1975static void 1976copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src) 1977{ 1978 ASSERT(dst->Format == MESA_FORMAT_A8); 1979 ASSERT(src->Format == MESA_FORMAT_A8); 1980 ASSERT(dst->Width == src->Width); 1981 ASSERT(dst->Height == src->Height); 1982 ASSERT(dst->RowStride == src->RowStride); 1983 1984 memcpy(dst->Data, src->Data, dst->RowStride * dst->Height * sizeof(GLubyte)); 1985} 1986 1987 1988/**********************************************************************/ 1989/**********************************************************************/ 1990/**********************************************************************/ 1991 1992 1993/** 1994 * Default GetPointer routine. Always return NULL to indicate that 1995 * direct buffer access is not supported. 1996 */ 1997static void * 1998nop_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) 1999{ 2000 return NULL; 2001} 2002 2003 2004/** 2005 * Initialize the fields of a gl_renderbuffer to default values. 2006 */ 2007void 2008_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) 2009{ 2010 _glthread_INIT_MUTEX(rb->Mutex); 2011 2012 rb->ClassID = 0; 2013 rb->Name = name; 2014 rb->RefCount = 0; 2015 rb->Delete = _mesa_delete_renderbuffer; 2016 2017 /* The rest of these should be set later by the caller of this function or 2018 * the AllocStorage method: 2019 */ 2020 rb->AllocStorage = NULL; 2021 2022 rb->Width = 0; 2023 rb->Height = 0; 2024 rb->InternalFormat = GL_RGBA; 2025 rb->Format = MESA_FORMAT_NONE; 2026 2027 rb->DataType = GL_NONE; 2028 rb->Data = NULL; 2029 2030 /* Point back to ourself so that we don't have to check for Wrapped==NULL 2031 * all over the drivers. 2032 */ 2033 rb->Wrapped = rb; 2034 2035 rb->GetPointer = nop_get_pointer; 2036 rb->GetRow = NULL; 2037 rb->GetValues = NULL; 2038 rb->PutRow = NULL; 2039 rb->PutRowRGB = NULL; 2040 rb->PutMonoRow = NULL; 2041 rb->PutValues = NULL; 2042 rb->PutMonoValues = NULL; 2043} 2044 2045 2046/** 2047 * Allocate a new gl_renderbuffer object. This can be used for user-created 2048 * renderbuffers or window-system renderbuffers. 2049 */ 2050struct gl_renderbuffer * 2051_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name) 2052{ 2053 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); 2054 if (rb) { 2055 _mesa_init_renderbuffer(rb, name); 2056 } 2057 return rb; 2058} 2059 2060 2061/** 2062 * Delete a gl_framebuffer. 2063 * This is the default function for renderbuffer->Delete(). 2064 */ 2065void 2066_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) 2067{ 2068 if (rb->Data) { 2069 free(rb->Data); 2070 } 2071 free(rb); 2072} 2073 2074 2075/** 2076 * Allocate a software-based renderbuffer. This is called via the 2077 * ctx->Driver.NewRenderbuffer() function when the user creates a new 2078 * renderbuffer. 2079 * This would not be used for hardware-based renderbuffers. 2080 */ 2081struct gl_renderbuffer * 2082_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) 2083{ 2084 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); 2085 if (rb) { 2086 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2087 /* Normally, one would setup the PutRow, GetRow, etc functions here. 2088 * But we're doing that in the _mesa_soft_renderbuffer_storage() function 2089 * instead. 2090 */ 2091 } 2092 return rb; 2093} 2094 2095 2096/** 2097 * Add software-based color renderbuffers to the given framebuffer. 2098 * This is a helper routine for device drivers when creating a 2099 * window system framebuffer (not a user-created render/framebuffer). 2100 * Once this function is called, you can basically forget about this 2101 * renderbuffer; core Mesa will handle all the buffer management and 2102 * rendering! 2103 */ 2104GLboolean 2105_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2106 GLuint rgbBits, GLuint alphaBits, 2107 GLboolean frontLeft, GLboolean backLeft, 2108 GLboolean frontRight, GLboolean backRight) 2109{ 2110 gl_buffer_index b; 2111 2112 if (rgbBits > 16 || alphaBits > 16) { 2113 _mesa_problem(ctx, 2114 "Unsupported bit depth in _mesa_add_color_renderbuffers"); 2115 return GL_FALSE; 2116 } 2117 2118 assert(MAX_COLOR_ATTACHMENTS >= 4); 2119 2120 for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { 2121 struct gl_renderbuffer *rb; 2122 2123 if (b == BUFFER_FRONT_LEFT && !frontLeft) 2124 continue; 2125 else if (b == BUFFER_BACK_LEFT && !backLeft) 2126 continue; 2127 else if (b == BUFFER_FRONT_RIGHT && !frontRight) 2128 continue; 2129 else if (b == BUFFER_BACK_RIGHT && !backRight) 2130 continue; 2131 2132 assert(fb->Attachment[b].Renderbuffer == NULL); 2133 2134 rb = _mesa_new_renderbuffer(ctx, 0); 2135 if (!rb) { 2136 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); 2137 return GL_FALSE; 2138 } 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->InternalFormat = GL_DEPTH_COMPONENT16; 2288 } 2289 else if (depthBits <= 24) { 2290 rb->InternalFormat = GL_DEPTH_COMPONENT24; 2291 } 2292 else { 2293 rb->InternalFormat = GL_DEPTH_COMPONENT32; 2294 } 2295 2296 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2297 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 2298 2299 return GL_TRUE; 2300} 2301 2302 2303/** 2304 * Add a software-based stencil renderbuffer to the given framebuffer. 2305 * This is a helper routine for device drivers when creating a 2306 * window system framebuffer (not a user-created render/framebuffer). 2307 * Once this function is called, you can basically forget about this 2308 * renderbuffer; core Mesa will handle all the buffer management and 2309 * rendering! 2310 */ 2311GLboolean 2312_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2313 GLuint stencilBits) 2314{ 2315 struct gl_renderbuffer *rb; 2316 2317 if (stencilBits > 16) { 2318 _mesa_problem(ctx, 2319 "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); 2320 return GL_FALSE; 2321 } 2322 2323 assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); 2324 2325 rb = _mesa_new_renderbuffer(ctx, 0); 2326 if (!rb) { 2327 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); 2328 return GL_FALSE; 2329 } 2330 2331 assert(stencilBits <= 8); 2332 rb->InternalFormat = GL_STENCIL_INDEX8; 2333 2334 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2335 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); 2336 2337 return GL_TRUE; 2338} 2339 2340 2341/** 2342 * Add a software-based accumulation renderbuffer to the given framebuffer. 2343 * This is a helper routine for device drivers when creating a 2344 * window system framebuffer (not a user-created render/framebuffer). 2345 * Once this function is called, you can basically forget about this 2346 * renderbuffer; core Mesa will handle all the buffer management and 2347 * rendering! 2348 */ 2349GLboolean 2350_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, 2351 GLuint redBits, GLuint greenBits, 2352 GLuint blueBits, GLuint alphaBits) 2353{ 2354 struct gl_renderbuffer *rb; 2355 2356 if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { 2357 _mesa_problem(ctx, 2358 "Unsupported accumBits in _mesa_add_accum_renderbuffer"); 2359 return GL_FALSE; 2360 } 2361 2362 assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); 2363 2364 rb = _mesa_new_renderbuffer(ctx, 0); 2365 if (!rb) { 2366 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); 2367 return GL_FALSE; 2368 } 2369 2370 rb->InternalFormat = GL_RGBA16_SNORM; 2371 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2372 _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); 2373 2374 return GL_TRUE; 2375} 2376 2377 2378 2379/** 2380 * Add a software-based aux renderbuffer to the given framebuffer. 2381 * This is a helper routine for device drivers when creating a 2382 * window system framebuffer (not a user-created render/framebuffer). 2383 * Once this function is called, you can basically forget about this 2384 * renderbuffer; core Mesa will handle all the buffer management and 2385 * rendering! 2386 * 2387 * NOTE: color-index aux buffers not supported. 2388 */ 2389GLboolean 2390_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, 2391 GLuint colorBits, GLuint numBuffers) 2392{ 2393 GLuint i; 2394 2395 if (colorBits > 16) { 2396 _mesa_problem(ctx, 2397 "Unsupported accumBits in _mesa_add_aux_renderbuffers"); 2398 return GL_FALSE; 2399 } 2400 2401 assert(numBuffers <= MAX_AUX_BUFFERS); 2402 2403 for (i = 0; i < numBuffers; i++) { 2404 struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); 2405 2406 assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); 2407 2408 if (!rb) { 2409 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); 2410 return GL_FALSE; 2411 } 2412 2413 assert (colorBits <= 8); 2414 rb->InternalFormat = GL_RGBA; 2415 2416 rb->AllocStorage = _mesa_soft_renderbuffer_storage; 2417 _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); 2418 } 2419 return GL_TRUE; 2420} 2421 2422 2423/** 2424 * Create/attach software-based renderbuffers to the given framebuffer. 2425 * This is a helper routine for device drivers. Drivers can just as well 2426 * call the individual _mesa_add_*_renderbuffer() routines directly. 2427 */ 2428void 2429_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, 2430 GLboolean color, 2431 GLboolean depth, 2432 GLboolean stencil, 2433 GLboolean accum, 2434 GLboolean alpha, 2435 GLboolean aux) 2436{ 2437 GLboolean frontLeft = GL_TRUE; 2438 GLboolean backLeft = fb->Visual.doubleBufferMode; 2439 GLboolean frontRight = fb->Visual.stereoMode; 2440 GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; 2441 2442 if (color) { 2443 assert(fb->Visual.redBits == fb->Visual.greenBits); 2444 assert(fb->Visual.redBits == fb->Visual.blueBits); 2445 _mesa_add_color_renderbuffers(NULL, fb, 2446 fb->Visual.redBits, 2447 fb->Visual.alphaBits, 2448 frontLeft, backLeft, 2449 frontRight, backRight); 2450 } 2451 2452 if (depth) { 2453 assert(fb->Visual.depthBits > 0); 2454 _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); 2455 } 2456 2457 if (stencil) { 2458 assert(fb->Visual.stencilBits > 0); 2459 _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); 2460 } 2461 2462 if (accum) { 2463 assert(fb->Visual.accumRedBits > 0); 2464 assert(fb->Visual.accumGreenBits > 0); 2465 assert(fb->Visual.accumBlueBits > 0); 2466 _mesa_add_accum_renderbuffer(NULL, fb, 2467 fb->Visual.accumRedBits, 2468 fb->Visual.accumGreenBits, 2469 fb->Visual.accumBlueBits, 2470 fb->Visual.accumAlphaBits); 2471 } 2472 2473 if (aux) { 2474 assert(fb->Visual.numAuxBuffers > 0); 2475 _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, 2476 fb->Visual.numAuxBuffers); 2477 } 2478 2479 if (alpha) { 2480 assert(fb->Visual.alphaBits > 0); 2481 _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, 2482 frontLeft, backLeft, 2483 frontRight, backRight); 2484 } 2485 2486#if 0 2487 if (multisample) { 2488 /* maybe someday */ 2489 } 2490#endif 2491} 2492 2493 2494/** 2495 * Attach a renderbuffer to a framebuffer. 2496 * \param bufferName one of the BUFFER_x tokens 2497 */ 2498void 2499_mesa_add_renderbuffer(struct gl_framebuffer *fb, 2500 gl_buffer_index bufferName, struct gl_renderbuffer *rb) 2501{ 2502 assert(fb); 2503 assert(rb); 2504 assert(bufferName < BUFFER_COUNT); 2505 2506 /* There should be no previous renderbuffer on this attachment point, 2507 * with the exception of depth/stencil since the same renderbuffer may 2508 * be used for both. 2509 */ 2510 assert(bufferName == BUFFER_DEPTH || 2511 bufferName == BUFFER_STENCIL || 2512 fb->Attachment[bufferName].Renderbuffer == NULL); 2513 2514 /* winsys vs. user-created buffer cross check */ 2515 if (fb->Name) { 2516 assert(rb->Name); 2517 } 2518 else { 2519 assert(!rb->Name); 2520 } 2521 2522 fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; 2523 fb->Attachment[bufferName].Complete = GL_TRUE; 2524 _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); 2525} 2526 2527 2528/** 2529 * Remove the named renderbuffer from the given framebuffer. 2530 * \param bufferName one of the BUFFER_x tokens 2531 */ 2532void 2533_mesa_remove_renderbuffer(struct gl_framebuffer *fb, 2534 gl_buffer_index bufferName) 2535{ 2536 struct gl_renderbuffer *rb; 2537 2538 assert(bufferName < BUFFER_COUNT); 2539 2540 rb = fb->Attachment[bufferName].Renderbuffer; 2541 if (!rb) 2542 return; 2543 2544 _mesa_reference_renderbuffer(&rb, NULL); 2545 2546 fb->Attachment[bufferName].Renderbuffer = NULL; 2547} 2548 2549 2550/** 2551 * Set *ptr to point to rb. If *ptr points to another renderbuffer, 2552 * dereference that buffer first. The new renderbuffer's refcount will 2553 * be incremented. The old renderbuffer's refcount will be decremented. 2554 * This is normally only called from the _mesa_reference_renderbuffer() macro 2555 * when there's a real pointer change. 2556 */ 2557void 2558_mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr, 2559 struct gl_renderbuffer *rb) 2560{ 2561 if (*ptr) { 2562 /* Unreference the old renderbuffer */ 2563 GLboolean deleteFlag = GL_FALSE; 2564 struct gl_renderbuffer *oldRb = *ptr; 2565 2566 _glthread_LOCK_MUTEX(oldRb->Mutex); 2567 ASSERT(oldRb->RefCount > 0); 2568 oldRb->RefCount--; 2569 /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/ 2570 deleteFlag = (oldRb->RefCount == 0); 2571 _glthread_UNLOCK_MUTEX(oldRb->Mutex); 2572 2573 if (deleteFlag) { 2574 oldRb->Delete(oldRb); 2575 } 2576 2577 *ptr = NULL; 2578 } 2579 assert(!*ptr); 2580 2581 if (rb) { 2582 /* reference new renderbuffer */ 2583 _glthread_LOCK_MUTEX(rb->Mutex); 2584 rb->RefCount++; 2585 /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/ 2586 _glthread_UNLOCK_MUTEX(rb->Mutex); 2587 *ptr = rb; 2588 } 2589} 2590