mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 13:38:06 +02:00
Assorted fixes for dealing with zero-size frame/renderbuffers.
In xmesa_check_and_update_buffer_size() handle xmctx==NULL correctly: still call _mesa_resize_framebufer(). If we don't we can wind up in a situation where the framebuffer size is non-zero but an attached renderbuffer size is still initialized to zero. This inconsistancy can later cause problems. Check for zero-size renderbuffers in update_color_draw_buffers() and update_color_read_buffer(). See bug 7205.
This commit is contained in:
parent
7573b58db6
commit
e5070bc3ca
4 changed files with 50 additions and 34 deletions
|
|
@ -1842,16 +1842,18 @@ XMesaDestroyBuffer(XMesaBuffer b)
|
||||||
* 1. the first time a buffer is bound to a context.
|
* 1. the first time a buffer is bound to a context.
|
||||||
* 2. from glViewport to poll for window size changes
|
* 2. from glViewport to poll for window size changes
|
||||||
* 3. from the XMesaResizeBuffers() API function.
|
* 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
|
void
|
||||||
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
|
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
|
||||||
{
|
{
|
||||||
GLuint width, height;
|
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 ||
|
if (drawBuffer->mesa_buffer.Width != width ||
|
||||||
drawBuffer->mesa_buffer.Height != height) {
|
drawBuffer->mesa_buffer.Height != height) {
|
||||||
_mesa_resize_framebuffer(&(xmctx->mesa),
|
GLcontext *ctx = xmctx ? &xmctx->mesa : NULL;
|
||||||
&(drawBuffer->mesa_buffer), width, height);
|
_mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height);
|
||||||
}
|
}
|
||||||
drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
|
drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
|
||||||
}
|
}
|
||||||
|
|
@ -2175,7 +2177,7 @@ void XMesaSwapBuffers( XMesaBuffer b )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (b->backxrb->ximage) {
|
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 defined(USE_XSHM) && !defined(XFree86Server)
|
||||||
if (b->shm) {
|
if (b->shm) {
|
||||||
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
|
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
|
||||||
|
|
@ -2197,8 +2199,8 @@ void XMesaSwapBuffers( XMesaBuffer b )
|
||||||
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
|
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (b->backxrb->pixmap) {
|
||||||
/* Copy pixmap to window on server */
|
/* Copy pixmap (back buf) to window (front buf) on server */
|
||||||
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
|
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
|
||||||
XMesaCopyArea( b->xm_visual->display,
|
XMesaCopyArea( b->xm_visual->display,
|
||||||
b->backxrb->pixmap, /* source drawable */
|
b->backxrb->pixmap, /* source drawable */
|
||||||
|
|
|
||||||
|
|
@ -168,9 +168,6 @@ alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
|
||||||
static void
|
static void
|
||||||
alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
|
alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
|
||||||
{
|
{
|
||||||
if (width == 0 || height == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (b->db_mode == BACK_XIMAGE) {
|
if (b->db_mode == BACK_XIMAGE) {
|
||||||
/* Deallocate the old backxrb->ximage, if any */
|
/* Deallocate the old backxrb->ximage, if any */
|
||||||
if (b->backxrb->ximage) {
|
if (b->backxrb->ximage) {
|
||||||
|
|
@ -186,6 +183,9 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
|
||||||
b->backxrb->ximage = NULL;
|
b->backxrb->ximage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Allocate new back buffer */
|
/* Allocate new back buffer */
|
||||||
#ifdef XFree86Server
|
#ifdef XFree86Server
|
||||||
/* Allocate a regular XImage for the back buffer. */
|
/* Allocate a regular XImage for the back buffer. */
|
||||||
|
|
@ -218,20 +218,20 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
|
||||||
b->backxrb->pixmap = None;
|
b->backxrb->pixmap = None;
|
||||||
}
|
}
|
||||||
else if (b->db_mode == BACK_PIXMAP) {
|
else if (b->db_mode == BACK_PIXMAP) {
|
||||||
if (!width)
|
|
||||||
width = 1;
|
|
||||||
if (!height)
|
|
||||||
height = 1;
|
|
||||||
|
|
||||||
/* Free the old back pixmap */
|
/* Free the old back pixmap */
|
||||||
if (b->backxrb->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,
|
if (width > 0 && height > 0) {
|
||||||
b->frontxrb->drawable,
|
/* Allocate new back pixmap */
|
||||||
width, height,
|
b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
|
||||||
GET_VISUAL_DEPTH(b->xm_visual));
|
b->frontxrb->drawable,
|
||||||
|
width, height,
|
||||||
|
GET_VISUAL_DEPTH(b->xm_visual));
|
||||||
|
}
|
||||||
|
|
||||||
b->backxrb->ximage = NULL;
|
b->backxrb->ximage = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -250,6 +250,7 @@ xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reallocate renderbuffer storage for front color buffer.
|
* Reallocate renderbuffer storage for front color buffer.
|
||||||
|
* Called via gl_renderbuffer::AllocStorage()
|
||||||
*/
|
*/
|
||||||
static GLboolean
|
static GLboolean
|
||||||
xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
|
|
@ -260,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 */
|
/* just clear these to be sure we don't accidentally use them */
|
||||||
xrb->origin1 = NULL;
|
xrb->origin1 = NULL;
|
||||||
xrb->origin2 = NULL;
|
xrb->origin2 = NULL;
|
||||||
|
xrb->origin3 = NULL;
|
||||||
xrb->origin4 = NULL;
|
xrb->origin4 = NULL;
|
||||||
|
|
||||||
/* for the FLIP macro: */
|
/* for the FLIP macro: */
|
||||||
|
|
@ -275,6 +277,7 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reallocate renderbuffer storage for back color buffer.
|
* Reallocate renderbuffer storage for back color buffer.
|
||||||
|
* Called via gl_renderbuffer::AllocStorage()
|
||||||
*/
|
*/
|
||||||
static GLboolean
|
static GLboolean
|
||||||
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
|
|
@ -309,8 +312,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
|
xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* this assertion will fail if we happend to run out of memory */
|
/* out of memory or buffer size is 0 x 0 */
|
||||||
/*assert(xrb->pixmap);*/
|
xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0;
|
||||||
|
xrb->origin1 = NULL;
|
||||||
|
xrb->origin2 = NULL;
|
||||||
|
xrb->origin3 = NULL;
|
||||||
|
xrb->origin4 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
|
|
|
||||||
|
|
@ -647,7 +647,7 @@ update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||||
const GLuint bufferBit = 1 << i;
|
const GLuint bufferBit = 1 << i;
|
||||||
if (bufferBit & bufferMask) {
|
if (bufferBit & bufferMask) {
|
||||||
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
||||||
if (rb) {
|
if (rb && rb->Width > 0 && rb->Height > 0) {
|
||||||
fb->_ColorDrawBuffers[output][count] = rb;
|
fb->_ColorDrawBuffers[output][count] = rb;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
@ -673,7 +673,10 @@ static void
|
||||||
update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||||
{
|
{
|
||||||
(void) ctx;
|
(void) ctx;
|
||||||
if (fb->_ColorReadBufferIndex == -1 || fb->DeletePending) {
|
if (fb->_ColorReadBufferIndex == -1 ||
|
||||||
|
fb->DeletePending ||
|
||||||
|
fb->Width == 0 ||
|
||||||
|
fb->Height == 0) {
|
||||||
fb->_ColorReadBuffer = NULL; /* legal! */
|
fb->_ColorReadBuffer = NULL; /* legal! */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -1192,18 +1192,22 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
ASSERT(rb->PutMonoValues);
|
ASSERT(rb->PutMonoValues);
|
||||||
|
|
||||||
/* free old buffer storage */
|
/* free old buffer storage */
|
||||||
if (rb->Data)
|
if (rb->Data) {
|
||||||
_mesa_free(rb->Data);
|
_mesa_free(rb->Data);
|
||||||
|
rb->Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate new buffer storage */
|
if (width > 0 && height > 0) {
|
||||||
rb->Data = _mesa_malloc(width * height * pixelSize);
|
/* allocate new buffer storage */
|
||||||
if (rb->Data == NULL) {
|
rb->Data = _mesa_malloc(width * height * pixelSize);
|
||||||
rb->Width = 0;
|
if (rb->Data == NULL) {
|
||||||
rb->Height = 0;
|
rb->Width = 0;
|
||||||
_mesa_error(ctx, GL_OUT_OF_MEMORY,
|
rb->Height = 0;
|
||||||
"software renderbuffer allocation (%d x %d x %d)",
|
_mesa_error(ctx, GL_OUT_OF_MEMORY,
|
||||||
width, height, pixelSize);
|
"software renderbuffer allocation (%d x %d x %d)",
|
||||||
return GL_FALSE;
|
width, height, pixelSize);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rb->Width = width;
|
rb->Width = width;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue