Fix some renderbuffer reference counting issues. Also fixes a mem leak.
[mesa.git] / src / mesa / main / rbadaptors.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2007 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 * Renderbuffer adaptors.
28 * These fuctions are used to convert rendering from core Mesa's GLchan
29 * colors to 8 or 16-bit color channels in RGBA renderbuffers.
30 * This means Mesa can be compiled for 16 or 32-bit color processing
31 * and still render into 8 and 16-bit/channel renderbuffers.
32 */
33
34
35 #include "glheader.h"
36 #include "mtypes.h"
37 #include "colormac.h"
38 #include "renderbuffer.h"
39 #include "rbadaptors.h"
40
41
42 static void
43 Delete_wrapper(struct gl_renderbuffer *rb)
44 {
45 /* Decrement reference count on the buffer we're wrapping and delete
46 * it if refcount hits zero.
47 */
48 _mesa_reference_renderbuffer(&rb->Wrapped, NULL);
49
50 /* delete myself */
51 _mesa_delete_renderbuffer(rb);
52 }
53
54
55 static GLboolean
56 AllocStorage_wrapper(GLcontext *ctx, struct gl_renderbuffer *rb,
57 GLenum internalFormat, GLuint width, GLuint height)
58 {
59 GLboolean b = rb->Wrapped->AllocStorage(ctx, rb->Wrapped, internalFormat,
60 width, height);
61 if (b) {
62 rb->Width = width;
63 rb->Height = height;
64 }
65 return b;
66 }
67
68
69 static void *
70 GetPointer_wrapper(GLcontext *ctx, struct gl_renderbuffer *rb,
71 GLint x, GLint y)
72 {
73 (void) ctx;
74 (void) rb;
75 (void) x;
76 (void) y;
77 return NULL;
78 }
79
80
81 static void
82 GetRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
83 GLint x, GLint y, void *values)
84 {
85 GLubyte values8[MAX_WIDTH * 4];
86 GLushort *values16 = (GLushort *) values;
87 GLuint i;
88 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
89 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
90 ASSERT(count <= MAX_WIDTH);
91
92 /* get 8bpp values */
93 rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values8);
94
95 /* convert 8bpp to 16bpp */
96 for (i = 0; i < 4 * count; i++) {
97 values16[i] = (values8[i] << 8) | values8[i];
98 }
99 }
100
101
102 static void
103 GetValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
104 const GLint x[], const GLint y[], void *values)
105 {
106 GLubyte values8[MAX_WIDTH * 4];
107 GLushort *values16 = (GLushort *) values;
108 GLuint i;
109 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
110 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
111
112 rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values8);
113
114 for (i = 0; i < 4 * count; i++) {
115 values16[i] = (values8[i] << 8) | values8[i];
116 }
117 }
118
119
120 static void
121 PutRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
122 GLint x, GLint y, const void *values, const GLubyte *mask)
123 {
124 GLubyte values8[MAX_WIDTH * 4];
125 GLushort *values16 = (GLushort *) values;
126 GLuint i;
127 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
128 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
129 for (i = 0; i < 4 * count; i++) {
130 values8[i] = values16[i] >> 8;
131 }
132 rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values8, mask);
133 }
134
135
136 static void
137 PutRowRGB_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
138 GLint x, GLint y, const void *values, const GLubyte *mask)
139 {
140 GLubyte values8[MAX_WIDTH * 3];
141 GLushort *values16 = (GLushort *) values;
142 GLuint i;
143 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
144 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
145 for (i = 0; i < 3 * count; i++) {
146 values8[i] = values16[i] >> 8;
147 }
148 rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values8, mask);
149 }
150
151
152 static void
153 PutMonoRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
154 GLint x, GLint y, const void *value, const GLubyte *mask)
155 {
156 GLubyte value8[4];
157 GLushort *value16 = (GLushort *) value;
158 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
159 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
160 value8[0] = value16[0] >> 8;
161 value8[1] = value16[1] >> 8;
162 value8[2] = value16[2] >> 8;
163 value8[3] = value16[3] >> 8;
164 rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value8, mask);
165 }
166
167
168 static void
169 PutValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
170 const GLint x[], const GLint y[], const void *values,
171 const GLubyte *mask)
172 {
173 GLubyte values8[MAX_WIDTH * 4];
174 GLushort *values16 = (GLushort *) values;
175 GLuint i;
176 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
177 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
178 for (i = 0; i < 4 * count; i++) {
179 values8[i] = values16[i] >> 8;
180 }
181 rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values8, mask);
182 }
183
184
185 static void
186 PutMonoValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb,
187 GLuint count, const GLint x[], const GLint y[],
188 const void *value, const GLubyte *mask)
189 {
190 GLubyte value8[4];
191 GLushort *value16 = (GLushort *) value;
192 ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
193 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
194 value8[0] = value16[0] >> 8;
195 value8[1] = value16[1] >> 8;
196 value8[2] = value16[2] >> 8;
197 value8[3] = value16[3] >> 8;
198 rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value8, mask);
199 }
200
201
202 /**
203 * Wrap an 8-bit/channel renderbuffer with a 16-bit/channel
204 * renderbuffer adaptor.
205 */
206 struct gl_renderbuffer *
207 _mesa_new_renderbuffer_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb8)
208 {
209 struct gl_renderbuffer *rb16;
210
211 rb16 = _mesa_new_renderbuffer(ctx, rb8->Name);
212 if (rb16) {
213 ASSERT(rb8->DataType == GL_UNSIGNED_BYTE);
214 ASSERT(rb8->_BaseFormat == GL_RGBA);
215
216 _glthread_LOCK_MUTEX(rb8->Mutex);
217 rb8->RefCount++;
218 _glthread_UNLOCK_MUTEX(rb8->Mutex);
219
220 rb16->InternalFormat = rb8->InternalFormat;
221 rb16->_ActualFormat = rb8->_ActualFormat;
222 rb16->_BaseFormat = rb8->_BaseFormat;
223 rb16->DataType = GL_UNSIGNED_SHORT;
224 /* Note: passing through underlying bits/channel */
225 rb16->RedBits = rb8->RedBits;
226 rb16->GreenBits = rb8->GreenBits;
227 rb16->BlueBits = rb8->BlueBits;
228 rb16->AlphaBits = rb8->AlphaBits;
229 rb16->Wrapped = rb8;
230
231 rb16->AllocStorage = AllocStorage_wrapper;
232 rb16->Delete = Delete_wrapper;
233 rb16->GetPointer = GetPointer_wrapper;
234 rb16->GetRow = GetRow_16wrap8;
235 rb16->GetValues = GetValues_16wrap8;
236 rb16->PutRow = PutRow_16wrap8;
237 rb16->PutRowRGB = PutRowRGB_16wrap8;
238 rb16->PutMonoRow = PutMonoRow_16wrap8;
239 rb16->PutValues = PutValues_16wrap8;
240 rb16->PutMonoValues = PutMonoValues_16wrap8;
241 }
242 return rb16;
243 }
244
245
246
247
248 static void
249 GetRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
250 GLint x, GLint y, void *values)
251 {
252 GLubyte values8[MAX_WIDTH * 4];
253 GLfloat *values32 = (GLfloat *) values;
254 GLuint i;
255 ASSERT(rb->DataType == GL_FLOAT);
256 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
257 ASSERT(count <= MAX_WIDTH);
258
259 /* get 8bpp values */
260 rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values8);
261
262 /* convert 8bpp to 32bpp */
263 for (i = 0; i < 4 * count; i++) {
264 values32[i] = UBYTE_TO_FLOAT(values8[i]);
265 }
266 }
267
268
269 static void
270 GetValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
271 const GLint x[], const GLint y[], void *values)
272 {
273 GLubyte values8[MAX_WIDTH * 4];
274 GLfloat *values32 = (GLfloat *) values;
275 GLuint i;
276 ASSERT(rb->DataType == GL_FLOAT);
277 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
278
279 rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values8);
280
281 for (i = 0; i < 4 * count; i++) {
282 values32[i] = UBYTE_TO_FLOAT(values8[i]);
283 }
284 }
285
286
287 static void
288 PutRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
289 GLint x, GLint y, const void *values, const GLubyte *mask)
290 {
291 GLubyte values8[MAX_WIDTH * 4];
292 GLfloat *values32 = (GLfloat *) values;
293 GLuint i;
294 ASSERT(rb->DataType == GL_FLOAT);
295 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
296 for (i = 0; i < 4 * count; i++) {
297 UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]);
298 }
299 rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values8, mask);
300 }
301
302
303 static void
304 PutRowRGB_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
305 GLint x, GLint y, const void *values, const GLubyte *mask)
306 {
307 GLubyte values8[MAX_WIDTH * 3];
308 GLfloat *values32 = (GLfloat *) values;
309 GLuint i;
310 ASSERT(rb->DataType == GL_FLOAT);
311 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
312 for (i = 0; i < 3 * count; i++) {
313 UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]);
314 }
315 rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values8, mask);
316 }
317
318
319 static void
320 PutMonoRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
321 GLint x, GLint y, const void *value, const GLubyte *mask)
322 {
323 GLubyte value8[4];
324 GLfloat *value32 = (GLfloat *) value;
325 ASSERT(rb->DataType == GL_FLOAT);
326 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
327 UNCLAMPED_FLOAT_TO_UBYTE(value8[0], value32[0]);
328 UNCLAMPED_FLOAT_TO_UBYTE(value8[1], value32[1]);
329 UNCLAMPED_FLOAT_TO_UBYTE(value8[2], value32[2]);
330 UNCLAMPED_FLOAT_TO_UBYTE(value8[3], value32[3]);
331 rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value8, mask);
332 }
333
334
335 static void
336 PutValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
337 const GLint x[], const GLint y[], const void *values,
338 const GLubyte *mask)
339 {
340 GLubyte values8[MAX_WIDTH * 4];
341 GLfloat *values32 = (GLfloat *) values;
342 GLuint i;
343 ASSERT(rb->DataType == GL_FLOAT);
344 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
345 for (i = 0; i < 4 * count; i++) {
346 UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]);
347 }
348 rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values8, mask);
349 }
350
351
352 static void
353 PutMonoValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb,
354 GLuint count, const GLint x[], const GLint y[],
355 const void *value, const GLubyte *mask)
356 {
357 GLubyte value8[4];
358 GLfloat *value32 = (GLfloat *) value;
359 ASSERT(rb->DataType == GL_FLOAT);
360 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE);
361 UNCLAMPED_FLOAT_TO_UBYTE(value8[0], value32[0]);
362 UNCLAMPED_FLOAT_TO_UBYTE(value8[1], value32[1]);
363 UNCLAMPED_FLOAT_TO_UBYTE(value8[2], value32[2]);
364 UNCLAMPED_FLOAT_TO_UBYTE(value8[3], value32[3]);
365 rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value8, mask);
366 }
367
368
369 /**
370 * Wrap an 8-bit/channel renderbuffer with a 32-bit/channel
371 * renderbuffer adaptor.
372 */
373 struct gl_renderbuffer *
374 _mesa_new_renderbuffer_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb8)
375 {
376 struct gl_renderbuffer *rb32;
377
378 rb32 = _mesa_new_renderbuffer(ctx, rb8->Name);
379 if (rb32) {
380 ASSERT(rb8->DataType == GL_UNSIGNED_BYTE);
381 ASSERT(rb8->_BaseFormat == GL_RGBA);
382
383 _glthread_LOCK_MUTEX(rb8->Mutex);
384 rb8->RefCount++;
385 _glthread_UNLOCK_MUTEX(rb8->Mutex);
386
387 rb32->InternalFormat = rb8->InternalFormat;
388 rb32->_ActualFormat = rb8->_ActualFormat;
389 rb32->_BaseFormat = rb8->_BaseFormat;
390 rb32->DataType = GL_FLOAT;
391 /* Note: passing through underlying bits/channel */
392 rb32->RedBits = rb8->RedBits;
393 rb32->GreenBits = rb8->GreenBits;
394 rb32->BlueBits = rb8->BlueBits;
395 rb32->AlphaBits = rb8->AlphaBits;
396 rb32->Wrapped = rb8;
397
398 rb32->AllocStorage = AllocStorage_wrapper;
399 rb32->Delete = Delete_wrapper;
400 rb32->GetPointer = GetPointer_wrapper;
401 rb32->GetRow = GetRow_32wrap8;
402 rb32->GetValues = GetValues_32wrap8;
403 rb32->PutRow = PutRow_32wrap8;
404 rb32->PutRowRGB = PutRowRGB_32wrap8;
405 rb32->PutMonoRow = PutMonoRow_32wrap8;
406 rb32->PutValues = PutValues_32wrap8;
407 rb32->PutMonoValues = PutMonoValues_32wrap8;
408 }
409 return rb32;
410 }
411
412
413
414
415 static void
416 GetRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
417 GLint x, GLint y, void *values)
418 {
419 GLushort values16[MAX_WIDTH * 4];
420 GLfloat *values32 = (GLfloat *) values;
421 GLuint i;
422 ASSERT(rb->DataType == GL_FLOAT);
423 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
424 ASSERT(count <= MAX_WIDTH);
425
426 /* get 16bpp values */
427 rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values16);
428
429 /* convert 16bpp to 32bpp */
430 for (i = 0; i < 4 * count; i++) {
431 values32[i] = USHORT_TO_FLOAT(values16[i]);
432 }
433 }
434
435
436 static void
437 GetValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
438 const GLint x[], const GLint y[], void *values)
439 {
440 GLushort values16[MAX_WIDTH * 4];
441 GLfloat *values32 = (GLfloat *) values;
442 GLuint i;
443 ASSERT(rb->DataType == GL_FLOAT);
444 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
445
446 rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values16);
447
448 for (i = 0; i < 4 * count; i++) {
449 values32[i] = USHORT_TO_FLOAT(values16[i]);
450 }
451 }
452
453
454 static void
455 PutRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
456 GLint x, GLint y, const void *values, const GLubyte *mask)
457 {
458 GLushort values16[MAX_WIDTH * 4];
459 GLfloat *values32 = (GLfloat *) values;
460 GLuint i;
461 ASSERT(rb->DataType == GL_FLOAT);
462 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
463 for (i = 0; i < 4 * count; i++) {
464 UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]);
465 }
466 rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values16, mask);
467 }
468
469
470 static void
471 PutRowRGB_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
472 GLint x, GLint y, const void *values, const GLubyte *mask)
473 {
474 GLushort values16[MAX_WIDTH * 3];
475 GLfloat *values32 = (GLfloat *) values;
476 GLuint i;
477 ASSERT(rb->DataType == GL_FLOAT);
478 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
479 for (i = 0; i < 3 * count; i++) {
480 UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]);
481 }
482 rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values16, mask);
483 }
484
485
486 static void
487 PutMonoRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
488 GLint x, GLint y, const void *value, const GLubyte *mask)
489 {
490 GLushort value16[4];
491 GLfloat *value32 = (GLfloat *) value;
492 ASSERT(rb->DataType == GL_FLOAT);
493 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
494 UNCLAMPED_FLOAT_TO_USHORT(value16[0], value32[0]);
495 UNCLAMPED_FLOAT_TO_USHORT(value16[1], value32[1]);
496 UNCLAMPED_FLOAT_TO_USHORT(value16[2], value32[2]);
497 UNCLAMPED_FLOAT_TO_USHORT(value16[3], value32[3]);
498 rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value16, mask);
499 }
500
501
502 static void
503 PutValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
504 const GLint x[], const GLint y[], const void *values,
505 const GLubyte *mask)
506 {
507 GLushort values16[MAX_WIDTH * 4];
508 GLfloat *values32 = (GLfloat *) values;
509 GLuint i;
510 ASSERT(rb->DataType == GL_FLOAT);
511 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
512 for (i = 0; i < 4 * count; i++) {
513 UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]);
514 }
515 rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values16, mask);
516 }
517
518
519 static void
520 PutMonoValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb,
521 GLuint count, const GLint x[], const GLint y[],
522 const void *value, const GLubyte *mask)
523 {
524 GLushort value16[4];
525 GLfloat *value32 = (GLfloat *) value;
526 ASSERT(rb->DataType == GL_FLOAT);
527 ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT);
528 UNCLAMPED_FLOAT_TO_USHORT(value16[0], value32[0]);
529 UNCLAMPED_FLOAT_TO_USHORT(value16[1], value32[1]);
530 UNCLAMPED_FLOAT_TO_USHORT(value16[2], value32[2]);
531 UNCLAMPED_FLOAT_TO_USHORT(value16[3], value32[3]);
532 rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value16, mask);
533 }
534
535
536 /**
537 * Wrap an 16-bit/channel renderbuffer with a 32-bit/channel
538 * renderbuffer adaptor.
539 */
540 struct gl_renderbuffer *
541 _mesa_new_renderbuffer_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb16)
542 {
543 struct gl_renderbuffer *rb32;
544
545 rb32 = _mesa_new_renderbuffer(ctx, rb16->Name);
546 if (rb32) {
547 ASSERT(rb16->DataType == GL_UNSIGNED_SHORT);
548 ASSERT(rb16->_BaseFormat == GL_RGBA);
549
550 _glthread_LOCK_MUTEX(rb16->Mutex);
551 rb16->RefCount++;
552 _glthread_UNLOCK_MUTEX(rb16->Mutex);
553
554 rb32->InternalFormat = rb16->InternalFormat;
555 rb32->_ActualFormat = rb16->_ActualFormat;
556 rb32->_BaseFormat = rb16->_BaseFormat;
557 rb32->DataType = GL_FLOAT;
558 /* Note: passing through underlying bits/channel */
559 rb32->RedBits = rb16->RedBits;
560 rb32->GreenBits = rb16->GreenBits;
561 rb32->BlueBits = rb16->BlueBits;
562 rb32->AlphaBits = rb16->AlphaBits;
563 rb32->Wrapped = rb16;
564
565 rb32->AllocStorage = AllocStorage_wrapper;
566 rb32->Delete = Delete_wrapper;
567 rb32->GetPointer = GetPointer_wrapper;
568 rb32->GetRow = GetRow_32wrap16;
569 rb32->GetValues = GetValues_32wrap16;
570 rb32->PutRow = PutRow_32wrap16;
571 rb32->PutRowRGB = PutRowRGB_32wrap16;
572 rb32->PutMonoRow = PutMonoRow_32wrap16;
573 rb32->PutValues = PutValues_32wrap16;
574 rb32->PutMonoValues = PutMonoValues_32wrap16;
575 }
576 return rb32;
577 }