Big re-org of buffer size management.
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 14 Oct 2006 22:52:17 +0000 (22:52 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 14 Oct 2006 22:52:17 +0000 (22:52 +0000)
All buffer resizes now handled by xmesa_check_and_update_buffer_size() which
uses the _mesa_resize_framebuffer() function.
Moved all low-level XImage/Pixmap resizing into xm_buffers.c file.
Also, update lots of comments for Doxygen.

src/mesa/drivers/x11/xm_api.c
src/mesa/drivers/x11/xm_buffer.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/drivers/x11/xmesaP.h

index e0187d2..6aa8dc5 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/*
- * This file contains the implementations of all the XMesa* functions.
+/**
+ * \file xm_api.c
+ *
+ * All the XMesa* API functions.
  *
  *
  * NOTES:
 #include "framebuffer.h"
 #include "glthread.h"
 #include "imports.h"
-#include "matrix.h"
-#include "mtypes.h"
 #include "macros.h"
 #include "renderbuffer.h"
-#include "texformat.h"
-#include "texobj.h"
-#include "texstore.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "array_cache/acache.h"
 #include <GL/glxtokens.h>
 #endif
 
-/*
+/**
  * Global X driver lock
  */
 _glthread_Mutex _xmesa_lock;
 
 
 
-/*
+/**
  * Lookup tables for HPCR pixel format:
  */
 static short hpcr_rgbTbl[3][256] = {
@@ -161,7 +158,7 @@ static short hpcr_rgbTbl[3][256] = {
 /**********************************************************************/
 
 
-/*
+/**
  * Return the host's byte order as LSBFirst or MSBFirst ala X.
  */
 #ifndef XFree86Server
@@ -174,23 +171,7 @@ static int host_byte_order( void )
 #endif
 
 
-/*
- * Error handling.
- */
-#ifndef XFree86Server
-static volatile int mesaXErrorFlag = 0;
-
-static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
-{
-   (void) dpy;
-   (void) event;
-   mesaXErrorFlag = 1;
-   return 0;
-}
-#endif
-
-
-/*
+/**
  * Check if the X Shared Memory extension is available.
  * Return:  0 = not available
  *          1 = shared XImage support available
@@ -222,11 +203,12 @@ static int check_for_xshm( XMesaDisplay *display )
 }
 
 
-/*
+/**
  * Apply gamma correction to an intensity value in [0..max].  Return the
  * new intensity value.
  */
-static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
+static GLint
+gamma_adjust( GLfloat gamma, GLint value, GLint max )
 {
    if (gamma == 1.0) {
       return value;
@@ -239,7 +221,7 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
 
 
 
-/*
+/**
  * Return the true number of bits per pixel for XImages.
  * For example, if we request a 24-bit deep visual we may actually need/get
  * 32bpp XImages.  This function returns the appropriate bpp.
@@ -247,10 +229,10 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
  *         visinfo - desribes the visual to be used for XImages
  * Return:  true number of bits per pixel for XImages
  */
-#ifdef XFree86Server
-
-static int bits_per_pixel( XMesaVisual xmv )
+static int
+bits_per_pixel( XMesaVisual xmv )
 {
+#ifdef XFree86Server
    const int depth = xmv->nplanes;
    int i;
    assert(depth > 0);
@@ -259,12 +241,7 @@ static int bits_per_pixel( XMesaVisual xmv )
          return screenInfo.formats[i].bitsPerPixel;
    }
    return depth;  /* should never get here, but this should be safe */
-}
-
 #else
-
-static int bits_per_pixel( XMesaVisual xmv )
-{
    XMesaDisplay *dpy = xmv->display;
    XMesaVisualInfo visinfo = xmv->visinfo;
    XMesaImage *img;
@@ -285,8 +262,8 @@ static int bits_per_pixel( XMesaVisual xmv )
    img->data = NULL;
    XMesaDestroyImage( img );
    return bitsPerPixel;
-}
 #endif
+}
 
 
 
@@ -325,6 +302,45 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
 
 
 
+/**
+ * Return the size of the window (or pixmap) that corresponds to the
+ * given XMesaBuffer.
+ * \param width  returns width in pixels
+ * \param height  returns height in pixels
+ */
+void
+xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
+                      GLuint *width, GLuint *height)
+{
+#ifdef XFree86Server
+   *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
+   *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
+#else
+   Window root;
+   Status stat;
+   int xpos, ypos;
+   unsigned int w, h, bw, depth;
+
+   _glthread_LOCK_MUTEX(_xmesa_lock);
+   XSync(b->xm_visual->display, 0); /* added for Chromium */
+   stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
+                       &w, &h, &bw, &depth);
+   _glthread_UNLOCK_MUTEX(_xmesa_lock);
+
+   if (stat) {
+      *width = w;
+      *height = h;
+   }
+   else {
+      /* probably querying a window that's recently been destroyed */
+      _mesa_warning(NULL, "XGetGeometry failed!\n");
+      *width = *height = 1;
+   }
+#endif
+}
+
+
+
 /**********************************************************************/
 /*****                Linked list of XMesaBuffers                 *****/
 /**********************************************************************/
@@ -333,80 +349,110 @@ static XMesaBuffer XMesaBufferList = NULL;
 
 
 /**
- * Allocate a new XMesaBuffer, initialize basic fields and add to
- * the list of all buffers.
+ * Allocate a new XMesaBuffer object which corresponds to the given drawable.
+ * Note that XMesaBuffer is derived from GLframebuffer.
+ * The new XMesaBuffer will not have any size (Width=Height=0).
+ *
+ * \param d  the corresponding X drawable (window or pixmap)
+ * \param type  either WINDOW, PIXMAP or PBUFFER, describing d
+ * \param vis  the buffer's visual
+ * \param cmap  the window's colormap, if known.
+ * \return new XMesaBuffer or NULL if any problem
  */
 static XMesaBuffer
-alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap)
+create_xmesa_buffer(XMesaDrawable d, BufferType type,
+                    XMesaVisual vis, XMesaColormap cmap)
 {
-   XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
-   if (b) {
-      GLboolean swAlpha;
+   GLboolean swAlpha;
+   XMesaBuffer b;
 
-      b->display = vis->display;
-      b->xm_visual = vis;
-      b->type = type;
-      b->cmap = cmap;
+   ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
 
-      _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
+   b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
+   if (!b)
+      return NULL;
+
+   b->display = vis->display;
+   b->xm_visual = vis;
+   b->type = type;
+   b->cmap = cmap;
 
-      /* Allocate the framebuffer's renderbuffers */
-      assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
-      assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+   _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
 
-      /* front renderbuffer */
-      b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
+   /*
+    * Front renderbuffer
+    */
+   b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
                                            GL_FALSE);
-      _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
-                             &b->frontxrb->Base);
-
-      /* back renderbuffer */
-      if (vis->mesa_visual.doubleBufferMode) {
-         b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
-                                             GL_TRUE);
-         /* determine back buffer implementation */
-         b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
-
-         _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
-                                &b->backxrb->Base);
-      }
+   if (!b->frontxrb) {
+      _mesa_free(b);
+      return NULL;
+   }
+   b->frontxrb->Parent = b;
+   b->frontxrb->drawable = d;
+   b->frontxrb->pixmap = (XMesaPixmap) d;
+   _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
+                          &b->frontxrb->Base);
 
-      /* determine if we need software alpha planes */
-      if (vis->mesa_visual.alphaBits > 0
-          && vis->undithered_pf != PF_8A8B8G8R
-          && vis->undithered_pf != PF_8A8R8G8B) {
-         /* Visual has alpha, but pixel format doesn't support it.
-          * We'll use an alpha renderbuffer wrapper.
-          */
-         swAlpha = GL_TRUE;
-      }
-      else {
-         swAlpha = GL_FALSE;
+   /*
+    * Back renderbuffer
+    */
+   if (vis->mesa_visual.doubleBufferMode) {
+      b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
+                                          GL_TRUE);
+      if (!b->backxrb) {
+         /* XXX free front xrb too */
+         _mesa_free(b);
+         return NULL;
       }
+      b->backxrb->Parent = b;
+      /* determine back buffer implementation */
+      b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
+      
+      _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
+                             &b->backxrb->Base);
+   }
 
-      _mesa_add_soft_renderbuffers(&b->mesa_buffer,
-                                   GL_FALSE,  /* color */
-                                   vis->mesa_visual.haveDepthBuffer,
-                                   vis->mesa_visual.haveStencilBuffer,
-                                   vis->mesa_visual.haveAccumBuffer,
-                                   swAlpha,
-                                   vis->mesa_visual.numAuxBuffers > 0 );
-
-      /* insert into linked list */
-      b->Next = XMesaBufferList;
-      XMesaBufferList = b;
+   /*
+    * Software alpha planes
+    */
+   if (vis->mesa_visual.alphaBits > 0
+       && vis->undithered_pf != PF_8A8B8G8R
+       && vis->undithered_pf != PF_8A8R8G8B) {
+      /* Visual has alpha, but pixel format doesn't support it.
+       * We'll use an alpha renderbuffer wrapper.
+       */
+      swAlpha = GL_TRUE;
+   }
+   else {
+      swAlpha = GL_FALSE;
    }
+
+   /*
+    * Other renderbuffer (depth, stencil, etc)
+    */
+   _mesa_add_soft_renderbuffers(&b->mesa_buffer,
+                                GL_FALSE,  /* color */
+                                vis->mesa_visual.haveDepthBuffer,
+                                vis->mesa_visual.haveStencilBuffer,
+                                vis->mesa_visual.haveAccumBuffer,
+                                swAlpha,
+                                vis->mesa_visual.numAuxBuffers > 0 );
+   
+   /* insert buffer into linked list */
+   b->Next = XMesaBufferList;
+   XMesaBufferList = b;
+
    return b;
 }
 
 
-/*
+/**
  * Find an XMesaBuffer by matching X display and colormap but NOT matching
  * the notThis buffer.
  */
-static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
-                                     XMesaColormap cmap,
-                                     XMesaBuffer notThis)
+static XMesaBuffer
+find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
 {
    XMesaBuffer b;
    for (b=XMesaBufferList; b; b=b->Next) {
@@ -418,11 +464,12 @@ static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
 }
 
 
-/*
+/**
  * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
  * entries.
  */
-static void free_xmesa_buffer(int client, XMesaBuffer buffer)
+static void
+free_xmesa_buffer(int client, XMesaBuffer buffer)
 {
    XMesaBuffer prev = NULL, b;
    (void) client;
@@ -461,8 +508,11 @@ static void free_xmesa_buffer(int client, XMesaBuffer buffer)
 }
 
 
-/* Copy X color table stuff from one XMesaBuffer to another. */
-static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
+/**
+ * Copy X color table stuff from one XMesaBuffer to another.
+ */
+static void
+copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
 {
    MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
    MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
@@ -481,198 +531,6 @@ static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
 
 
 /**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- * Return:  GL_TRUE if success, GL_FALSE if error
- */
-#ifndef XFree86Server
-static GLboolean
-alloc_shm_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
-{
-#ifdef USE_XSHM
-   /*
-    * We have to do a _lot_ of error checking here to be sure we can
-    * really use the XSHM extension.  It seems different servers trigger
-    * errors at different points if the extension won't work.  Therefore
-    * we have to be very careful...
-    */
-   GC gc;
-   int (*old_handler)( XMesaDisplay *, XErrorEvent * );
-
-   if (width == 0 || height == 0) {
-      /* this will be true the first time we're called on 'b' */
-      return GL_FALSE;
-   }
-
-   b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
-                                        b->xm_visual->visinfo->visual,
-                                        b->xm_visual->visinfo->depth,
-                                        ZPixmap, NULL, &b->shminfo,
-                                        width, height);
-   if (b->backxrb->ximage == NULL) {
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
-                            * b->backxrb->ximage->height, IPC_CREAT|0777 );
-   if (b->shminfo.shmid < 0) {
-      _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
-      XDestroyImage( b->backxrb->ximage );
-      b->backxrb->ximage = NULL;
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.shmaddr = b->backxrb->ximage->data
-                      = (char*)shmat( b->shminfo.shmid, 0, 0 );
-   if (b->shminfo.shmaddr == (char *) -1) {
-      _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
-      XDestroyImage( b->backxrb->ximage );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backxrb->ximage = NULL;
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.readOnly = False;
-   mesaXErrorFlag = 0;
-   old_handler = XSetErrorHandler( mesaHandleXError );
-   /* This may trigger the X protocol error we're ready to catch: */
-   XShmAttach( b->xm_visual->display, &b->shminfo );
-   XSync( b->xm_visual->display, False );
-
-   if (mesaXErrorFlag) {
-      /* we are on a remote display, this error is normal, don't print it */
-      XFlush( b->xm_visual->display );
-      mesaXErrorFlag = 0;
-      XDestroyImage( b->backxrb->ximage );
-      shmdt( b->shminfo.shmaddr );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backxrb->ximage = NULL;
-      b->shm = 0;
-      (void) XSetErrorHandler( old_handler );
-      return GL_FALSE;
-   }
-
-   shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
-
-   /* Finally, try an XShmPutImage to be really sure the extension works */
-   gc = XCreateGC( b->xm_visual->display, b->frontxrb->drawable, 0, NULL );
-   XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, gc,
-                b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
-   XSync( b->xm_visual->display, False );
-   XFreeGC( b->xm_visual->display, gc );
-   (void) XSetErrorHandler( old_handler );
-   if (mesaXErrorFlag) {
-      XFlush( b->xm_visual->display );
-      mesaXErrorFlag = 0;
-      XDestroyImage( b->backxrb->ximage );
-      shmdt( b->shminfo.shmaddr );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backxrb->ximage = NULL;
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-#else
-   /* Can't compile XSHM support */
-   return GL_FALSE;
-#endif
-}
-#endif
-
-
-
-
-/*
- * Setup an off-screen pixmap or Ximage to use as the back buffer.
- * Input:  b - the X/Mesa buffer
- */
-void
-xmesa_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) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
-        if (b->shm) {
-           XShmDetach( b->xm_visual->display, &b->shminfo );
-           XDestroyImage( b->backxrb->ximage );
-           shmdt( b->shminfo.shmaddr );
-        }
-        else
-#endif
-          XMesaDestroyImage( b->backxrb->ximage );
-        b->backxrb->ximage = NULL;
-      }
-
-      /* Allocate new back buffer */
-#ifdef XFree86Server
-      /* Allocate a regular XImage for the back buffer. */
-      b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
-                                            width, height, NULL);
-      {
-#else
-      if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) {
-        /* Allocate a regular XImage for the back buffer. */
-        b->backxrb->ximage = XCreateImage( b->xm_visual->display,
-                                      b->xm_visual->visinfo->visual,
-                                      GET_VISUAL_DEPTH(b->xm_visual),
-                                     ZPixmap, 0,   /* format, offset */
-                                     NULL,
-                                      width, height,
-                                     8, 0 );  /* pad, bytes_per_line */
-#endif
-        if (!b->backxrb->ximage) {
-           _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
-            return;
-        }
-         b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height
-                                        * b->backxrb->ximage->bytes_per_line );
-         if (!b->backxrb->ximage->data) {
-            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
-            XMesaDestroyImage( b->backxrb->ximage );
-            b->backxrb->ximage = NULL;
-         }
-         else {
-            /* this call just updates the width/origin fields in the xrb */
-            b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base, 
-                                          b->backxrb->Base.InternalFormat,
-                                          b->backxrb->ximage->width,
-                                          b->backxrb->ximage->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 );
-      }
-      /* 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;
-   }
-}
-
-
-
-/*
  * A replacement for XAllocColor.  This function should never
  * fail to allocate a color.  When XAllocColor fails, we return
  * the nearest matching color.  If we have to allocate many colors
@@ -715,10 +573,11 @@ noFaultXAllocColor( int client,
    if (AllocColor(cmap,
                  &color->red, &color->green, &color->blue,
                  &color->pixel,
-                 client) == Success) {
+                 client) == Success)
 #else
-   if (XAllocColor(dpy, cmap, color)) {
+   if (XAllocColor(dpy, cmap, color))
 #endif
+   {
       *exact = 1;
       *alloced = 1;
       return;
@@ -808,13 +667,13 @@ noFaultXAllocColor( int client,
 
 
 
-
-/*
+/**
  * Do setup for PF_GRAYSCALE pixel format.
  * Note that buffer may be NULL.
  */
-static GLboolean setup_grayscale( int client, XMesaVisual v,
-                                  XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_grayscale(int client, XMesaVisual v,
+                XMesaBuffer buffer, XMesaColormap cmap)
 {
    if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
       return GL_FALSE;
@@ -893,7 +752,7 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
 
 
 
-/*
+/**
  * Setup RGB rendering for a window with a PseudoColor, StaticColor,
  * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
  * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
@@ -901,8 +760,9 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
  * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
  * Dithering code contributed by Bob Mercier.
  */
-static GLboolean setup_dithered_color( int client, XMesaVisual v,
-                                       XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_dithered_color(int client, XMesaVisual v,
+                     XMesaBuffer buffer, XMesaColormap cmap)
 {
    if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
       return GL_FALSE;
@@ -972,12 +832,13 @@ static GLboolean setup_dithered_color( int client, XMesaVisual v,
 }
 
 
-/*
+/**
  * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
  * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
  * Special dithering tables have to be initialized.
  */
-static void setup_8bit_hpcr( XMesaVisual v )
+static void
+setup_8bit_hpcr(XMesaVisual v)
 {
    /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
     * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
@@ -1027,11 +888,11 @@ static void setup_8bit_hpcr( XMesaVisual v )
 }
 
 
-/*
+/**
  * Setup RGB rendering for a window with a True/DirectColor visual.
  */
-static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
-                             XMesaColormap cmap )
+static void
+setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
 {
    unsigned long rmask, gmask, bmask;
    (void) buffer;
@@ -1171,10 +1032,11 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
 
 
 
-/*
+/**
  * Setup RGB rendering for a window with a monochrome visual.
  */
-static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
+static void
+setup_monochrome( XMesaVisual v, XMesaBuffer b )
 {
    (void) b;
    v->dithered_pf = v->undithered_pf = PF_1Bit;
@@ -1205,7 +1067,7 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
    v->BitsPerPixel = bits_per_pixel(v);
    assert(v->BitsPerPixel > 0);
 
-   if (rgb_flag==GL_FALSE) {
+   if (rgb_flag == GL_FALSE) {
       /* COLOR-INDEXED WINDOW:
        * Even if the visual is TrueColor or DirectColor we treat it as
        * being color indexed.  This is weird but might be useful to someone.
@@ -1264,14 +1126,14 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
    if (b && window) {
       /* Do window-specific initializations */
 
-      b->frontxrb->drawable = window;
-      b->frontxrb->pixmap = (XMesaPixmap) window;
+      /* these should have been set in create_xmesa_buffer */
+      ASSERT(b->frontxrb->drawable == window);
+      ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
 
       /* Setup for single/double buffering */
       if (v->mesa_visual.doubleBufferMode) {
          /* Double buffered */
          b->shm = check_for_xshm( v->display );
-         xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
       }
 
       /* X11 graphics contexts */
@@ -1732,13 +1594,13 @@ void XMesaDestroyContext( XMesaContext c )
 
 
 
-/*
- * XXX this isn't a public function!  It's a hack for the 3Dfx driver.
- * Create a new XMesaBuffer from an X window.
- * Input:  v - the XMesaVisual
- *         w - the window
- *         c - the context
- * Return:  new XMesaBuffer or NULL if error
+/**
+ * Private function for creating an XMesaBuffer which corresponds to an
+ * X window or pixmap.
+ * \param v  the window's XMesaVisual
+ * \param w  the window we're wrapping
+ * \param c  context used to initialize the buffer if 3Dfx mode in use.
+ * \return  new XMesaBuffer or NULL if error
  */
 XMesaBuffer
 XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
@@ -1754,6 +1616,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
    XMesaColormap cmap;
 
    assert(v);
+   assert(w);
    (void) c;
 
    /* Check that window depth matches visual depth */
@@ -1790,10 +1653,9 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
    }
 #endif
 
-   b = alloc_xmesa_buffer(v, WINDOW, cmap);
-   if (!b) {
+   b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
+   if (!b)
       return NULL;
-   }
 
    if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
                                       (XMesaDrawable) w, cmap )) {
@@ -1908,10 +1770,9 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
 
    assert(v);
 
-   b = alloc_xmesa_buffer(v, PIXMAP, cmap);
-   if (!b) {
+   b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
+   if (!b)
       return NULL;
-   }
 
 #ifdef XFree86Server
    client = CLIENT_ID(((XMesaDrawable)p)->id);
@@ -1940,14 +1801,16 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
    XMesaDrawable drawable;  /* X Pixmap Drawable */
    XMesaBuffer b;
 
-   b = alloc_xmesa_buffer(v, PBUFFER, cmap);
-   if (!b) {
-      return NULL;
-   }
-
    /* allocate pixmap for front buffer */
    root = RootWindow( v->display, v->visinfo->screen );
-   drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth );
+   drawable = XCreatePixmap(v->display, root, width, height,
+                            v->visinfo->depth);
+   if (!drawable)
+      return NULL;
+
+   b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
+   if (!b)
+      return NULL;
 
    if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
                                     drawable, cmap)) {
@@ -2009,6 +1872,27 @@ void XMesaDestroyBuffer( XMesaBuffer b )
 }
 
 
+/**
+ * Query the current window size and update the corresponding GLframebuffer
+ * and all attached renderbuffers.
+ * Called when:
+ *  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.
+ */
+void
+xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+{
+   GLuint width, height;
+   xmesa_get_window_size(xmctx->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);
+   }
+   drawBuffer->mesa_buffer.Initialized = GL_TRUE;
+}
+
 
 /*
  * Bind buffer b to context c and make c the current rendering context.
@@ -2041,7 +1925,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
       if (&(c->mesa) == _mesa_get_current_context()
           && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
           && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
-          && ((XMesaBuffer) c->mesa.DrawBuffer)->wasCurrent) {
+          && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
          /* same context and buffer, do nothing */
          return GL_TRUE;
       }
@@ -2053,6 +1937,12 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
        */
       _glapi_check_multithread();
 
+      if (!drawBuffer->mesa_buffer.Initialized)
+         xmesa_check_and_update_buffer_size(c, drawBuffer);
+
+      if (!readBuffer->mesa_buffer.Initialized)
+         xmesa_check_and_update_buffer_size(c, readBuffer);
+
       _mesa_make_current(&(c->mesa),
                          &drawBuffer->mesa_buffer,
                          &readBuffer->mesa_buffer);
@@ -2123,7 +2013,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
 {
    GET_CURRENT_CONTEXT(ctx);
    if (ctx) {
-      return (XMesaBuffer) (ctx->ReadBuffer);
+      return XMESA_BUFFER(ctx->ReadBuffer);
    }
    else {
       return 0;
@@ -2212,9 +2102,7 @@ static void FXgetImage( XMesaBuffer b )
    GET_CURRENT_CONTEXT(ctx);
    static unsigned short pixbuf[MAX_WIDTH];
    GLuint x, y;
-   int xpos, ypos;
-   XMesaWindow root;
-   unsigned int bw, depth, width, height;
+   GLuint width, height;
    XMesaContext xmesa = XMESA_CONTEXT(ctx);
 
 #ifdef XFree86Server
@@ -2224,15 +2112,14 @@ static void FXgetImage( XMesaBuffer b )
    height = b->frontxrb->pixmap->height;
    depth = b->frontxrb->pixmap->depth;
 #else
-   XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
-                 &root, &xpos, &ypos, &width, &height, &bw, &depth);
+   xmesa_get_window_size(b->display, b, &width, &height);
+   x = y = 0;
 #endif
    if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
       b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
       b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
       if (b->mesa_buffer.Width & 1)
          b->mesa_buffer.Width--;  /* prevent odd width */
-      xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
    }
 
    /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
@@ -2646,24 +2533,11 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
  * This is typically called when the window size changes and we need
  * to reallocate the buffer's back/depth/stencil/accum buffers.
  */
-void XMesaResizeBuffers( XMesaBuffer b )
+void
+XMesaResizeBuffers( XMesaBuffer b )
 {
-#ifdef XFree86Server
-   GLuint winwidth, winheight;
    GET_CURRENT_CONTEXT(ctx);
-
-   winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
-   winheight = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
-
-   xmesa_resize_buffers(ctx, &(b->mesa_buffer), winwidth, winheight);
-#else
-   Window root;
-   int xpos, ypos;
-   unsigned int width, height, bw, depth;
-   GET_CURRENT_CONTEXT(ctx);
-   XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
-                 &root, &xpos, &ypos, &width, &height, &bw, &depth);
-   xmesa_resize_buffers(ctx, &(b->mesa_buffer), width, height);
-#endif
+   XMesaContext xmctx = XMESA_CONTEXT(ctx);
+   xmesa_check_and_update_buffer_size(xmctx, b);
 }
 
index 2a44e12..98ae372 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  6.5.2
  *
- * 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"),
  */
 
 
+/**
+ * \file xm_buffer.h
+ * Framebuffer and renderbuffer-related functions.
+ */
+
+
 #include "glxheader.h"
 #include "GL/xmesa.h"
 #include "xmesaP.h"
 #include "renderbuffer.h"
 
 
+#ifndef XFree86Server
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event)
+{
+   (void) dpy;
+   (void) event;
+   mesaXErrorFlag = 1;
+   return 0;
+}
+#endif
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ * Return:  GL_TRUE if success, GL_FALSE if error
+ */
+#ifndef XFree86Server
+static GLboolean
+alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
+{
+#ifdef USE_XSHM
+   /*
+    * We have to do a _lot_ of error checking here to be sure we can
+    * really use the XSHM extension.  It seems different servers trigger
+    * errors at different points if the extension won't work.  Therefore
+    * we have to be very careful...
+    */
+   GC gc;
+   int (*old_handler)(XMesaDisplay *, XErrorEvent *);
+
+   if (width == 0 || height == 0) {
+      /* this will be true the first time we're called on 'b' */
+      return GL_FALSE;
+   }
+
+   b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
+                                        b->xm_visual->visinfo->visual,
+                                        b->xm_visual->visinfo->depth,
+                                        ZPixmap, NULL, &b->shminfo,
+                                        width, height);
+   if (b->backxrb->ximage == NULL) {
+      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
+      b->shm = 0;
+      return GL_FALSE;
+   }
+
+   b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
+                            * b->backxrb->ximage->height, IPC_CREAT|0777);
+   if (b->shminfo.shmid < 0) {
+      _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
+      XDestroyImage(b->backxrb->ximage);
+      b->backxrb->ximage = NULL;
+      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
+      b->shm = 0;
+      return GL_FALSE;
+   }
+
+   b->shminfo.shmaddr = b->backxrb->ximage->data
+                      = (char*)shmat(b->shminfo.shmid, 0, 0);
+   if (b->shminfo.shmaddr == (char *) -1) {
+      _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
+      XDestroyImage(b->backxrb->ximage);
+      shmctl(b->shminfo.shmid, IPC_RMID, 0);
+      b->backxrb->ximage = NULL;
+      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
+      b->shm = 0;
+      return GL_FALSE;
+   }
+
+   b->shminfo.readOnly = False;
+   mesaXErrorFlag = 0;
+   old_handler = XSetErrorHandler(mesaHandleXError);
+   /* This may trigger the X protocol error we're ready to catch: */
+   XShmAttach(b->xm_visual->display, &b->shminfo);
+   XSync(b->xm_visual->display, False);
+
+   if (mesaXErrorFlag) {
+      /* we are on a remote display, this error is normal, don't print it */
+      XFlush(b->xm_visual->display);
+      mesaXErrorFlag = 0;
+      XDestroyImage(b->backxrb->ximage);
+      shmdt(b->shminfo.shmaddr);
+      shmctl(b->shminfo.shmid, IPC_RMID, 0);
+      b->backxrb->ximage = NULL;
+      b->shm = 0;
+      (void) XSetErrorHandler(old_handler);
+      return GL_FALSE;
+   }
+
+   shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */
+
+   /* Finally, try an XShmPutImage to be really sure the extension works */
+   gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL);
+   XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
+                b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
+   XSync(b->xm_visual->display, False);
+   XFreeGC(b->xm_visual->display, gc);
+   (void) XSetErrorHandler(old_handler);
+   if (mesaXErrorFlag) {
+      XFlush(b->xm_visual->display);
+      mesaXErrorFlag = 0;
+      XDestroyImage(b->backxrb->ximage);
+      shmdt(b->shminfo.shmaddr);
+      shmctl(b->shminfo.shmid, IPC_RMID, 0);
+      b->backxrb->ximage = NULL;
+      b->shm = 0;
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+#else
+   /* Can't compile XSHM support */
+   return GL_FALSE;
+#endif
+}
+#endif
+
+
+
+/**
+ * Setup an off-screen pixmap or Ximage to use as the back buffer.
+ * Input:  b - the X/Mesa buffer
+ */
+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) {
+#if defined(USE_XSHM) && !defined(XFree86Server)
+        if (b->shm) {
+           XShmDetach(b->xm_visual->display, &b->shminfo);
+           XDestroyImage(b->backxrb->ximage);
+           shmdt(b->shminfo.shmaddr);
+        }
+        else
+#endif
+          XMesaDestroyImage(b->backxrb->ximage);
+        b->backxrb->ximage = NULL;
+      }
+
+      /* Allocate new back buffer */
+#ifdef XFree86Server
+      /* Allocate a regular XImage for the back buffer. */
+      b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
+                                            width, height, NULL);
+      {
+#else
+      if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
+        /* Allocate a regular XImage for the back buffer. */
+        b->backxrb->ximage = XCreateImage(b->xm_visual->display,
+                                      b->xm_visual->visinfo->visual,
+                                      GET_VISUAL_DEPTH(b->xm_visual),
+                                     ZPixmap, 0,   /* format, offset */
+                                     NULL,
+                                      width, height,
+                                     8, 0);  /* pad, bytes_per_line */
+#endif
+        if (!b->backxrb->ximage) {
+           _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
+            return;
+        }
+         b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height
+                                        * b->backxrb->ximage->bytes_per_line);
+         if (!b->backxrb->ximage->data) {
+            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
+            XMesaDestroyImage(b->backxrb->ximage);
+            b->backxrb->ximage = NULL;
+         }
+         else {
+            /* this call just updates the width/origin fields in the xrb */
+            b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base, 
+                                          b->backxrb->Base.InternalFormat,
+                                          b->backxrb->ximage->width,
+                                          b->backxrb->ximage->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);
+      }
+      /* 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;
+   }
+}
+
+
 static void
 xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
 {
@@ -68,7 +281,6 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
 /**
  * Reallocate renderbuffer storage for back color buffer.
- * XXX we should resize the back pixmap/ximage here.
  */
 static GLboolean
 xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
@@ -76,7 +288,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 {
    struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
 
+   /* reallocate the back buffer XImage or Pixmap */
+   assert(xrb->Parent);
+   alloc_back_buffer(xrb->Parent, width, height);
+
    /* same as front buffer */
+   /* XXX why is this here? */
    (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
 
    /* plus... */
index f484953..df2fc48 100644 (file)
  */
 
 
+/**
+ * \file xm_dd.h
+ * General device driver functions for Xlib driver.
+ */
+
 #include "glxheader.h"
 #include "bufferobj.h"
 #include "buffers.h"
@@ -89,47 +94,12 @@ const int xmesa_kernel1[16] = {
 };
 
 
-/*
- * Return the size (width, height) of the X window for the given GLframebuffer.
- * Output:  width - width of buffer in pixels.
- *          height - height of buffer in pixels.
- */
+/** XXX obsolete ***/
 static void
 get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
 {
-   /* We can do this cast because the first field in the XMesaBuffer
-    * struct is a GLframebuffer struct.  If this weren't true, we'd
-    * need a pointer from the GLframebuffer to the XMesaBuffer.
-    */
-   const XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
-   unsigned int winwidth, winheight;
-#ifdef XFree86Server
-   /* XFree86 GLX renderer */
-   winwidth = MIN2(xmBuffer->frontxrb->drawable->width, MAX_WIDTH);
-   winheight = MIN2(xmBuffer->frontxrb->drawable->height, MAX_HEIGHT);
-#else
-   Window root;
-   Status stat;
-   int winx, winy;
-   unsigned int bw, d;
-
-   _glthread_LOCK_MUTEX(_xmesa_lock);
-   XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */
-
-   stat = XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap,
-                 &root, &winx, &winy, &winwidth, &winheight, &bw, &d );
-   _glthread_UNLOCK_MUTEX(_xmesa_lock);
-
-   if (!stat) {
-      /* probably querying a window that's recently been destroyed */
-      _mesa_warning(NULL, "XGetGeometry failed!\n");
-      *width = *height = 1;
-      return;
-   }
-#endif
-
-   *width = winwidth;
-   *height = winheight;
+   XMesaBuffer b = XMESA_BUFFER(buffer);
+   xmesa_get_window_size(b->display, b, width, height);
 }
 
 
@@ -567,26 +537,6 @@ clear_buffers( GLcontext *ctx, GLbitfield mask,
 }
 
 
-/**
- * Called by ctx->Driver.ResizeBuffers()
- * Resize the front/back colorbuffers to match the latest window size.
- */
-void
-xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
-                     GLuint width, GLuint height)
-{
-   /* We can do this cast because the first field in the XMesaBuffer
-    * struct is a GLframebuffer struct.  If this weren't true, we'd
-    * need a pointer from the GLframebuffer to the XMesaBuffer.
-    */
-   XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
-
-   xmesa_alloc_back_buffer(xmBuffer, width, height);
-
-   _mesa_resize_framebuffer(ctx, buffer, width, height);
-}
-
-
 #ifndef XFree86Server
 /* XXX this was never tested in the Xserver environment */
 
@@ -1121,33 +1071,6 @@ choose_tex_format( GLcontext *ctx, GLint internalFormat,
 
 
 /**
- * Get the current drawing (and reading) window's size and update the
- * corresponding gl_framebuffer(s) if needed.
- */
-static void
-update_framebuffer_size(GLcontext *ctx)
-{
-   struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
-   GLuint newWidth, newHeight;
-   get_buffer_size(fb, &newWidth, &newHeight);
-   if (newWidth != fb->Width || newHeight != fb->Height) {
-      xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
-   }
-
-   if (ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
-      /* Update readbuffer's size */
-      struct gl_framebuffer *fb = ctx->WinSysReadBuffer;
-      GLuint newWidth, newHeight;
-      get_buffer_size(fb, &newWidth, &newHeight);
-      if (newWidth != fb->Width || newHeight != fb->Height) {
-         xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
-         ctx->NewState |= _NEW_BUFFERS;
-      }
-   }
-}
-
-
-/**
  * Called by glViewport.
  * This is a good time for us to poll the current X window size and adjust
  * our renderbuffers to match the current window size.
@@ -1161,11 +1084,15 @@ update_framebuffer_size(GLcontext *ctx)
 static void
 xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
+   XMesaContext xmctx = XMESA_CONTEXT(ctx);
+   XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer);
+   XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer);
+   xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf);
+   xmesa_check_and_update_buffer_size(xmctx, xmreadbuf);
    (void) x;
    (void) y;
    (void) w;
    (void) h;
-   update_framebuffer_size(ctx);
 }
 
 
@@ -1258,7 +1185,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
    driver->ColorMask = color_mask;
    driver->Enable = enable;
    driver->Clear = clear_buffers;
-   driver->ResizeBuffers = xmesa_resize_buffers;
    driver->Viewport = xmesa_viewport;
 #ifndef XFree86Server
    driver->CopyPixels = xmesa_CopyPixels;
index 4db0872..86b01e8 100644 (file)
@@ -81,8 +81,9 @@ enum pixel_format {
 };
 
 
-/*
- * "Derived" from GLvisual.  Basically corresponds to an XVisualInfo.
+/**
+ * Visual inforation, derived from GLvisual.
+ * Basically corresponds to an XVisualInfo.
  */
 struct xmesa_visual {
    GLvisual mesa_visual;       /* Device independent visual parameters */
@@ -127,8 +128,9 @@ struct xmesa_visual {
 };
 
 
-/*
- * "Derived" from __GLcontextRec.  Basically corresponds to a GLXContext.
+/**
+ * Context info, dDerived from GLcontext.
+ * Basically corresponds to a GLXContext.
  */
 struct xmesa_context {
    GLcontext mesa;             /* the core library context (containment) */
@@ -146,7 +148,9 @@ struct xmesa_context {
 };
 
 
-
+/**
+ * Types of X/GLX drawables we might render into.
+ */
 typedef enum {
    WINDOW,          /* An X window */
    GLXWINDOW,       /* GLX window */
@@ -155,9 +159,11 @@ typedef enum {
 } BufferType;
 
 
-/* Values for db_mode: */
+/** Values for db_mode: */
+/*@{*/
 #define BACK_PIXMAP    1
 #define BACK_XIMAGE    2
+/*@}*/
 
 
 /**
@@ -175,6 +181,7 @@ struct xmesa_renderbuffer
 {
    struct gl_renderbuffer Base;  /* Base class */
 
+   XMesaBuffer Parent;  /**< The XMesaBuffer this renderbuffer belongs to */
    XMesaDrawable drawable;     /* Usually the X window ID */
    XMesaPixmap pixmap; /* Back color buffer */
    XMesaImage *ximage; /* The back buffer, if not using a Pixmap */
@@ -194,8 +201,9 @@ struct xmesa_renderbuffer
 };
 
 
-/*
- * "Derived" from GLframebuffer.  Basically corresponds to a GLXDrawable.
+/**
+ * Framebuffer information, derived from.
+ * Basically corresponds to a GLXDrawable.
  */
 struct xmesa_buffer {
    GLframebuffer mesa_buffer;  /* depth, stencil, accum, etc buffers */
@@ -264,7 +272,7 @@ struct xmesa_buffer {
 };
 
 
-/*
+/**
  * If pixelformat==PF_TRUECOLOR:
  */
 #define PACK_TRUECOLOR( PIXEL, R, G, B )       \
@@ -273,7 +281,7 @@ struct xmesa_buffer {
          | xmesa->xm_visual->BtoPixel[B];      \
 
 
-/*
+/**
  * If pixelformat==PF_TRUEDITHER:
  */
 #define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B )                        \
@@ -286,14 +294,14 @@ struct xmesa_buffer {
 
 
 
-/*
+/**
  * If pixelformat==PF_8A8B8G8R:
  */
 #define PACK_8A8B8G8R( R, G, B, A )    \
        ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
 
 
-/*
+/**
  * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
  * shortcut.
  */
@@ -301,19 +309,19 @@ struct xmesa_buffer {
 
 
 
-/*
+/**
  * If pixelformat==PF_8R8G8B:
  */
 #define PACK_8R8G8B( R, G, B)   ( ((R) << 16) | ((G) << 8) | (B) )
 
 
-/*
+/**
  * If pixelformat==PF_5R6G5B:
  */
 #define PACK_5R6G5B( R, G, B)   ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
 
 
-/*
+/**
  * If pixelformat==PF_8A8R8G8B:
  */
 #define PACK_8A8R8G8B( R, G, B, A )    \
@@ -321,7 +329,7 @@ struct xmesa_buffer {
 
 
 
-/*
+/**
  * If pixelformat==PF_DITHER:
  *
  * Improved 8-bit RGB dithering code contributed by Bob Mercier
@@ -398,7 +406,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
 
 
 
-/*
+/**
  * If pixelformat==PF_LOOKUP:
  */
 #define _dither_lookup(C, c)   (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12)
@@ -412,8 +420,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
                        _dither_lookup(DITH_B, (B)))]
 
 
-
-/*
+/**
  * If pixelformat==PF_HPCR:
  *
  *      HP Color Recovery dithering               (ad@lms.be 30/08/95)
@@ -433,7 +440,7 @@ extern const short xmesa_HPCR_DRGB[3][2][16];
 
 
 
-/*
+/**
  * If pixelformat==PF_1BIT:
  */
 extern const int xmesa_kernel1[16];
@@ -444,20 +451,20 @@ extern const int xmesa_kernel1[16];
 
 
 
-/*
+/**
  * If pixelformat==PF_GRAYSCALE:
  */
 #define GRAY_RGB( R, G, B )   XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3]
 
 
 
-/*
+/**
  * Converts a GL window Y coord to an X window Y coord:
  */
 #define YFLIP(XRB, Y)  ((XRB)->bottom - (Y))
 
 
-/*
+/**
  * Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
  * X==0 is left, Y==0 is bottom.
  */
@@ -475,23 +482,6 @@ extern const int xmesa_kernel1[16];
 
 
 
-
-/*
- * Return pointer to XMesaContext corresponding to a Mesa GLcontext.
- * Since we're using structure containment, it's just a cast!.
- * XXX should use inlined function for better type safety.
- */
-#define XMESA_CONTEXT(MESACTX)  ((XMesaContext) (MESACTX))
-
-/*
- * Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer.
- * Since we're using structure containment, it's just a cast!.
- * XXX should use inlined function for better type safety.
- */
-#define XMESA_BUFFER(MESABUFF)  ((XMesaBuffer) (MESABUFF))
-
-
-
 /*
  * External functions:
  */
@@ -506,21 +496,25 @@ xmesa_color_to_pixel( GLcontext *ctx,
                       GLuint pixelFormat );
 
 extern void
-xmesa_alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height);
+xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
+                      GLuint *width, GLuint *height);
 
-extern void xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
-                                 GLuint width, GLuint height);
+extern void
+xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
 
-extern void xmesa_init_driver_functions( XMesaVisual xmvisual,
-                                         struct dd_function_table *driver );
+extern void
+xmesa_init_driver_functions( XMesaVisual xmvisual,
+                             struct dd_function_table *driver );
 
-extern void xmesa_update_state( GLcontext *ctx, GLbitfield new_state );
+extern void
+xmesa_update_state( GLcontext *ctx, GLbitfield new_state );
 
 extern void
 xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
                              enum pixel_format pixelformat, GLint depth);
 
-extern void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
+extern void
+xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
 
 
 /**
@@ -533,6 +527,30 @@ xmesa_renderbuffer(struct gl_renderbuffer *rb)
 }
 
 
+/**
+ * Return pointer to XMesaContext corresponding to a Mesa GLcontext.
+ * Since we're using structure containment, it's just a cast!.
+ * XXX should use inlined function for better type safety.
+ */
+static INLINE XMesaContext
+XMESA_CONTEXT(GLcontext *ctx)
+{
+   return (XMesaContext) ctx;
+}
+
+
+/**
+ * Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer.
+ * Since we're using structure containment, it's just a cast!.
+ * XXX should use inlined function for better type safety.
+ */
+static INLINE XMesaBuffer
+XMESA_BUFFER(GLframebuffer *b)
+{
+   return (XMesaBuffer) b;
+}
+
+
 /* Plugged into the software rasterizer.  Try to use internal
  * swrast-style point, line and triangle functions.
  */