xm_buffer.c revision e5070bc3ca75dee31034cc543f3d2ee04e5dc032
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"
35e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "imports.h"
36928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#include "framebuffer.h"
37e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#include "renderbuffer.h"
38e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
39e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
40d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#ifndef 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#endif
55d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
56d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
57d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
58d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
59d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Return:  GL_TRUE if success, GL_FALSE if error
60d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
61d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#ifndef XFree86Server
62d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic GLboolean
63d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
64d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{
65d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#ifdef USE_XSHM
66d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /*
67d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * We have to do a _lot_ of error checking here to be sure we can
68d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * really use the XSHM extension.  It seems different servers trigger
69d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * errors at different points if the extension won't work.  Therefore
70d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    * we have to be very careful...
71d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul    */
72d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   GC gc;
73d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   int (*old_handler)(XMesaDisplay *, XErrorEvent *);
74d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
75d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (width == 0 || height == 0) {
76d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* this will be true the first time we're called on 'b' */
77d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
78d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
79d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
80d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
81d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        b->xm_visual->visinfo->visual,
82d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        b->xm_visual->visinfo->depth,
83d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        ZPixmap, NULL, &b->shminfo,
84d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        width, height);
85d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->backxrb->ximage == NULL) {
86d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
87d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
88d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
89d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
90d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
91d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
92d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul			     * b->backxrb->ximage->height, IPC_CREAT|0777);
93d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->shminfo.shmid < 0) {
94d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
95d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
96d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
97d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
98d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
99d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
100d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
101d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
102d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.shmaddr = b->backxrb->ximage->data
103d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                      = (char*)shmat(b->shminfo.shmid, 0, 0);
104d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->shminfo.shmaddr == (char *) -1) {
105d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
106d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
107d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
108d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
109d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
110d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
111d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
112d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
113d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
114d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   b->shminfo.readOnly = False;
115d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   mesaXErrorFlag = 0;
116d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   old_handler = XSetErrorHandler(mesaHandleXError);
117d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* This may trigger the X protocol error we're ready to catch: */
118d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XShmAttach(b->xm_visual->display, &b->shminfo);
119d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XSync(b->xm_visual->display, False);
120d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
121d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (mesaXErrorFlag) {
122d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* we are on a remote display, this error is normal, don't print it */
123d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XFlush(b->xm_visual->display);
124d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      mesaXErrorFlag = 0;
125d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
126d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmdt(b->shminfo.shmaddr);
127d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
128d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
129d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
130d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      (void) XSetErrorHandler(old_handler);
131d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
132d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
133d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
134d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */
135d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
136d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* Finally, try an XShmPutImage to be really sure the extension works */
137d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL);
138d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
139d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul		 b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
140d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XSync(b->xm_visual->display, False);
141d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   XFreeGC(b->xm_visual->display, gc);
142d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   (void) XSetErrorHandler(old_handler);
143d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (mesaXErrorFlag) {
144d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XFlush(b->xm_visual->display);
145d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      mesaXErrorFlag = 0;
146d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      XDestroyImage(b->backxrb->ximage);
147d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmdt(b->shminfo.shmaddr);
148d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      shmctl(b->shminfo.shmid, IPC_RMID, 0);
149d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
150d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->shm = 0;
151d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      return GL_FALSE;
152d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
153d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
154d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   return GL_TRUE;
155d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#else
156d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* Can't compile XSHM support */
157d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   return GL_FALSE;
158d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
159d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul}
160d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
161d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
162d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
163d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
164d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul/**
165d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Setup an off-screen pixmap or Ximage to use as the back buffer.
166d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul * Input:  b - the X/Mesa buffer
167d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul */
168d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulstatic void
169d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paulalloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
170d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul{
171d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   if (b->db_mode == BACK_XIMAGE) {
172d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Deallocate the old backxrb->ximage, if any */
173d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->backxrb->ximage) {
174d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
175d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 if (b->shm) {
176d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    XShmDetach(b->xm_visual->display, &b->shminfo);
177d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    XDestroyImage(b->backxrb->ximage);
178d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    shmdt(b->shminfo.shmaddr);
179d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 }
180d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 else
181d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
182d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	   XMesaDestroyImage(b->backxrb->ximage);
183d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 b->backxrb->ximage = NULL;
184d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
185d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
186e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      if (width == 0 || height == 0)
187e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         return;
188e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
189d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Allocate new back buffer */
190d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#ifdef XFree86Server
191d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Allocate a regular XImage for the back buffer. */
192d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
193d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                            width, height, NULL);
194d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      {
195d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#else
196d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
197d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 /* Allocate a regular XImage for the back buffer. */
198d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 b->backxrb->ximage = XCreateImage(b->xm_visual->display,
199d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      b->xm_visual->visinfo->visual,
200d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      GET_VISUAL_DEPTH(b->xm_visual),
201d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      ZPixmap, 0,   /* format, offset */
202d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      NULL,
203d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                      width, height,
204d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul				      8, 0);  /* pad, bytes_per_line */
205d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul#endif
206d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 if (!b->backxrb->ximage) {
207d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	    _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
208d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            return;
209d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul	 }
210d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height
211d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul                                        * b->backxrb->ximage->bytes_per_line);
212d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         if (!b->backxrb->ximage->data) {
213d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
214d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            XMesaDestroyImage(b->backxrb->ximage);
215d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul            b->backxrb->ximage = NULL;
216d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul         }
217d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
218d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->pixmap = None;
219d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
220d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   else if (b->db_mode == BACK_PIXMAP) {
221d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      /* Free the old back pixmap */
222d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      if (b->backxrb->pixmap) {
223e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
224e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         b->backxrb->pixmap = 0;
225d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      }
226e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
227e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      if (width > 0 && height > 0) {
228e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         /* Allocate new back pixmap */
229e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian         b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
230e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                b->frontxrb->drawable,
231e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                width, height,
232e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian                                                GET_VISUAL_DEPTH(b->xm_visual));
233e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      }
234e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian
235d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul      b->backxrb->ximage = NULL;
236d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   }
237d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul}
238d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
239d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
240e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void
241e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulxmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
242e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
243d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul   /* XXX Note: the ximage or Pixmap attached to this renderbuffer
244d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    * should probably get freed here, but that's currently done in
245d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    * XMesaDestroyBuffer().
246d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul    */
247d2e289c70f2b9fb882f5b3992b610a9ea5c8357cBrian Paul   _mesa_free(rb);
248e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
249e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
250e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
251e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/**
252692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for front color buffer.
253e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage()
254e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */
255e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic GLboolean
256692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulxmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
257692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                          GLenum internalFormat, GLuint width, GLuint height)
258e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
259444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
260e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
261692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* just clear these to be sure we don't accidentally use them */
262692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin1 = NULL;
263692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin2 = NULL;
264e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian   xrb->origin3 = NULL;
265692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->origin4 = NULL;
266692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
267692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* for the FLIP macro: */
268692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   xrb->bottom = height - 1;
269692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
270692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->Width = width;
271692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->Height = height;
272692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   rb->InternalFormat = internalFormat;
273692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
274692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   return GL_TRUE;
275692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul}
276692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
277692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
278692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul/**
279692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul * Reallocate renderbuffer storage for back color buffer.
280e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian * Called via gl_renderbuffer::AllocStorage()
281692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul */
282692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulstatic GLboolean
283692147ebf7f09d56a7de1659de2449478da4d1baBrian Paulxmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
284692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                         GLenum internalFormat, GLuint width, GLuint height)
285692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul{
286444cd293fd69d1848b2c55f75674d563e0582fbaBrian Paul   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
287692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
288d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* reallocate the back buffer XImage or Pixmap */
289d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   assert(xrb->Parent);
290d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   alloc_back_buffer(xrb->Parent, width, height);
291d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul
292692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* same as front buffer */
293d21fa9cd79e4198b673c1453b8bc05749f8a73ebBrian Paul   /* XXX why is this here? */
294692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
295692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul
296692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul   /* plus... */
297e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (xrb->ximage) {
298e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR1 macro */
299e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width1 = xrb->ximage->bytes_per_line;
300e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin1 = (GLubyte *) xrb->ximage->data + xrb->width1 * (height - 1);
301e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
302e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR2 macro */
303e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width2 = xrb->ximage->bytes_per_line / 2;
304e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin2 = (GLushort *) xrb->ximage->data + xrb->width2 * (height - 1);
305e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
306e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR3 macro */
307e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width3 = xrb->ximage->bytes_per_line;
308e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin3 = (GLubyte *) xrb->ximage->data + xrb->width3 * (height - 1);
309e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
310e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* Needed by PIXELADDR4 macro */
311e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->width4 = xrb->ximage->width;
312e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1);
313e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
314e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else {
315e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      /* out of memory or buffer size is 0 x 0 */
316e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0;
317e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin1 = NULL;
318e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin2 = NULL;
319e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin3 = NULL;
320e5070bc3ca75dee31034cc543f3d2ee04e5dc032Brian      xrb->origin4 = NULL;
321e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
322e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
323e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return GL_TRUE;
324e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
325e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
326e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
327e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstruct xmesa_renderbuffer *
3289e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paulxmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
329692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul                       GLboolean backBuffer)
330e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{
331e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer);
332e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (xrb) {
333e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      GLuint name = 0;
334e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      _mesa_init_renderbuffer(&xrb->Base, name);
335e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
336e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      xrb->Base.Delete = xmesa_delete_renderbuffer;
337692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul      if (backBuffer)
338692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul         xrb->Base.AllocStorage = xmesa_alloc_back_storage;
339692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul      else
340692147ebf7f09d56a7de1659de2449478da4d1baBrian Paul         xrb->Base.AllocStorage = xmesa_alloc_front_storage;
341e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
3429e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul      if (visual->rgbMode) {
343e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.InternalFormat = GL_RGBA;
344e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base._BaseFormat = GL_RGBA;
345e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.DataType = GL_UNSIGNED_BYTE;
3469e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.RedBits = visual->redBits;
3479e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.GreenBits = visual->greenBits;
3489e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.BlueBits = visual->blueBits;
3499e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.AlphaBits = visual->alphaBits;
350e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
351e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else {
352e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.InternalFormat = GL_COLOR_INDEX;
353e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base._BaseFormat = GL_COLOR_INDEX;
354e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         xrb->Base.DataType = GL_UNSIGNED_INT;
3559e81d6ae3a6db9831d6aea0fe4d92722176e9f74Brian Paul         xrb->Base.IndexBits = visual->indexBits;
356e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
357676d0accf5cc43e86057b14cfb8bba9316932582Brian Paul      /* only need to set Red/Green/EtcBits fields for user-created RBs */
358e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
359e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   return xrb;
360e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul}
361e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
362e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
363928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian/**
364928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian * Called via gl_framebuffer::Delete() method when this buffer
36559e56ee3e5c8f9aa9ec74e1817065a7ae14012eaBrian * is _really_ being deleted.
366928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian */
367928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianvoid
368928a70e4354d4884e2918ec67ddc6d8baf942c8aBrianxmesa_delete_framebuffer(struct gl_framebuffer *fb)
369928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian{
370928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   XMesaBuffer b = XMESA_BUFFER(fb);
371e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
372928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->num_alloced > 0) {
373928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      /* If no other buffer uses this X colormap then free the colors. */
374928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (!xmesa_find_buffer(b->display, b->cmap, b)) {
375928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#ifdef XFree86Server
37647e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian         int client = 0;
37747e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian         if (b->frontxrb->drawable)
37847e0b606a85059ff29fe311dc2f1bcafdefe4cdbBrian            client = CLIENT_ID(b->frontxrb->drawable->id);
379928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         (void)FreeColors(b->cmap, client,
380928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                          b->num_alloced, b->alloced_colors, 0);
381928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#else
382928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         XFreeColors(b->display, b->cmap,
383928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                     b->alloced_colors, b->num_alloced, 0);
384928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#endif
385928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
386928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
387928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
388928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->gc)
389928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      XMesaFreeGC(b->xm_visual->display, b->gc);
390928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->cleargc)
391928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      XMesaFreeGC(b->xm_visual->display, b->cleargc);
392928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->swapgc)
393928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      XMesaFreeGC(b->xm_visual->display, b->swapgc);
394928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
395928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->xm_visual->mesa_visual.doubleBufferMode) {
396928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      /* free back ximage/pixmap/shmregion */
397928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (b->backxrb->ximage) {
398928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#if defined(USE_XSHM) && !defined(XFree86Server)
399928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         if (b->shm) {
400928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XShmDetach( b->xm_visual->display, &b->shminfo );
401928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XDestroyImage( b->backxrb->ximage );
402928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            shmdt( b->shminfo.shmaddr );
403928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         }
404928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         else
405928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian#endif
406928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XMesaDestroyImage( b->backxrb->ximage );
407928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         b->backxrb->ximage = NULL;
408928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
409928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      if (b->backxrb->pixmap) {
410928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap );
411928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         if (b->xm_visual->hpcr_clear_flag) {
412928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XMesaFreePixmap( b->xm_visual->display,
413928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian                             b->xm_visual->hpcr_clear_pixmap );
414928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian            XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
415928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian         }
416928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      }
417928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
418928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
419928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   if (b->rowimage) {
420928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      _mesa_free( b->rowimage->data );
421928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      b->rowimage->data = NULL;
422928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian      XMesaDestroyImage( b->rowimage );
423928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   }
424928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian
425955906aa647d0d233b422c979e1ee81dc32abb87Brian   /* Note that XMesaBuffer renderbuffers normally have a refcount of 2
426955906aa647d0d233b422c979e1ee81dc32abb87Brian    * (creation + binding) so we need to explicitly delete/unbind them here.
427955906aa647d0d233b422c979e1ee81dc32abb87Brian    */
428955906aa647d0d233b422c979e1ee81dc32abb87Brian   if (b->frontxrb) {
429955906aa647d0d233b422c979e1ee81dc32abb87Brian      _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb);
430955906aa647d0d233b422c979e1ee81dc32abb87Brian      ASSERT(b->frontxrb == NULL);
431955906aa647d0d233b422c979e1ee81dc32abb87Brian   }
432955906aa647d0d233b422c979e1ee81dc32abb87Brian   if (b->backxrb) {
433955906aa647d0d233b422c979e1ee81dc32abb87Brian      _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb);
434955906aa647d0d233b422c979e1ee81dc32abb87Brian      ASSERT(b->backxrb == NULL);
435955906aa647d0d233b422c979e1ee81dc32abb87Brian   }
436955906aa647d0d233b422c979e1ee81dc32abb87Brian
437928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   _mesa_free_framebuffer_data(fb);
438928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian   _mesa_free(fb);
439928a70e4354d4884e2918ec67ddc6d8baf942c8aBrian}
440