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