* Mesa 3-D graphics library
* Version: 6.5
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * 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"),
#include "fbobject.h"
#include "renderbuffer.h"
+#include "rbadaptors.h"
+
/* 32-bit color index format. Not a public format. */
#define COLOR_INDEX32 0x424243
if (!rb->Data)
return NULL;
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ /* Can't assert _ActualFormat since these funcs may be used for serveral
+ * different formats (GL_ALPHA8, GL_STENCIL_INDEX8, etc).
+ */
return (GLubyte *) rb->Data + y * rb->Width + x;
}
{
GLubyte *dst = (GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
dst[i] = *src;
{
const GLubyte *src = (const GLubyte *) values;
GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
if (mask) {
GLuint i;
for (i = 0; i < count; i++) {
{
const GLubyte val = *((const GLubyte *) value);
GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
if (mask) {
GLuint i;
for (i = 0; i < count; i++) {
{
const GLubyte *src = (const GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
{
const GLubyte val = *((const GLubyte *) value);
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
static void *
get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
- GLint x, GLint y)
+ GLint x, GLint y)
{
if (!rb->Data)
return NULL;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
return (GLuint *) rb->Data + y * rb->Width + x;
}
GLint x, GLint y, void *values)
{
const void *src = rb->GetPointer(ctx, rb, x, y);
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
_mesa_memcpy(values, src, count * sizeof(GLuint));
}
{
GLuint *dst = (GLuint *) values;
GLuint i;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
for (i = 0; i < count; i++) {
const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
dst[i] = *src;
{
const GLuint *src = (const GLuint *) values;
GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
if (mask) {
GLuint i;
for (i = 0; i < count; i++) {
{
const GLuint val = *((const GLuint *) value);
GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
- GLuint i;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ dst[i] = val;
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < count; i++) {
dst[i] = val;
}
}
{
const GLuint *src = (const GLuint *) values;
GLuint i;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
{
const GLuint val = *((const GLuint *) value);
GLuint i;
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
+ ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+ rb->DataType == GL_UNSIGNED_INT_24_8_EXT);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
GLint x, GLint y)
{
+ ASSERT(rb->_ActualFormat == GL_RGB8);
/* No direct access since this buffer is RGB but caller will be
* treating it as if it were RGBA.
*/
const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
GLubyte *dst = (GLubyte *) values;
GLuint i;
+ ASSERT(rb->_ActualFormat == GL_RGB8);
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
dst[i * 4 + 0] = src[i * 3 + 0];
{
GLubyte *dst = (GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
const GLubyte *src
= (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
const GLubyte *src = (const GLubyte *) values;
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i * 3 + 0] = src[i * 4 + 0];
const GLubyte *src = (const GLubyte *) values;
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i * 3 + 0] = src[i * 3 + 0];
const GLubyte val1 = ((const GLubyte *) value)[1];
const GLubyte val2 = ((const GLubyte *) value)[2];
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->Width + x);
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
if (!mask && val0 == val1 && val1 == val2) {
/* optimized case */
_mesa_memset(dst, val0, 3 * count);
/* note: incoming values are RGB+A! */
const GLubyte *src = (const GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
const GLubyte val1 = ((const GLubyte *) value)[1];
const GLubyte val2 = ((const GLubyte *) value)[2];
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGB8);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
if (!rb->Data)
return NULL;
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
return (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
}
get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, void *values)
{
- const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x);
+ const GLubyte *src = (const GLubyte *) rb->Data + 4 * (y * rb->Width + x);
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
- _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte));
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
+ _mesa_memcpy(values, src, 4 * count * sizeof(GLubyte));
}
/* treat 4*GLubyte as 1*GLuint */
GLuint *dst = (GLuint *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
for (i = 0; i < count; i++) {
const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
dst[i] = *src;
/* treat 4*GLubyte as 1*GLuint */
const GLuint *src = (const GLuint *) values;
GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
if (mask) {
GLuint i;
for (i = 0; i < count; i++) {
const GLubyte *src = (const GLubyte *) values;
GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->Width + x);
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i * 4 + 0] = src[i * 3 + 0];
/* treat 4*GLubyte as 1*GLuint */
const GLuint val = *((const GLuint *) value);
GLuint *dst = (GLuint *) rb->Data + (y * rb->Width + x);
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
if (!mask && val == 0) {
/* common case */
_mesa_bzero(dst, count * 4 * sizeof(GLubyte));
/* treat 4*GLubyte as 1*GLuint */
const GLuint *src = (const GLuint *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
/* treat 4*GLubyte as 1*GLuint */
const GLuint val = *((const GLuint *) value);
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(rb->_ActualFormat == GL_RGBA8);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]);
* This function also plugs in the appropriate GetPointer, Get/PutRow and
* Get/PutValues functions.
*/
-static GLboolean
-soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
- GLenum internalFormat, GLuint width, GLuint height)
+GLboolean
+_mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height)
{
GLuint pixelSize;
+ /* first clear these fields */
+ rb->RedBits =
+ rb->GreenBits =
+ rb->BlueBits =
+ rb->AlphaBits =
+ rb->IndexBits =
+ rb->DepthBits =
+ rb->StencilBits = 0;
+
switch (internalFormat) {
case GL_RGB:
case GL_R3_G3_B2:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
+ rb->_ActualFormat = GL_RGB8;
rb->_BaseFormat = GL_RGB;
rb->DataType = GL_UNSIGNED_BYTE;
rb->GetPointer = get_pointer_ubyte3;
rb->PutMonoRow = put_mono_row_ubyte3;
rb->PutValues = put_values_ubyte3;
rb->PutMonoValues = put_mono_values_ubyte3;
- rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[3] = 0;
- pixelSize = 3 * sizeof(GLchan);
+ rb->RedBits = 8 * sizeof(GLubyte);
+ rb->GreenBits = 8 * sizeof(GLubyte);
+ rb->BlueBits = 8 * sizeof(GLubyte);
+ rb->AlphaBits = 0;
+ pixelSize = 3 * sizeof(GLubyte);
break;
case GL_RGBA:
case GL_RGBA2:
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8:
+ rb->_ActualFormat = GL_RGBA8;
rb->_BaseFormat = GL_RGBA;
rb->DataType = GL_UNSIGNED_BYTE;
rb->GetPointer = get_pointer_ubyte4;
rb->PutMonoRow = put_mono_row_ubyte4;
rb->PutValues = put_values_ubyte4;
rb->PutMonoValues = put_mono_values_ubyte4;
- rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[1] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[2] = 8 * sizeof(GLubyte);
- rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
+ rb->RedBits = 8 * sizeof(GLubyte);
+ rb->GreenBits = 8 * sizeof(GLubyte);
+ rb->BlueBits = 8 * sizeof(GLubyte);
+ rb->AlphaBits = 8 * sizeof(GLubyte);
pixelSize = 4 * sizeof(GLubyte);
break;
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
+ rb->_ActualFormat = GL_RGBA16;
rb->_BaseFormat = GL_RGBA;
rb->DataType = GL_UNSIGNED_SHORT;
rb->GetPointer = get_pointer_ushort4;
rb->PutMonoRow = put_mono_row_ushort4;
rb->PutValues = put_values_ushort4;
rb->PutMonoValues = put_mono_values_ushort4;
- rb->ComponentSizes[0] = 8 * sizeof(GLushort);
- rb->ComponentSizes[1] = 8 * sizeof(GLushort);
- rb->ComponentSizes[2] = 8 * sizeof(GLushort);
- rb->ComponentSizes[3] = 8 * sizeof(GLushort);
+ rb->RedBits = 8 * sizeof(GLushort);
+ rb->GreenBits = 8 * sizeof(GLushort);
+ rb->BlueBits = 8 * sizeof(GLushort);
+ rb->AlphaBits = 8 * sizeof(GLushort);
pixelSize = 4 * sizeof(GLushort);
break;
#if 00
- case ALPHA8:
+ case GL_ALPHA8:
+ rb->_ActualFormat = GL_ALPHA8;
rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */
rb->DataType = GL_UNSIGNED_BYTE;
rb->GetPointer = get_pointer_alpha8;
rb->PutMonoRow = put_mono_row_alpha8;
rb->PutValues = put_values_alpha8;
rb->PutMonoValues = put_mono_values_alpha8;
- rb->ComponentSizes[0] = 0; /*red*/
- rb->ComponentSizes[1] = 0; /*green*/
- rb->ComponentSizes[2] = 0; /*blue*/
- rb->ComponentSizes[3] = 8 * sizeof(GLubyte);
+ rb->RedBits = 0; /*red*/
+ rb->GreenBits = 0; /*green*/
+ rb->BlueBits = 0; /*blue*/
+ rb->AlphaBits = 8 * sizeof(GLubyte);
pixelSize = sizeof(GLubyte);
break;
#endif
case GL_STENCIL_INDEX1_EXT:
case GL_STENCIL_INDEX4_EXT:
case GL_STENCIL_INDEX8_EXT:
+ rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
rb->_BaseFormat = GL_STENCIL_INDEX;
rb->DataType = GL_UNSIGNED_BYTE;
rb->GetPointer = get_pointer_ubyte;
rb->PutMonoRow = put_mono_row_ubyte;
rb->PutValues = put_values_ubyte;
rb->PutMonoValues = put_mono_values_ubyte;
- rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
+ rb->StencilBits = 8 * sizeof(GLubyte);
pixelSize = sizeof(GLubyte);
break;
case GL_STENCIL_INDEX16_EXT:
+ rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
rb->_BaseFormat = GL_STENCIL_INDEX;
rb->DataType = GL_UNSIGNED_SHORT;
rb->GetPointer = get_pointer_ushort;
rb->PutMonoRow = put_mono_row_ushort;
rb->PutValues = put_values_ushort;
rb->PutMonoValues = put_mono_values_ushort;
- rb->ComponentSizes[0] = 8 * sizeof(GLushort);
+ rb->StencilBits = 8 * sizeof(GLushort);
pixelSize = sizeof(GLushort);
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
+ rb->_ActualFormat = GL_DEPTH_COMPONENT16;
rb->_BaseFormat = GL_DEPTH_COMPONENT;
rb->DataType = GL_UNSIGNED_SHORT;
rb->GetPointer = get_pointer_ushort;
rb->PutMonoRow = put_mono_row_ushort;
rb->PutValues = put_values_ushort;
rb->PutMonoValues = put_mono_values_ushort;
- rb->ComponentSizes[0] = 8 * sizeof(GLushort);
+ rb->DepthBits = 8 * sizeof(GLushort);
pixelSize = sizeof(GLushort);
break;
case GL_DEPTH_COMPONENT24:
rb->PutMonoRow = put_mono_row_uint;
rb->PutValues = put_values_uint;
rb->PutMonoValues = put_mono_values_uint;
- rb->ComponentSizes[0] = 8 * sizeof(GLuint);
+ if (internalFormat == GL_DEPTH_COMPONENT24) {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT24;
+ rb->DepthBits = 24;
+ }
+ else {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT32;
+ rb->DepthBits = 32;
+ }
+ pixelSize = sizeof(GLuint);
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ rb->_BaseFormat = GL_DEPTH_STENCIL_EXT;
+ rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+ rb->GetPointer = get_pointer_uint;
+ rb->GetRow = get_row_uint;
+ rb->GetValues = get_values_uint;
+ rb->PutRow = put_row_uint;
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = put_mono_row_uint;
+ rb->PutValues = put_values_uint;
+ rb->PutMonoValues = put_mono_values_uint;
+ rb->DepthBits = 24;
+ rb->StencilBits = 8;
pixelSize = sizeof(GLuint);
break;
case GL_COLOR_INDEX8_EXT:
+ rb->_ActualFormat = GL_COLOR_INDEX8_EXT;
rb->_BaseFormat = GL_COLOR_INDEX;
rb->DataType = GL_UNSIGNED_BYTE;
rb->GetPointer = get_pointer_ubyte;
rb->PutMonoRow = put_mono_row_ubyte;
rb->PutValues = put_values_ubyte;
rb->PutMonoValues = put_mono_values_ubyte;
- rb->ComponentSizes[0] = 8 * sizeof(GLubyte);
+ rb->IndexBits = 8 * sizeof(GLubyte);
pixelSize = sizeof(GLubyte);
break;
case GL_COLOR_INDEX16_EXT:
+ rb->_ActualFormat = GL_COLOR_INDEX16_EXT;
rb->_BaseFormat = GL_COLOR_INDEX;
rb->DataType = GL_UNSIGNED_SHORT;
rb->GetPointer = get_pointer_ushort;
rb->PutMonoRow = put_mono_row_ushort;
rb->PutValues = put_values_ushort;
rb->PutMonoValues = put_mono_values_ushort;
- rb->ComponentSizes[0] = 8 * sizeof(GLushort);
+ rb->IndexBits = 8 * sizeof(GLushort);
pixelSize = sizeof(GLushort);
break;
case COLOR_INDEX32:
+ rb->_ActualFormat = COLOR_INDEX32;
rb->_BaseFormat = GL_COLOR_INDEX;
rb->DataType = GL_UNSIGNED_INT;
rb->GetPointer = get_pointer_uint;
rb->PutMonoRow = put_mono_row_uint;
rb->PutValues = put_values_uint;
rb->PutMonoValues = put_mono_values_uint;
- rb->ComponentSizes[0] = 8 * sizeof(GLuint);
+ rb->IndexBits = 8 * sizeof(GLuint);
pixelSize = sizeof(GLuint);
break;
default:
- _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage");
+ _mesa_problem(ctx, "Bad internalFormat in _mesa_soft_renderbuffer_storage");
return GL_FALSE;
}
ASSERT(rb->PutMonoRow);
ASSERT(rb->PutValues);
ASSERT(rb->PutMonoValues);
- ASSERT(rb->ComponentSizes[0] > 0);
/* free old buffer storage */
- if (rb->Data)
+ if (rb->Data) {
_mesa_free(rb->Data);
+ rb->Data = NULL;
+ }
- /* allocate new buffer storage */
- rb->Data = _mesa_malloc(width * height * pixelSize);
- if (rb->Data == NULL) {
- rb->Width = 0;
- rb->Height = 0;
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation");
- return GL_FALSE;
+ if (width > 0 && height > 0) {
+ /* allocate new buffer storage */
+ rb->Data = malloc(width * height * pixelSize);
+
+ if (rb->Data == NULL) {
+ rb->Width = 0;
+ rb->Height = 0;
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "software renderbuffer allocation (%d x %d x %d)",
+ width, height, pixelSize);
+ return GL_FALSE;
+ }
}
rb->Width = width;
rb->Height = height;
- rb->InternalFormat = internalFormat;
return GL_TRUE;
}
+
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
/**
- * The alpha_renderbuffer class is used to augment an RGB renderbuffer with
- * an alpha channel. The RGB buffer can be hardware-based.
- * We basically wrap the RGB buffer. When PutRow is called (for example),
- * we store the alpha values in this buffer, then pass on the PutRow call
- * to the wrapped RGB buffer.
+ * Here we utilize the gl_renderbuffer->Wrapper field to put an alpha
+ * buffer wrapper around an existing RGB renderbuffer (hw or sw).
+ *
+ * When PutRow is called (for example), we store the alpha values in
+ * this buffer, then pass on the PutRow call to the wrapped RGB
+ * buffer.
*/
-struct alpha_renderbuffer
-{
- struct gl_renderbuffer Base; /* the alpha buffer */
- struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */
-};
static GLboolean
-alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
+alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
GLenum internalFormat, GLuint width, GLuint height)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->_ActualFormat == GL_ALPHA8);
/* first, pass the call to the wrapped RGB buffer */
- if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat,
- width, height)) {
+ if (!arb->Wrapped->AllocStorage(ctx, arb->Wrapped, internalFormat,
+ width, height)) {
return GL_FALSE;
}
/* next, resize my alpha buffer */
- if (arb->Base.Data) {
- _mesa_free(arb->Base.Data);
+ if (arb->Data) {
+ _mesa_free(arb->Data);
}
- arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte));
- if (arb->Base.Data == NULL) {
- arb->Base.Width = 0;
- arb->Base.Height = 0;
+ arb->Data = _mesa_malloc(width * height * sizeof(GLubyte));
+ if (arb->Data == NULL) {
+ arb->Width = 0;
+ arb->Height = 0;
_mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation");
return GL_FALSE;
}
- arb->Base.Width = width;
- arb->Base.Height = height;
- arb->Base.InternalFormat = internalFormat;
+ arb->Width = width;
+ arb->Height = height;
return GL_TRUE;
}
* Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer.
*/
static void
-delete_renderbuffer_alpha8(struct gl_renderbuffer *rb)
+delete_renderbuffer_alpha8(struct gl_renderbuffer *arb)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
- if (arb->Base.Data) {
- _mesa_free(arb->Base.Data);
+ if (arb->Data) {
+ _mesa_free(arb->Data);
}
- assert(arb->RGBbuffer);
- arb->RGBbuffer->Delete(arb->RGBbuffer);
- arb->RGBbuffer = NULL;
+ ASSERT(arb->Wrapped);
+ ASSERT(arb != arb->Wrapped);
+ arb->Wrapped->Delete(arb->Wrapped);
+ arb->Wrapped = NULL;
_mesa_free(arb);
}
static void *
-get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
+get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
GLint x, GLint y)
{
return NULL; /* don't allow direct access! */
static void
-get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
GLint x, GLint y, void *values)
{
/* NOTE: 'values' is RGBA format! */
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
- const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
+ const GLubyte *src = (const GLubyte *) arb->Data + y * arb->Width + x;
GLubyte *dst = (GLubyte *) values;
GLuint i;
- ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values);
+ arb->Wrapped->GetRow(ctx, arb->Wrapped, count, x, y, values);
/* second, fill in alpha values from this buffer! */
for (i = 0; i < count; i++) {
dst[i * 4 + 3] = src[i];
static void
-get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
const GLint x[], const GLint y[], void *values)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
GLubyte *dst = (GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values);
+ arb->Wrapped->GetValues(ctx, arb->Wrapped, count, x, y, values);
/* second, fill in alpha values from this buffer! */
for (i = 0; i < count; i++) {
- const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ const GLubyte *src = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
dst[i * 4 + 3] = *src;
}
}
static void
-put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
const GLubyte *src = (const GLubyte *) values;
- GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask);
+ arb->Wrapped->PutRow(ctx, arb->Wrapped, count, x, y, values, mask);
/* second, store alpha in our buffer */
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
static void
-put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
const GLubyte *src = (const GLubyte *) values;
- GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask);
+ arb->Wrapped->PutRowRGB(ctx, arb->Wrapped, count, x, y, values, mask);
/* second, store alpha in our buffer */
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
static void
-put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
GLint x, GLint y, const void *value, const GLubyte *mask)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
const GLubyte val = ((const GLubyte *) value)[3];
- GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ GLubyte *dst = (GLubyte *) arb->Data + y * arb->Width + x;
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask);
+ arb->Wrapped->PutMonoRow(ctx, arb->Wrapped, count, x, y, value, mask);
/* second, store alpha in our buffer */
if (mask) {
GLuint i;
static void
-put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
+put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb, GLuint count,
const GLint x[], const GLint y[],
const void *values, const GLubyte *mask)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
const GLubyte *src = (const GLubyte *) values;
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask);
+ arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, values, mask);
/* second, store alpha in our buffer */
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
- GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
*dst = src[i * 4 + 3];
}
}
static void
-put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb,
+put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *arb,
GLuint count, const GLint x[], const GLint y[],
const void *value, const GLubyte *mask)
{
- struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb;
const GLubyte val = ((const GLubyte *) value)[3];
GLuint i;
- assert(rb->DataType == GL_UNSIGNED_BYTE);
+ ASSERT(arb != arb->Wrapped);
+ ASSERT(arb->DataType == GL_UNSIGNED_BYTE);
/* first, pass the call to the wrapped RGB buffer */
- arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask);
+ arb->Wrapped->PutValues(ctx, arb->Wrapped, count, x, y, value, mask);
/* second, store alpha in our buffer */
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
- GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
+ GLubyte *dst = (GLubyte *) arb->Data + y[i] * arb->Width + x[i];
*dst = val;
}
}
}
+static void
+copy_buffer_alpha8(struct gl_renderbuffer* dst, struct gl_renderbuffer* src)
+{
+ ASSERT(dst->_ActualFormat == GL_ALPHA8);
+ ASSERT(src->_ActualFormat == GL_ALPHA8);
+ ASSERT(dst->Width == src->Width);
+ ASSERT(dst->Height == src->Height);
+
+ _mesa_memcpy(dst->Data, src->Data, dst->Width * dst->Height * sizeof(GLubyte));
+}
+
/**********************************************************************/
/**********************************************************************/
void
_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
{
+ _glthread_INIT_MUTEX(rb->Mutex);
+
+ rb->Magic = RB_MAGIC;
+ rb->ClassID = 0;
rb->Name = name;
- rb->RefCount = 1;
+ rb->RefCount = 0;
rb->Delete = _mesa_delete_renderbuffer;
/* The rest of these should be set later by the caller of this function or
rb->Width = 0;
rb->Height = 0;
rb->InternalFormat = GL_NONE;
+ rb->_ActualFormat = GL_NONE;
rb->_BaseFormat = GL_NONE;
+
+ rb->ComponentType = GL_UNSIGNED_NORMALIZED; /* ARB_fbo */
+ rb->ColorEncoding = GL_LINEAR; /* ARB_fbo */
+
+ rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 0;
+ rb->IndexBits = 0;
+ rb->DepthBits = 0;
+ rb->StencilBits = 0;
+
rb->DataType = GL_NONE;
- rb->ComponentSizes[0] = 0;
- rb->ComponentSizes[1] = 0;
- rb->ComponentSizes[2] = 0;
- rb->ComponentSizes[3] = 0;
rb->Data = NULL;
+ /* Point back to ourself so that we don't have to check for Wrapped==NULL
+ * all over the drivers.
+ */
+ rb->Wrapped = rb;
+
rb->GetPointer = nop_get_pointer;
rb->GetRow = NULL;
rb->GetValues = NULL;
/**
* Delete a gl_framebuffer.
- * This is the default function for framebuffer->Delete().
+ * This is the default function for renderbuffer->Delete().
*/
void
_mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
* Allocate a software-based renderbuffer. This is called via the
* ctx->Driver.NewRenderbuffer() function when the user creates a new
* renderbuffer.
+ * This would not be used for hardware-based renderbuffers.
*/
struct gl_renderbuffer *
_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
{
struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
if (rb) {
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
/* Normally, one would setup the PutRow, GetRow, etc functions here.
- * But we're doing that in the soft_renderbuffer_storage() function
+ * But we're doing that in the _mesa_soft_renderbuffer_storage() function
* instead.
*/
}
if (rgbBits <= 8) {
if (alphaBits)
- rb->InternalFormat = GL_RGBA8;
+ rb->_ActualFormat = GL_RGBA8;
else
- rb->InternalFormat = GL_RGB8;
+ rb->_ActualFormat = GL_RGB8;
}
else {
assert(rgbBits <= 16);
if (alphaBits)
- rb->InternalFormat = GL_RGBA16;
+ rb->_ActualFormat = GL_RGBA16;
else
- rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */
+ rb->_ActualFormat = GL_RGBA16; /* don't really have RGB16 yet */
}
+ rb->InternalFormat = rb->_ActualFormat;
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, b, rb);
}
if (indexBits > 8) {
_mesa_problem(ctx,
- "Unsupported bit depth in _mesa_add_color_renderbuffers");
+ "Unsupported bit depth in _mesa_add_color_index_renderbuffers");
return GL_FALSE;
}
if (indexBits <= 8) {
/* only support GLuint for now */
/*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
- rb->InternalFormat = COLOR_INDEX32;
+ rb->_ActualFormat = COLOR_INDEX32;
}
else {
- rb->InternalFormat = COLOR_INDEX32;
+ rb->_ActualFormat = COLOR_INDEX32;
}
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->InternalFormat = rb->_ActualFormat;
+
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, b, rb);
}
assert(MAX_COLOR_ATTACHMENTS >= 4);
+ /* Wrap each of the RGB color buffers with an alpha renderbuffer.
+ */
for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
- struct alpha_renderbuffer *arb;
+ struct gl_renderbuffer *arb;
if (b == BUFFER_FRONT_LEFT && !frontLeft)
continue;
/* only GLubyte supported for now */
assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
- arb = CALLOC_STRUCT(alpha_renderbuffer);
+ /* allocate alpha renderbuffer */
+ arb = _mesa_new_renderbuffer(ctx, 0);
if (!arb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
return GL_FALSE;
}
- _mesa_init_renderbuffer(&arb->Base, 0);
-
- /* wrap the RGB buffer */
- arb->RGBbuffer = fb->Attachment[b].Renderbuffer;
-
- /* plug in my functions */
- arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat;
- arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat;
- arb->Base.DataType = arb->RGBbuffer->DataType;
- arb->Base.AllocStorage = alloc_storage_alpha8;
- arb->Base.Delete = delete_renderbuffer_alpha8;
- arb->Base.GetPointer = get_pointer_alpha8;
- arb->Base.GetRow = get_row_alpha8;
- arb->Base.GetValues = get_values_alpha8;
- arb->Base.PutRow = put_row_alpha8;
- arb->Base.PutRowRGB = put_row_rgb_alpha8;
- arb->Base.PutMonoRow = put_mono_row_alpha8;
- arb->Base.PutValues = put_values_alpha8;
- arb->Base.PutMonoValues = put_mono_values_alpha8;
+ /* wrap the alpha renderbuffer around the RGB renderbuffer */
+ arb->Wrapped = fb->Attachment[b].Renderbuffer;
+
+ /* Set up my alphabuffer fields and plug in my functions.
+ * The functions will put/get the alpha values from/to RGBA arrays
+ * and then call the wrapped buffer's functions to handle the RGB
+ * values.
+ */
+ arb->InternalFormat = arb->Wrapped->InternalFormat;
+ arb->_ActualFormat = GL_ALPHA8;
+ arb->_BaseFormat = arb->Wrapped->_BaseFormat;
+ arb->DataType = arb->Wrapped->DataType;
+ arb->AllocStorage = alloc_storage_alpha8;
+ arb->Delete = delete_renderbuffer_alpha8;
+ arb->GetPointer = get_pointer_alpha8;
+ arb->GetRow = get_row_alpha8;
+ arb->GetValues = get_values_alpha8;
+ arb->PutRow = put_row_alpha8;
+ arb->PutRowRGB = put_row_rgb_alpha8;
+ arb->PutMonoRow = put_mono_row_alpha8;
+ arb->PutValues = put_values_alpha8;
+ arb->PutMonoValues = put_mono_values_alpha8;
/* clear the pointer to avoid assertion/sanity check failure later */
fb->Attachment[b].Renderbuffer = NULL;
/* plug the alpha renderbuffer into the colorbuffer attachment */
- _mesa_add_renderbuffer(fb, b, &arb->Base);
+ _mesa_add_renderbuffer(fb, b, arb);
}
return GL_TRUE;
}
+/**
+ * For framebuffers that use a software alpha channel wrapper
+ * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers,
+ * copy the back buffer alpha channel into the front buffer alpha channel.
+ */
+void
+_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+
+ if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer &&
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer)
+ copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer,
+ fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);
+}
+
+
/**
* Add a software-based depth renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
}
if (depthBits <= 16) {
- rb->InternalFormat = GL_DEPTH_COMPONENT16;
+ rb->_ActualFormat = GL_DEPTH_COMPONENT16;
+ }
+ else if (depthBits <= 24) {
+ rb->_ActualFormat = GL_DEPTH_COMPONENT24;
}
else {
- rb->InternalFormat = GL_DEPTH_COMPONENT32;
+ rb->_ActualFormat = GL_DEPTH_COMPONENT32;
}
+ rb->InternalFormat = rb->_ActualFormat;
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
return GL_TRUE;
}
if (stencilBits <= 8) {
- rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
+ rb->_ActualFormat = GL_STENCIL_INDEX8_EXT;
}
else {
/* not really supported (see s_stencil.c code) */
- rb->InternalFormat = GL_STENCIL_INDEX16_EXT;
+ rb->_ActualFormat = GL_STENCIL_INDEX16_EXT;
}
+ rb->InternalFormat = rb->_ActualFormat;
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
return GL_TRUE;
return GL_FALSE;
}
+ rb->_ActualFormat = GL_RGBA16;
rb->InternalFormat = GL_RGBA16;
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
return GL_TRUE;
}
if (colorBits <= 8) {
- rb->InternalFormat = GL_RGBA8;
+ rb->_ActualFormat = GL_RGBA8;
}
else {
- rb->InternalFormat = GL_RGBA16;
+ rb->_ActualFormat = GL_RGBA16;
}
+ rb->InternalFormat = rb->_ActualFormat;
- rb->AllocStorage = soft_renderbuffer_storage;
+ rb->AllocStorage = _mesa_soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
}
return GL_TRUE;
{
assert(fb);
assert(rb);
-#if 00
- /* there should be no previous renderbuffer on this attachment point! */
- assert(fb->Attachment[bufferName].Renderbuffer == NULL);
-#endif
assert(bufferName < BUFFER_COUNT);
+ /* There should be no previous renderbuffer on this attachment point,
+ * with the exception of depth/stencil since the same renderbuffer may
+ * be used for both.
+ */
+ assert(bufferName == BUFFER_DEPTH ||
+ bufferName == BUFFER_STENCIL ||
+ fb->Attachment[bufferName].Renderbuffer == NULL);
+
/* winsys vs. user-created buffer cross check */
if (fb->Name) {
assert(rb->Name);
assert(!rb->Name);
}
+ /* If Mesa's compiled with deep color channels (16 or 32 bits / channel)
+ * and the device driver is expecting 8-bit values (GLubyte), we can
+ * use a "renderbuffer adaptor/wrapper" to do the necessary conversions.
+ */
+ if (rb->_BaseFormat == GL_RGBA) {
+ if (CHAN_BITS == 16 && rb->DataType == GL_UNSIGNED_BYTE) {
+ GET_CURRENT_CONTEXT(ctx);
+ rb = _mesa_new_renderbuffer_16wrap8(ctx, rb);
+ }
+ else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_BYTE) {
+ GET_CURRENT_CONTEXT(ctx);
+ rb = _mesa_new_renderbuffer_32wrap8(ctx, rb);
+ }
+ else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_SHORT) {
+ GET_CURRENT_CONTEXT(ctx);
+ rb = _mesa_new_renderbuffer_32wrap16(ctx, rb);
+ }
+ }
+
fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
fb->Attachment[bufferName].Complete = GL_TRUE;
- fb->Attachment[bufferName].Renderbuffer = rb;
+ _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);
+}
+
+
+/**
+ * Remove the named renderbuffer from the given framebuffer.
+ */
+void
+_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName)
+{
+ struct gl_renderbuffer *rb;
+
+ assert(bufferName < BUFFER_COUNT);
+
+ rb = fb->Attachment[bufferName].Renderbuffer;
+ if (!rb)
+ return;
+
+ _mesa_reference_renderbuffer(&rb, NULL);
+
+ fb->Attachment[bufferName].Renderbuffer = NULL;
+}
+
+
+/**
+ * Set *ptr to point to rb. If *ptr points to another renderbuffer,
+ * dereference that buffer first. The new renderbuffer's refcount will
+ * be incremented. The old renderbuffer's refcount will be decremented.
+ */
+void
+_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
+ struct gl_renderbuffer *rb)
+{
+ assert(ptr);
+ if (*ptr == rb) {
+ /* no change */
+ return;
+ }
+
+ if (*ptr) {
+ /* Unreference the old renderbuffer */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_renderbuffer *oldRb = *ptr;
+
+ assert(oldRb->Magic == RB_MAGIC);
+ _glthread_LOCK_MUTEX(oldRb->Mutex);
+ assert(oldRb->Magic == RB_MAGIC);
+ ASSERT(oldRb->RefCount > 0);
+ oldRb->RefCount--;
+ /*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
+ deleteFlag = (oldRb->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldRb->Mutex);
+
+ if (deleteFlag) {
+ oldRb->Magic = 0; /* now invalid memory! */
+ oldRb->Delete(oldRb);
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (rb) {
+ assert(rb->Magic == RB_MAGIC);
+ /* reference new renderbuffer */
+ _glthread_LOCK_MUTEX(rb->Mutex);
+ rb->RefCount++;
+ /*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
+ _glthread_UNLOCK_MUTEX(rb->Mutex);
+ *ptr = rb;
+ }
+}
+
+
+/**
+ * Create a new combined depth/stencil renderbuffer for implementing
+ * the GL_EXT_packed_depth_stencil extension.
+ * \return new depth/stencil renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_renderbuffer *dsrb;
+
+ dsrb = _mesa_new_renderbuffer(ctx, name);
+ if (!dsrb)
+ return NULL;
+
+ /* init fields not covered by _mesa_new_renderbuffer() */
+ dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
+ dsrb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
+
+ return dsrb;
}