mesa: fix the selection of soft renderbuffer color formats
[mesa.git] / src / mesa / main / renderbuffer.c
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 */
63 static int
64 get_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. */
98 static void *
99 get_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 */
111 static void
112 get_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 */
122 static void
123 get_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 */
141 static void
142 put_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
170 static void
171 put_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
196 static void
197 put_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
215 static void
216 put_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
237 static void
238 get_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
251 static void
252 put_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
272 static void
273 put_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
296 static void
297 put_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
313 static void
314 put_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
335 static void
336 get_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
349 static void
350 put_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
370 static void
371 put_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
394 static void
395 put_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
411 static void
412 put_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
442 static void
443 get_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
457 static void
458 put_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
479 static void
480 put_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
504 static void
505 put_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
522 static void
523 put_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
547 static void *
548 get_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
559 static void
560 get_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
578 static void
579 get_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
597 static void
598 put_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
617 static void
618 put_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
637 static void
638 put_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
665 static void
666 put_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
686 static void
687 put_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
715 static void
716 get_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
732 static void
733 put_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
756 static void
757 put_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
778 static void
779 put_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
812 static void
813 put_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
832 static void
833 put_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
857 static void
858 get_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
872 static void
873 put_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
896 static void
897 put_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
921 static void
922 put_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
949 static void
950 put_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
970 static void
971 put_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 */
996 static void
997 get_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
1009 static void
1010 get_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 */
1025 static void
1026 get_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
1038 static void
1039 get_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 */
1054 static void
1055 get_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
1070 static void
1071 get_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 */
1089 static void
1090 get_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
1105 static void
1106 get_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 */
1124 static void
1125 get_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
1140 static void
1141 get_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 */
1160 static void
1161 get_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
1176 static void
1177 get_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 */
1196 static void
1197 get_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
1212 static void
1213 get_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
1229 static void
1230 put_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
1252 static void
1253 put_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
1275 static void
1276 put_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
1292 static void
1293 put_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 */
1312 static void
1313 get_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
1328 static void
1329 get_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 */
1348 static void
1349 get_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
1364 static void
1365 get_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 */
1389 void
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 */
1607 GLboolean
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
1729 void
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
1750 void
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
1772 static GLboolean
1773 alloc_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 */
1809 static void
1810 delete_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
1823 static void *
1824 get_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
1831 static void
1832 get_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
1850 static void
1851 get_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
1868 static void
1869 put_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
1888 static void
1889 put_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
1908 static void
1909 put_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
1933 static void
1934 put_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
1954 static void
1955 put_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
1975 static void
1976 copy_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 */
1997 static void *
1998 nop_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 */
2007 void
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 */
2050 struct 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 */
2065 void
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 */
2081 struct 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 */
2104 GLboolean
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 */
2158 GLboolean
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 */
2242 void
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 */
2266 GLboolean
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 */
2311 GLboolean
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 */
2349 GLboolean
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 */
2389 GLboolean
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 */
2428 void
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 */
2498 void
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 */
2532 void
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 */
2557 void
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 }