xm_buffer.c revision 374e7fd6cc95d3d91629a6e1c951d77e8a29c31c
1e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/*
2e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Mesa 3-D graphics library
3d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Version:  6.5.2
4e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
5d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
7e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
8e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * copy of this software and associated documentation files (the "Software"),
9e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * to deal in the Software without restriction, including without limitation
10e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
12e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Software is furnished to do so, subject to the following conditions:
13e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
14e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The above copyright notice and this permission notice shall be included
15e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * in all copies or substantial portions of the Software.
16e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul *
17e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
24e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
25e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
26d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
27d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * \file xm_buffer.h
28d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Framebuffer and renderbuffer-related functions.
29d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
30d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
31d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
32e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "glxheader.h"
33e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "GL/xmesa.h"
34e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "xmesaP.h"
35374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/imports.h"
36374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/framebuffer.h"
37374e7fd6cc95d3d91629a6e1c951d77e8a29c31cBrian Paul#include "main/renderbuffer.h"
38e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
39e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
407439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis#if defined(USE_XSHM) && !defined(XFree86Server)
41d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic volatile int mesaXErrorFlag = 0;
42d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
43d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
44d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Catches potential Xlib errors.
45d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
46d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic int
47d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian PaulmesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event)
48d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{
49d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   (void) dpy;
50d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   (void) event;
51d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   mesaXErrorFlag = 1;
52d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   return 0;
53d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul}
54d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
55d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
56d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
57d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Return:  GL_TRUE if success, GL_FALSE if error
58d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
59d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic GLboolean
60d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
61d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{
62d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /*
63d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * We have to do a _lot_ of error checking here to be sure we can
64d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * really use the XSHM extension.  It seems different servers trigger
65d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * errors at different points if the extension won't work.  Therefore
66d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * we have to be very careful...
67d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    */
68d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   GC gc;
69d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   int (*old_handler)(XMesaDisplay *, XErrorEvent *);
70d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
71d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (width == 0 || height == 0) {
72d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* this will be true the first time we're called on 'b' */
73d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
74d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
75d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
76d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
77d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        b->xm_visual->visinfo->visual,
78d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        b->xm_visual->visinfo->depth,
79d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        ZPixmap, NULL, &b->shminfo,
80d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        width, height);
81d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->backxrb->ximage == NULL) {
82d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
83d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
84d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
85d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
86d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
87d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
88d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul			     * b->backxrb->ximage->height, IPC_CREAT|0777);
89d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->shminfo.shmid < 0) {
90d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
91d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
92d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
93d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
94d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
95d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
96d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
97d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
98d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.shmaddr = b->backxrb->ximage->data
99d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                      = (char*)shmat(b->shminfo.shmid, 0, 0);
100d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->shminfo.shmaddr == (char *) -1) {
101d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
102d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
103d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
104d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
105d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
106d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
107d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
108d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
109d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
110d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.readOnly = False;
111d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   mesaXErrorFlag = 0;
112d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   old_handler = XSetErrorHandler(mesaHandleXError);
113d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* This may trigger the X protocol error we're ready to catch: */
114d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XShmAttach(b->xm_visual->display, &b->shminfo);
115d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XSync(b->xm_visual->display, False);
116d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
117d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (mesaXErrorFlag) {
118d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* we are on a remote display, this error is normal, don't print it */
119d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XFlush(b->xm_visual->display);
120d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      mesaXErrorFlag = 0;
121d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
122d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmdt(b->shminfo.shmaddr);
123d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
124d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
125d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
126d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      (void) XSetErrorHandler(old_handler);
127d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
128d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
129d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
130d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */
131d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
132d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* Finally, try an XShmPutImage to be really sure the extension works */
133d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL);
134d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
135d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul		 b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
136d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XSync(b->xm_visual->display, False);
137d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XFreeGC(b->xm_visual->display, gc);
138d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   (void) XSetErrorHandler(old_handler);
139d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (mesaXErrorFlag) {
140d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XFlush(b->xm_visual->display);
141d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      mesaXErrorFlag = 0;
142d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
143d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmdt(b->shminfo.shmaddr);
144d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
145d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
146d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
147d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
148d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
149d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
150d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   return GL_TRUE;
1517439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis}
152d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#else
1537439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzisstatic GLboolean
1547439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzisalloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
1557439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis{
156d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* Can't compile XSHM support */
157d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   return GL_FALSE;
158d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul}
159d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
160d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
161d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
162d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
163d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
164d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Setup an off-screen pixmap or Ximage to use as the back buffer.
165d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Input:  b - the X/Mesa buffer
166d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
167d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic void
168d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
169d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{
170d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->db_mode == BACK_XIMAGE) {
171d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Deallocate the old backxrb->ximage, if any */
172d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->backxrb->ximage) {
173d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
174d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 if (b->shm) {
175d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    XShmDetach(b->xm_visual->display, &b->shminfo);
176d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    XDestroyImage(b->backxrb->ximage);
177d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    shmdt(b->shminfo.shmaddr);
178d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 }
179d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 else
180d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
181d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	   XMesaDestroyImage(b->backxrb->ximage);
182d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 b->backxrb->ximage = NULL;
183d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
184d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
185e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      if (width == 0 || height == 0)
186e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         return;
187e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
188d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Allocate new back buffer */
189d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
190d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 /* Allocate a regular XImage for the back buffer. */
1917439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis#ifdef XFree86Server
1927439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis	 b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
1937439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis                                               width, height, NULL);
1947439a36785b6a2783e80a40a96c09db8f56dc2bcGeorge Sapountzis#else
195d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 b->backxrb->ximage = XCreateImage(b->xm_visual->display,
196d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      b->xm_visual->visinfo->visual,
197d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      GET_VISUAL_DEPTH(b->xm_visual),
198d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      ZPixmap, 0,   /* format, offset */
199d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      NULL,
200d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      width, height,
201d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      8, 0);  /* pad, bytes_per_line */
202d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
203d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 if (!b->backxrb->ximage) {
204d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
205d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            return;
206d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 }
207d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height
208d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        * b->backxrb->ximage->bytes_per_line);
209d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         if (!b->backxrb->ximage->data) {
210d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
211d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            XMesaDestroyImage(b->backxrb->ximage);
212d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            b->backxrb->ximage = NULL;
213d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         }
214d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
215d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->pixmap = None;
216d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
217d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   else if (b->db_mode == BACK_PIXMAP) {
218d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Free the old back pixmap */
219d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->backxrb->pixmap) {
220e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
221e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         b->backxrb->pixmap = 0;
222d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
223e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
224e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      if (width > 0 && height > 0) {
225e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         /* Allocate new back pixmap */
226e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
227e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                b->frontxrb->drawable,
228e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                width, height,
229e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                GET_VISUAL_DEPTH(b->xm_visual));
230e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      }
231e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
232d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
233d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
234d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul}
235d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
236d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
237e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void
238e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulxmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
239e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
240d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul   /* XXX Note: the ximage or Pixmap attached to this renderbuffer
241d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    * should probably get freed here, but that's currently done in
242d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    * XMesaDestroyBuffer().
243d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    */
244d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul   _mesa_free(rb);
245e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
246e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
247e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
248e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
249692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for front color buffer.
250e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage()
251e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
252e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic GLboolean
253692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulxmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
254692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                          GLenum internalFormat, GLuint width, GLuint height)
255e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
256444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
257e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
258692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* just clear these to be sure we don't accidentally use them */
259692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin1 = NULL;
260692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin2 = NULL;
261e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian   xrb->origin3 = NULL;
262692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin4 = NULL;
263692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
264692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* for the FLIP macro: */
265692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->bottom = height - 1;
266692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
267692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->Width = width;
268692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->Height = height;
269692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->InternalFormat = internalFormat;
270692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
271692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   return GL_TRUE;
272692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul}
273692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
274692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
275692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul/**
276692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for back color buffer.
277e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage()
278692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul */
279692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulstatic GLboolean
280692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulxmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
281692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                         GLenum internalFormat, GLuint width, GLuint height)
282692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul{
283444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
284692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
285d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* reallocate the back buffer XImage or Pixmap */
286d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   assert(xrb->Parent);
287d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   alloc_back_buffer(xrb->Parent, width, height);
288d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
289692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* same as front buffer */
290d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* XXX why is this here? */
291692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
292692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
293692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* plus... */
294e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (xrb->ximage) {
295e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR1 macro */
296e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width1 = xrb->ximage->bytes_per_line;
297e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin1 = (GLubyte *) xrb->ximage->data + xrb->width1 * (height - 1);
298e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
299e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR2 macro */
300e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width2 = xrb->ximage->bytes_per_line / 2;
301e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin2 = (GLushort *) xrb->ximage->data + xrb->width2 * (height - 1);
302e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
303e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR3 macro */
304e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width3 = xrb->ximage->bytes_per_line;
305e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin3 = (GLubyte *) xrb->ximage->data + xrb->width3 * (height - 1);
306e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
307e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR4 macro */
308e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width4 = xrb->ximage->width;
309e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
310e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
311e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else {
312e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      /* out of memory or buffer size is 0 x 0 */
313e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0;
314e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin1 = NULL;
315e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin2 = NULL;
316e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin3 = NULL;
317e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin4 = NULL;
318e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
319e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
320e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return GL_TRUE;
321e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
322e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
323e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
324e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstruct xmesa_renderbuffer *
3259e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paulxmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
326692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                       GLboolean backBuffer)
327e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
328e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer);
329e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (xrb) {
330e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      GLuint name = 0;
331e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      _mesa_init_renderbuffer(&xrb->Base, name);
332e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
333e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->Base.Delete = xmesa_delete_renderbuffer;
334692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul      if (backBuffer)
335692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul         xrb->Base.AllocStorage = xmesa_alloc_back_storage;
336692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul      else
337692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul         xrb->Base.AllocStorage = xmesa_alloc_front_storage;
338e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
3399e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul      if (visual->rgbMode) {
340e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.InternalFormat = GL_RGBA;
341e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base._BaseFormat = GL_RGBA;
342e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.DataType = GL_UNSIGNED_BYTE;
3439e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.RedBits = visual->redBits;
3449e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.GreenBits = visual->greenBits;
3459e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.BlueBits = visual->blueBits;
3469e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.AlphaBits = visual->alphaBits;
347e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
348e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else {
349e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.InternalFormat = GL_COLOR_INDEX;
350e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base._BaseFormat = GL_COLOR_INDEX;
351e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.DataType = GL_UNSIGNED_INT;
3529e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.IndexBits = visual->indexBits;
353e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
354676d0accf5cc43e86057b14cfb8bba9316932582Brian Paul      /* only need to set Red/Green/EtcBits fields for user-created RBs */
355e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
356e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return xrb;
357e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
358e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
359e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
360928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian/**
361928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian * Called via gl_framebuffer::Delete() method when this buffer
36259e56ee3e5c8f9aa9ec74e1817065a7ae14012eaBrian * is _really_ being deleted.
363928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian */
364928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianvoid
365928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianxmesa_delete_framebuffer(struct gl_framebuffer *fb)
366928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian{
367928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   XMesaBuffer b = XMESA_BUFFER(fb);
368e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
369928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->num_alloced > 0) {
370928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      /* If no other buffer uses this X colormap then free the colors. */
371928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (!xmesa_find_buffer(b->display, b->cmap, b)) {
372928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#ifdef XFree86Server
37347e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian         int client = 0;
37447e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian         if (b->frontxrb->drawable)
37547e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian            client = CLIENT_ID(b->frontxrb->drawable->id);
376928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         (void)FreeColors(b->cmap, client,
377928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                          b->num_alloced, b->alloced_colors, 0);
378928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#else
379928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         XFreeColors(b->display, b->cmap,
380928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                     b->alloced_colors, b->num_alloced, 0);
381928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#endif
382928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
383928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
384928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
385928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->gc)
386e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian      XMesaFreeGC(b->display, b->gc);
387928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->cleargc)
388e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian      XMesaFreeGC(b->display, b->cleargc);
389928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->swapgc)
390e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian      XMesaFreeGC(b->display, b->swapgc);
391928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
392e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian   if (fb->Visual.doubleBufferMode) {
393928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      /* free back ximage/pixmap/shmregion */
394928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (b->backxrb->ximage) {
395928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#if defined(USE_XSHM) && !defined(XFree86Server)
396928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         if (b->shm) {
397e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian            XShmDetach( b->display, &b->shminfo );
398928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XDestroyImage( b->backxrb->ximage );
399928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            shmdt( b->shminfo.shmaddr );
400928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         }
401928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         else
402928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#endif
403928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XMesaDestroyImage( b->backxrb->ximage );
404928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         b->backxrb->ximage = NULL;
405928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
406928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (b->backxrb->pixmap) {
407e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian         XMesaFreePixmap( b->display, b->backxrb->pixmap );
408928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         if (b->xm_visual->hpcr_clear_flag) {
409e812a2a484660c87383e7e7d8897a9bcf85cf9ccBrian            XMesaFreePixmap( b->display,
410928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                             b->xm_visual->hpcr_clear_pixmap );
411928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
412928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         }
413928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
414928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
415928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
416928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->rowimage) {
417928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      _mesa_free( b->rowimage->data );
418928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      b->rowimage->data = NULL;
419928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      XMesaDestroyImage( b->rowimage );
420928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
421928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
422928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   _mesa_free_framebuffer_data(fb);
423928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   _mesa_free(fb);
424928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian}
425