assorted fixes for dealing with zero-size frame/renderbuffers.

from freedesktop (mesa-commits) with help from games/bzflag;
ok matthieu@
This commit is contained in:
aanriot 2007-04-19 08:12:55 +00:00
parent 90a95c09bd
commit d1f4a95e58
4 changed files with 49 additions and 33 deletions

View File

@ -1879,16 +1879,18 @@ void XMesaDestroyBuffer( XMesaBuffer b )
* 1. the first time a buffer is bound to a context.
* 2. from glViewport to poll for window size changes
* 3. from the XMesaResizeBuffers() API function.
* Note: it's possible (and legal) for xmctx to be NULL. That can happen
* when resizing a buffer when no rendering context is bound.
*/
void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
{
GLuint width, height;
xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height);
xmesa_get_window_size(drawBuffer->display, drawBuffer, &width, &height);
if (drawBuffer->mesa_buffer.Width != width ||
drawBuffer->mesa_buffer.Height != height) {
_mesa_resize_framebuffer(&(xmctx->mesa),
&(drawBuffer->mesa_buffer), width, height);
GLcontext *ctx = xmctx ? &xmctx->mesa : NULL;
_mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height);
}
drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
}
@ -2212,7 +2214,7 @@ void XMesaSwapBuffers( XMesaBuffer b )
}
#endif
if (b->backxrb->ximage) {
/* Copy Ximage from host's memory to server's window */
/* Copy Ximage (back buf) from client memory to server window */
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
@ -2234,8 +2236,8 @@ void XMesaSwapBuffers( XMesaBuffer b )
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
}
}
else {
/* Copy pixmap to window on server */
else if (b->backxrb->pixmap) {
/* Copy pixmap (back buf) to window (front buf) on server */
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
XMesaCopyArea( b->xm_visual->display,
b->backxrb->pixmap, /* source drawable */

View File

@ -167,9 +167,6 @@ alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
static void
alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
{
if (width == 0 || height == 0)
return;
if (b->db_mode == BACK_XIMAGE) {
/* Deallocate the old backxrb->ximage, if any */
if (b->backxrb->ximage) {
@ -185,6 +182,9 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
b->backxrb->ximage = NULL;
}
if (width == 0 || height == 0)
return;
/* Allocate new back buffer */
#ifdef XFree86Server
/* Allocate a regular XImage for the back buffer. */
@ -217,20 +217,21 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
b->backxrb->pixmap = None;
}
else if (b->db_mode == BACK_PIXMAP) {
if (!width)
width = 1;
if (!height)
height = 1;
/* Free the old back pixmap */
if (b->backxrb->pixmap) {
XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
b->backxrb->pixmap = 0;
}
/* Allocate new back pixmap */
b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
b->frontxrb->drawable,
width, height,
GET_VISUAL_DEPTH(b->xm_visual));
if (width > 0 && height > 0) {
/* Allocate new back pixmap */
b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
b->frontxrb->drawable,
width, height,
GET_VISUAL_DEPTH(b->xm_visual));
}
b->backxrb->ximage = NULL;
}
}
@ -249,6 +250,7 @@ xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
/**
* Reallocate renderbuffer storage for front color buffer.
* Called via gl_renderbuffer::AllocStorage()
*/
static GLboolean
xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
@ -259,6 +261,7 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
/* just clear these to be sure we don't accidentally use them */
xrb->origin1 = NULL;
xrb->origin2 = NULL;
xrb->origin3 = NULL;
xrb->origin4 = NULL;
/* for the FLIP macro: */
@ -274,6 +277,7 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
/**
* Reallocate renderbuffer storage for back color buffer.
* Called via gl_renderbuffer::AllocStorage()
*/
static GLboolean
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
@ -308,8 +312,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
}
else {
/* this assertion will fail if we happend to run out of memory */
/*assert(xrb->pixmap);*/
/* out of memory or buffer size is 0 x 0 */
xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0;
xrb->origin1 = NULL;
xrb->origin2 = NULL;
xrb->origin3 = NULL;
xrb->origin4 = NULL;
}
return GL_TRUE;

View File

@ -612,7 +612,7 @@ update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
const GLuint bufferBit = 1 << i;
if (bufferBit & bufferMask) {
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
if (rb) {
if (rb && rb->Width > 0 && rb->Height > 0) {
fb->_ColorDrawBuffers[output][count] = rb;
count++;
}
@ -635,7 +635,9 @@ static void
update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
(void) ctx;
if (fb->_ColorReadBufferIndex == -1) {
if (fb->_ColorReadBufferIndex == -1 ||
fb->Width == 0 ||
fb->Height == 0) {
fb->_ColorReadBuffer = NULL; /* legal! */
}
else {

View File

@ -1192,18 +1192,22 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
ASSERT(rb->PutMonoValues);
/* 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 (%d x %d x %d)",
width, height, pixelSize);
return GL_FALSE;
if (width > 0 && height > 0) {
/* 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 (%d x %d x %d)",
width, height, pixelSize);
return GL_FALSE;
}
}
rb->Width = width;