diff options
Diffstat (limited to 'src/mesa/main/rbadaptors.c')
-rw-r--r-- | src/mesa/main/rbadaptors.c | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c new file mode 100644 index 00000000000..313c8d43d62 --- /dev/null +++ b/src/mesa/main/rbadaptors.c @@ -0,0 +1,577 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Renderbuffer adaptors. + * These fuctions are used to convert rendering from core Mesa's GLchan + * colors to 8 or 16-bit color channels in RGBA renderbuffers. + * This means Mesa can be compiled for 16 or 32-bit color processing + * and still render into 8 and 16-bit/channel renderbuffers. + */ + + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "renderbuffer.h" +#include "rbadaptors.h" + + +static void +Delete_wrapper(struct gl_renderbuffer *rb) +{ + /* Decrement reference count on the buffer we're wrapping and delete + * it if refcount hits zero. + */ + _mesa_dereference_renderbuffer(&rb->Wrapped); + + /* delete myself */ + _mesa_delete_renderbuffer(rb); +} + + +static GLboolean +AllocStorage_wrapper(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + GLboolean b = rb->Wrapped->AllocStorage(ctx, rb->Wrapped, internalFormat, + width, height); + if (b) { + rb->Width = width; + rb->Height = height; + } + return b; +} + + +static void * +GetPointer_wrapper(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + (void) ctx; + (void) rb; + (void) x; + (void) y; + return NULL; +} + + +static void +GetRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLushort *values16 = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + ASSERT(count <= MAX_WIDTH); + + /* get 8bpp values */ + rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values8); + + /* convert 8bpp to 16bpp */ + for (i = 0; i < 4 * count; i++) { + values16[i] = (values8[i] << 8) | values8[i]; + } +} + + +static void +GetValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLushort *values16 = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + + rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values8); + + for (i = 0; i < 4 * count; i++) { + values16[i] = (values8[i] << 8) | values8[i]; + } +} + + +static void +PutRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLushort *values16 = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 4 * count; i++) { + values8[i] = values16[i] >> 8; + } + rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutRowRGB_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 3]; + GLushort *values16 = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 3 * count; i++) { + values8[i] = values16[i] >> 8; + } + rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutMonoRow_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + GLubyte value8[4]; + GLushort *value16 = (GLushort *) value; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + value8[0] = value16[0] >> 8; + value8[1] = value16[1] >> 8; + value8[2] = value16[2] >> 8; + value8[3] = value16[3] >> 8; + rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value8, mask); +} + + +static void +PutValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLushort *values16 = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 4 * count; i++) { + values8[i] = values16[i] >> 8; + } + rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutMonoValues_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + GLubyte value8[4]; + GLushort *value16 = (GLushort *) value; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + value8[0] = value16[0] >> 8; + value8[1] = value16[1] >> 8; + value8[2] = value16[2] >> 8; + value8[3] = value16[3] >> 8; + rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value8, mask); +} + + +/** + * Wrap an 8-bit/channel renderbuffer with a 16-bit/channel + * renderbuffer adaptor. + */ +struct gl_renderbuffer * +_mesa_new_renderbuffer_16wrap8(GLcontext *ctx, struct gl_renderbuffer *rb8) +{ + struct gl_renderbuffer *rb16; + + rb16 = _mesa_new_renderbuffer(ctx, rb8->Name); + if (rb16) { + ASSERT(rb8->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb8->_BaseFormat == GL_RGBA); + + _glthread_LOCK_MUTEX(rb8->Mutex); + rb8->RefCount++; + _glthread_UNLOCK_MUTEX(rb8->Mutex); + + rb16->InternalFormat = rb8->InternalFormat; + rb16->_ActualFormat = rb8->_ActualFormat; + rb16->_BaseFormat = rb8->_BaseFormat; + rb16->DataType = GL_UNSIGNED_SHORT; + /* Note: passing through underlying bits/channel */ + rb16->RedBits = rb8->RedBits; + rb16->GreenBits = rb8->GreenBits; + rb16->BlueBits = rb8->BlueBits; + rb16->AlphaBits = rb8->AlphaBits; + rb16->Wrapped = rb8; + + rb16->AllocStorage = AllocStorage_wrapper; + rb16->Delete = Delete_wrapper; + rb16->GetPointer = GetPointer_wrapper; + rb16->GetRow = GetRow_16wrap8; + rb16->GetValues = GetValues_16wrap8; + rb16->PutRow = PutRow_16wrap8; + rb16->PutRowRGB = PutRowRGB_16wrap8; + rb16->PutMonoRow = PutMonoRow_16wrap8; + rb16->PutValues = PutValues_16wrap8; + rb16->PutMonoValues = PutMonoValues_16wrap8; + } + return rb16; +} + + + + +static void +GetRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + ASSERT(count <= MAX_WIDTH); + + /* get 8bpp values */ + rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values8); + + /* convert 8bpp to 32bpp */ + for (i = 0; i < 4 * count; i++) { + values32[i] = UBYTE_TO_FLOAT(values8[i]); + } +} + + +static void +GetValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + + rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values8); + + for (i = 0; i < 4 * count; i++) { + values32[i] = UBYTE_TO_FLOAT(values8[i]); + } +} + + +static void +PutRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 4 * count; i++) { + UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]); + } + rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutRowRGB_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 3]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 3 * count; i++) { + UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]); + } + rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutMonoRow_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + GLubyte value8[4]; + GLfloat *value32 = (GLfloat *) value; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + UNCLAMPED_FLOAT_TO_UBYTE(value8[0], value32[0]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[1], value32[1]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[2], value32[2]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[3], value32[3]); + rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value8, mask); +} + + +static void +PutValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + GLubyte values8[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < 4 * count; i++) { + UNCLAMPED_FLOAT_TO_UBYTE(values8[i], values32[i]); + } + rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values8, mask); +} + + +static void +PutMonoValues_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + GLubyte value8[4]; + GLfloat *value32 = (GLfloat *) value; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_BYTE); + UNCLAMPED_FLOAT_TO_UBYTE(value8[0], value32[0]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[1], value32[1]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[2], value32[2]); + UNCLAMPED_FLOAT_TO_UBYTE(value8[3], value32[3]); + rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value8, mask); +} + + +/** + * Wrap an 8-bit/channel renderbuffer with a 32-bit/channel + * renderbuffer adaptor. + */ +struct gl_renderbuffer * +_mesa_new_renderbuffer_32wrap8(GLcontext *ctx, struct gl_renderbuffer *rb8) +{ + struct gl_renderbuffer *rb32; + + rb32 = _mesa_new_renderbuffer(ctx, rb8->Name); + if (rb32) { + ASSERT(rb8->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb8->_BaseFormat == GL_RGBA); + + _glthread_LOCK_MUTEX(rb8->Mutex); + rb8->RefCount++; + _glthread_UNLOCK_MUTEX(rb8->Mutex); + + rb32->InternalFormat = rb8->InternalFormat; + rb32->_ActualFormat = rb8->_ActualFormat; + rb32->_BaseFormat = rb8->_BaseFormat; + rb32->DataType = GL_FLOAT; + /* Note: passing through underlying bits/channel */ + rb32->RedBits = rb8->RedBits; + rb32->GreenBits = rb8->GreenBits; + rb32->BlueBits = rb8->BlueBits; + rb32->AlphaBits = rb8->AlphaBits; + rb32->Wrapped = rb8; + + rb32->AllocStorage = AllocStorage_wrapper; + rb32->Delete = Delete_wrapper; + rb32->GetPointer = GetPointer_wrapper; + rb32->GetRow = GetRow_32wrap8; + rb32->GetValues = GetValues_32wrap8; + rb32->PutRow = PutRow_32wrap8; + rb32->PutRowRGB = PutRowRGB_32wrap8; + rb32->PutMonoRow = PutMonoRow_32wrap8; + rb32->PutValues = PutValues_32wrap8; + rb32->PutMonoValues = PutMonoValues_32wrap8; + } + return rb32; +} + + + + +static void +GetRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + GLushort values16[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + ASSERT(count <= MAX_WIDTH); + + /* get 16bpp values */ + rb->Wrapped->GetRow(ctx, rb->Wrapped, count, x, y, values16); + + /* convert 16bpp to 32bpp */ + for (i = 0; i < 4 * count; i++) { + values32[i] = USHORT_TO_FLOAT(values16[i]); + } +} + + +static void +GetValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLushort values16[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + + rb->Wrapped->GetValues(ctx, rb->Wrapped, count, x, y, values16); + + for (i = 0; i < 4 * count; i++) { + values32[i] = USHORT_TO_FLOAT(values16[i]); + } +} + + +static void +PutRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLushort values16[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + for (i = 0; i < 4 * count; i++) { + UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]); + } + rb->Wrapped->PutRow(ctx, rb->Wrapped, count, x, y, values16, mask); +} + + +static void +PutRowRGB_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + GLushort values16[MAX_WIDTH * 3]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + for (i = 0; i < 3 * count; i++) { + UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]); + } + rb->Wrapped->PutRowRGB(ctx, rb->Wrapped, count, x, y, values16, mask); +} + + +static void +PutMonoRow_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + GLushort value16[4]; + GLfloat *value32 = (GLfloat *) value; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + UNCLAMPED_FLOAT_TO_USHORT(value16[0], value32[0]); + UNCLAMPED_FLOAT_TO_USHORT(value16[1], value32[1]); + UNCLAMPED_FLOAT_TO_USHORT(value16[2], value32[2]); + UNCLAMPED_FLOAT_TO_USHORT(value16[3], value32[3]); + rb->Wrapped->PutMonoRow(ctx, rb->Wrapped, count, x, y, value16, mask); +} + + +static void +PutValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + GLushort values16[MAX_WIDTH * 4]; + GLfloat *values32 = (GLfloat *) values; + GLuint i; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + for (i = 0; i < 4 * count; i++) { + UNCLAMPED_FLOAT_TO_USHORT(values16[i], values32[i]); + } + rb->Wrapped->PutValues(ctx, rb->Wrapped, count, x, y, values16, mask); +} + + +static void +PutMonoValues_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + GLushort value16[4]; + GLfloat *value32 = (GLfloat *) value; + ASSERT(rb->DataType == GL_FLOAT); + ASSERT(rb->Wrapped->DataType == GL_UNSIGNED_SHORT); + UNCLAMPED_FLOAT_TO_USHORT(value16[0], value32[0]); + UNCLAMPED_FLOAT_TO_USHORT(value16[1], value32[1]); + UNCLAMPED_FLOAT_TO_USHORT(value16[2], value32[2]); + UNCLAMPED_FLOAT_TO_USHORT(value16[3], value32[3]); + rb->Wrapped->PutMonoValues(ctx, rb->Wrapped, count, x, y, value16, mask); +} + + +/** + * Wrap an 16-bit/channel renderbuffer with a 32-bit/channel + * renderbuffer adaptor. + */ +struct gl_renderbuffer * +_mesa_new_renderbuffer_32wrap16(GLcontext *ctx, struct gl_renderbuffer *rb16) +{ + struct gl_renderbuffer *rb32; + + rb32 = _mesa_new_renderbuffer(ctx, rb16->Name); + if (rb32) { + ASSERT(rb16->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb16->_BaseFormat == GL_RGBA); + + _glthread_LOCK_MUTEX(rb16->Mutex); + rb16->RefCount++; + _glthread_UNLOCK_MUTEX(rb16->Mutex); + + rb32->InternalFormat = rb16->InternalFormat; + rb32->_ActualFormat = rb16->_ActualFormat; + rb32->_BaseFormat = rb16->_BaseFormat; + rb32->DataType = GL_FLOAT; + /* Note: passing through underlying bits/channel */ + rb32->RedBits = rb16->RedBits; + rb32->GreenBits = rb16->GreenBits; + rb32->BlueBits = rb16->BlueBits; + rb32->AlphaBits = rb16->AlphaBits; + rb32->Wrapped = rb16; + + rb32->AllocStorage = AllocStorage_wrapper; + rb32->Delete = Delete_wrapper; + rb32->GetPointer = GetPointer_wrapper; + rb32->GetRow = GetRow_32wrap16; + rb32->GetValues = GetValues_32wrap16; + rb32->PutRow = PutRow_32wrap16; + rb32->PutRowRGB = PutRowRGB_32wrap16; + rb32->PutMonoRow = PutMonoRow_32wrap16; + rb32->PutValues = PutValues_32wrap16; + rb32->PutMonoValues = PutMonoValues_32wrap16; + } + return rb32; +} |