return True for GLX_Y_INVERTED_EXT query
[mesa.git] / src / mesa / drivers / x11 / xm_dd.c
index 5b3c89c1dd07978074bf5d122511afc768ce7f08..c8546236fbf3644b222a96e16149e7ddab152265 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  6.5.2
  *
- * Copyright (C) 1999-2004  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_dd.h
+ * General device driver functions for Xlib driver.
+ */
+
 #include "glxheader.h"
 #include "bufferobj.h"
 #include "buffers.h"
 #include "texstore.h"
 #include "texformat.h"
 #include "xmesaP.h"
-#include "array_cache/acache.h"
 #include "swrast/swrast.h"
 #include "swrast/s_context.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 
-#ifdef XFree86Server
-#include <GL/glxtokens.h>
-#endif
-
 
 
 /*
@@ -89,41 +89,6 @@ 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.
- */
-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->pixmap->width, MAX_WIDTH);
-   winheight = MIN2(xmBuffer->frontxrb->pixmap->height, MAX_HEIGHT);
-#else
-   Window root;
-   int winx, winy;
-   unsigned int bw, d;
-
-   _glthread_LOCK_MUTEX(_xmesa_lock);
-   XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */
-   XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap, &root,
-                &winx, &winy, &winwidth, &winheight, &bw, &d );
-   _glthread_UNLOCK_MUTEX(_xmesa_lock);
-#endif
-
-   *width = winwidth;
-   *height = winheight;
-}
-
-
 static void
 finish_or_flush( GLcontext *ctx )
 {
@@ -140,71 +105,6 @@ finish_or_flush( GLcontext *ctx )
 }
 
 
-
-/**
- * This chooses the color buffer for reading and writing spans, points,
- * lines, and triangles.
- * Remember that a GLframebuffer has several distinct color buffers:
- * front/left, front/right, back/left, back/right and aux buffers.
- * The bufferBit specifies which one to use.
- */
-void
-xmesa_set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
-{
-#if 000
-   /* We can make this cast since the XMesaBuffer wraps GLframebuffer.
-    * GLframebuffer is the first member in a XMesaBuffer struct.
-    */
-   XMesaBuffer target = (XMesaBuffer) buffer;
-   const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-
-#if NEW_RENDERBUFFER
-   if (buffer->Name != 0)
-      return;
-#endif
-
-   /* This assignment tells the span/point/line/triangle functions
-    * which XMesaBuffer to use.
-    */
-   /*   xmesa->xm_buffer = target;*/
-
-   /*
-    * Now determine front vs back color buffer.
-    */
-   if (bufferBit == BUFFER_BIT_FRONT_LEFT) {
-      target->buffer = target->frontxrb->pixmap;
-      printf("set get/put!\n");
-      xmesa_update_span_funcs(ctx);
-   }
-   else if (bufferBit == BUFFER_BIT_BACK_LEFT) {
-      ASSERT(target->db_state);
-      if (target->backxrb->pixmap) {
-         /* back buffer is a pixmap */
-         target->buffer = (XMesaDrawable) target->backxrb->pixmap;
-      }
-      else if (target->backimage) {
-         /* back buffer is an XImage */
-         target->buffer = None;
-      }
-      else {
-         /* No back buffer!!!!  Must be out of memory, use front buffer */
-         target->buffer = target->frontxrb->pixmap;
-      }
-      printf("set get/put!\n");
-      xmesa_update_span_funcs(ctx);
-   }
-   else if (bufferBit & (BUFFER_BIT_AUX0 | BUFFER_BIT_AUX1 | BUFFER_BIT_AUX2 | BUFFER_BIT_AUX3)) {
-      /*_swrast_use_aux_buffer(ctx, buffer, bufferBit);*/
-   } 
-   else {
-      _mesa_problem(ctx, "invalid buffer 0x%x in set_buffer() in xm_dd.c");
-      return;
-   }
-#endif
-}
-
-
-
 static void
 clear_index( GLcontext *ctx, GLuint index )
 {
@@ -270,10 +170,15 @@ color_mask(GLcontext *ctx,
            GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-   XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+   XMesaBuffer xmbuf;
    const int xclass = xmesa->xm_visual->mesa_visual.visualType;
    (void) amask;
 
+   if (ctx->DrawBuffer->Name != 0)
+      return;
+
+   xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+
    if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
       unsigned long m;
       if (rmask && gmask && bmask) {
@@ -301,7 +206,7 @@ color_mask(GLcontext *ctx,
  * Clear the front or back color buffer, if it's implemented with a pixmap.
  */
 static void
-clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLboolean all,
+clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
              GLint x, GLint y, GLint width, GLint height)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
@@ -314,91 +219,41 @@ clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLboolean all,
    assert(xrb->pixmap);
    assert(xmbuf->cleargc);
 
-   if (all) {
-      XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc,
-                          0, 0, xrb->Base.Width + 1, xrb->Base.Height + 1 );
-   }
-   else {
-      XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc,
-                          x, xrb->Base.Height - y - height,
-                          width, height );
-   }
+   XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc,
+                       x, xrb->Base.Height - y - height,
+                       width, height );
 }
 
 
 static void
 clear_8bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                   GLboolean all, GLint x, GLint y, GLint width, GLint height )
+                   GLint x, GLint y, GLint width, GLint height )
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-
-   if (all) {
-      const size_t n = xrb->ximage->bytes_per_line * xrb->Base.Height;
-      MEMSET( xrb->ximage->data, xmesa->clearpixel, n );
-   }
-   else {
-      GLint i;
-      for (i=0;i<height;i++) {
-         GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i);
-         MEMSET( ptr, xmesa->clearpixel, width );
-      }
+   GLint i;
+   for (i = 0; i < height; i++) {
+      GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i);
+      MEMSET( ptr, xmesa->clearpixel, width );
    }
 }
 
 
 static void
 clear_HPCR_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                   GLboolean all, GLint x, GLint y, GLint width, GLint height )
+                   GLint x, GLint y, GLint width, GLint height )
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-
-   if (all) {
-      GLint i, c16 = (xrb->ximage->bytes_per_line>>4)<<4;
-      GLubyte *ptr  = (GLubyte *) xrb->ximage->data;
-      for (i = 0; i < xrb->Base.Height; i++) {
-         GLint j;
-         GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
-         if (i&1) {
-            sptr += 16;
-         }
-         for (j=0; j<c16; j+=16) {
-            ptr[0] = sptr[0];
-            ptr[1] = sptr[1];
-            ptr[2] = sptr[2];
-            ptr[3] = sptr[3];
-            ptr[4] = sptr[4];
-            ptr[5] = sptr[5];
-            ptr[6] = sptr[6];
-            ptr[7] = sptr[7];
-            ptr[8] = sptr[8];
-            ptr[9] = sptr[9];
-            ptr[10] = sptr[10];
-            ptr[11] = sptr[11];
-            ptr[12] = sptr[12];
-            ptr[13] = sptr[13];
-            ptr[14] = sptr[14];
-            ptr[15] = sptr[15];
-            ptr += 16;
-         }
-         for (; j < xrb->ximage->bytes_per_line; j++) {
-            *ptr = sptr[j&15];
-            ptr++;
-         }
+   GLint i;
+   for (i = y; i < y + height; i++) {
+      GLubyte *ptr = PIXEL_ADDR1( xrb, x, i );
+      int j;
+      const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
+      if (i & 1) {
+         sptr += 16;
       }
-   }
-   else {
-      GLint i;
-      for (i=y; i<y+height; i++) {
-         GLubyte *ptr = PIXEL_ADDR1( xrb, x, i );
-         int j;
-         const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0];
-         if (i&1) {
-            sptr += 16;
-         }
-         for (j=x; j<x+width; j++) {
-            *ptr = sptr[j&15];
-            ptr++;
-         }
+      for (j = x; j < x + width; j++) {
+         *ptr = sptr[j&15];
+         ptr++;
       }
    }
 }
@@ -406,42 +261,20 @@ clear_HPCR_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb,
 
 static void
 clear_16bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                    GLboolean all, GLint x, GLint y, GLint width, GLint height)
+                    GLint x, GLint y, GLint width, GLint height)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-   register GLuint pixel = (GLuint) xmesa->clearpixel;
+   GLuint pixel = (GLuint) xmesa->clearpixel;
+   GLint i, j;
 
    if (xmesa->swapbytes) {
       pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00);
    }
 
-   if (all) {
-      GLuint *ptr4 = (GLuint *) xrb->ximage->data;
-      if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) {
-         /* low and high bytes are equal so use memset() */
-         const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height;
-         MEMSET( ptr4, pixel & 0xff, n );
-      }
-      else {
-         const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height / 4;
-         GLuint i;
-         pixel = pixel | (pixel<<16);
-         for (i = 0; i < n; i++) {
-            ptr4[i] = pixel;
-         }
-         ptr4 += n;
-         /* might be one last GLushort to set */
-         if ((xrb->ximage->bytes_per_line * xrb->Base.Height) & 0x2)
-            *(GLushort *)ptr4 = pixel & 0xffff;
-      }
-   }
-   else {
-      GLint i, j;
-      for (j=0;j<height;j++) {
-         GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j);
-         for (i=0;i<width;i++) {
-            *ptr2++ = pixel;
-         }
+   for (j = 0; j < height; j++) {
+      GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j);
+      for (i = 0; i < width; i++) {
+         ptr2[i] = pixel;
       }
    }
 }
@@ -450,61 +283,31 @@ clear_16bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb,
 /* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */
 static void
 clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                   GLboolean all, GLint x, GLint y, GLint width, GLint height)
+                   GLint x, GLint y, GLint width, GLint height)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    const GLubyte r = xmesa->clearcolor[0];
    const GLubyte g = xmesa->clearcolor[1];
    const GLubyte b = xmesa->clearcolor[2];
 
-   if (all) {
-      if (r == g && g == b) {
-         /* same value for all three components (gray) */
-         const GLint w3 = xrb->Base.Width * 3;
-         const GLint h = xrb->Base.Height;
-         GLint i;
-         for (i = 0; i < h; i++) {
-            bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i);
-            MEMSET(ptr3, r, w3);
-         }
-      }
-      else {
-         /* the usual case */
-         const GLint w = xrb->Base.Width;
-         const GLint h = xrb->Base.Height;
-         GLint i, j;
-         for (i = 0; i < h; i++) {
-            bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i);
-            for (j = 0; j < w; j++) {
-               ptr3->r = r;
-               ptr3->g = g;
-               ptr3->b = b;
-               ptr3++;
-            }
-         }
+   if (r == g && g == b) {
+      /* same value for all three components (gray) */
+      GLint j;
+      for (j = 0; j < height; j++) {
+         bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j);
+         MEMSET(ptr3, r, 3 * width);
       }
    }
    else {
-      /* only clear subrect of color buffer */
-      if (r == g && g == b) {
-         /* same value for all three components (gray) */
-         GLint j;
-         for (j=0;j<height;j++) {
-            bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j);
-            MEMSET(ptr3, r, 3 * width);
-         }
-      }
-      else {
-         /* non-gray clear color */
-         GLint i, j;
-         for (j = 0; j < height; j++) {
-            bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j);
-            for (i = 0; i < width; i++) {
-               ptr3->r = r;
-               ptr3->g = g;
-               ptr3->b = b;
-               ptr3++;
-            }
+      /* non-gray clear color */
+      GLint i, j;
+      for (j = 0; j < height; j++) {
+         bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j);
+         for (i = 0; i < width; i++) {
+            ptr3->r = r;
+            ptr3->g = g;
+            ptr3->b = b;
+            ptr3++;
          }
       }
    }
@@ -513,11 +316,14 @@ clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
 
 static void
 clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                   GLboolean all, GLint x, GLint y, GLint width, GLint height)
+                   GLint x, GLint y, GLint width, GLint height)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    register GLuint pixel = (GLuint) xmesa->clearpixel;
 
+   if (!xrb->ximage)
+      return;
+
    if (xmesa->swapbytes) {
       pixel = ((pixel >> 24) & 0x000000ff)
             | ((pixel >> 8)  & 0x0000ff00)
@@ -525,10 +331,12 @@ clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
             | ((pixel << 24) & 0xff000000);
    }
 
-   if (all) {
+   if (width == xrb->Base.Width && height == xrb->Base.Height) {
+      /* clearing whole buffer */
       const GLuint n = xrb->Base.Width * xrb->Base.Height;
       GLuint *ptr4 = (GLuint *) xrb->ximage->data;
       if (pixel == 0) {
+         /* common case */
          _mesa_memset(ptr4, pixel, 4 * n);
       }
       else {
@@ -538,6 +346,7 @@ clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
       }
    }
    else {
+      /* clearing scissored region */
       GLint i, j;
       for (j = 0; j < height; j++) {
          GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y + j);
@@ -551,15 +360,12 @@ clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
 
 static void
 clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
-                  GLboolean all, GLint x, GLint y, GLint width, GLint height)
+                  GLint x, GLint y, GLint width, GLint height)
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    XMesaImage *img = xrb->ximage;
    GLint i, j;
 
-   /* We can ignore 'all' here - x, y, width, height are always right */
-   (void) all;
-
    /* TODO: optimize this */
    y = YFLIP(xrb, y);
    for (j = 0; j < height; j++) {
@@ -572,65 +378,46 @@ clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb,
 
 
 static void
-clear_buffers( GLcontext *ctx, GLbitfield mask,
-               GLboolean all, GLint x, GLint y, GLint width, GLint height )
+clear_buffers(GLcontext *ctx, GLbitfield buffers)
 {
    if (ctx->DrawBuffer->Name == 0) {
       /* this is a window system framebuffer */
       const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
-      XMesaBuffer b = (XMesaBuffer) ctx->DrawBuffer;
+      XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer);
+      const GLint x = ctx->DrawBuffer->_Xmin;
+      const GLint y = ctx->DrawBuffer->_Ymin;
+      const GLint width = ctx->DrawBuffer->_Xmax - x;
+      const GLint height = ctx->DrawBuffer->_Ymax - y;
 
       /* we can't handle color or index masking */
       if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
-         if (mask & BUFFER_BIT_FRONT_LEFT) {
+         if (buffers & BUFFER_BIT_FRONT_LEFT) {
             /* clear front color buffer */
-            if (b->frontxrb == (struct xmesa_renderbuffer *)
-                ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
+            struct gl_renderbuffer *frontRb
+               = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+            if (b->frontxrb == xmesa_renderbuffer(frontRb)) {
                /* renderbuffer is not wrapped - great! */
-               b->frontxrb->clearFunc(ctx, b->frontxrb, all, x, y,
-                                      width, height);
-               mask &= ~BUFFER_BIT_FRONT_LEFT;
+               b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height);
+               buffers &= ~BUFFER_BIT_FRONT_LEFT;
             }
             else {
                /* we can't directly clear an alpha-wrapped color buffer */
             }
          }
-         if (mask & BUFFER_BIT_BACK_LEFT) {
+         if (buffers & BUFFER_BIT_BACK_LEFT) {
             /* clear back color buffer */
-            if (b->backxrb == (struct xmesa_renderbuffer *)
-                ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer) {
+            struct gl_renderbuffer *backRb
+               = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+            if (b->backxrb == xmesa_renderbuffer(backRb)) {
                /* renderbuffer is not wrapped - great! */
-               b->backxrb->clearFunc(ctx, b->backxrb, all, x, y,
-                                     width, height);
-               mask &= ~BUFFER_BIT_BACK_LEFT;
+               b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height);
+               buffers &= ~BUFFER_BIT_BACK_LEFT;
             }
          }
       }
    }
-   if (mask)
-      _swrast_Clear( ctx, mask, all, x, y, width, height );
-}
-
-
-/**
- * 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);
-
-#if NEW_RENDERBUFFER
-   _mesa_resize_framebuffer(ctx, buffer, width, height);
-#endif
+   if (buffers)
+      _swrast_Clear(ctx, buffers);
 }
 
 
@@ -649,37 +436,37 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
                          const struct gl_pixelstore_attrib *unpack,
                          const GLvoid *pixels )
 {
-   struct xmesa_renderbuffer *xrb
-      = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0];
-
-   const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
-   XMesaDisplay *dpy = xmesa->xm_visual->display;
-   XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
-   const XMesaGC gc = xmbuf->gc;
-
-   ASSERT(dpy);
-   ASSERT(gc);
-   ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B);
-   ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B);
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped);
 
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
-   if (xrb->pixmap &&
+   if (ctx->DrawBuffer->Name == 0 &&
        format == GL_BGRA &&
        type == GL_UNSIGNED_BYTE &&
        (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */
        ctx->_ImageTransferState == 0 &&  /* no color tables, scale/bias, etc */
        ctx->Pixel.ZoomX == 1.0 &&        /* no zooming */
-       ctx->Pixel.ZoomY == 1.0) {
+       ctx->Pixel.ZoomY == 1.0 &&
+       xrb->pixmap &&
+       xrb->Base.AlphaBits == 0)
+   {
+      const XMesaContext xmesa = XMESA_CONTEXT(ctx);
+      XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+      XMesaDisplay *dpy = xmesa->xm_visual->display;
+      const XMesaGC gc = xmbuf->gc;
       int dstX = x;
       int dstY = y;
       int w = width;
       int h = height;
-      int srcX = unpack->SkipPixels;
-      int srcY = unpack->SkipRows;
-      int rowLength = unpack->RowLength ? unpack->RowLength : width;
+      struct gl_pixelstore_attrib clippedUnpack = *unpack;
+
+      ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B);
+      ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B);
+      ASSERT(dpy);
+      ASSERT(gc);
 
       if (unpack->BufferObj->Name) {
          /* unpack from PBO */
@@ -703,11 +490,14 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
          pixels = ADD_POINTERS(buf, pixels);
       }
 
-      if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
+      if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) {
          /* This is a little tricky since all coordinates up to now have
           * been in the OpenGL bottom-to-top orientation.  X is top-to-bottom
           * so we have to carefully compute the Y coordinates/addresses here.
           */
+         int srcX = clippedUnpack.SkipPixels;
+         int srcY = clippedUnpack.SkipRows;
+         int rowLength = clippedUnpack.RowLength;
          XMesaImage ximage;
          MEMSET(&ximage, 0, sizeof(XMesaImage));
          ximage.width = width;
@@ -756,7 +546,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
                          const GLvoid *pixels )
 {
    struct xmesa_renderbuffer *xrb
-      = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
    XMesaDisplay *dpy = xmesa->xm_visual->display;
@@ -782,9 +572,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
       int dstY = y;
       int w = width;
       int h = height;
-      int srcX = unpack->SkipPixels;
-      int srcY = unpack->SkipRows;
-      int rowLength = unpack->RowLength ? unpack->RowLength : width;
+      struct gl_pixelstore_attrib clippedUnpack = *unpack;
 
       if (unpack->BufferObj->Name) {
          /* unpack from PBO */
@@ -808,11 +596,14 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
          pixels = ADD_POINTERS(buf, pixels);
       }
 
-      if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) {
+      if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) {
          /* This is a little tricky since all coordinates up to now have
           * been in the OpenGL bottom-to-top orientation.  X is top-to-bottom
           * so we have to carefully compute the Y coordinates/addresses here.
           */
+         int srcX = clippedUnpack.SkipPixels;
+         int srcY = clippedUnpack.SkipRows;
+         int rowLength = clippedUnpack.RowLength;
          XMesaImage ximage;
          MEMSET(&ximage, 0, sizeof(XMesaImage));
          ximage.width = width;
@@ -861,10 +652,10 @@ xmesa_CopyPixels( GLcontext *ctx,
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
    XMesaDisplay *dpy = xmesa->xm_visual->display;
    const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc;
-   struct xmesa_renderbuffer *srcXrb = (struct xmesa_renderbuffer *)
-      ctx->ReadBuffer->_ColorReadBuffer;
-   struct xmesa_renderbuffer *dstXrb = (struct xmesa_renderbuffer *)
-      ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+   struct xmesa_renderbuffer *srcXrb
+      = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped);
+   struct xmesa_renderbuffer *dstXrb
+      = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
 
    ASSERT(dpy);
    ASSERT(gc);
@@ -1021,78 +812,74 @@ clear_color_HPCR_pixmap( GLcontext *ctx, const GLfloat color[4] )
 
 
 /**
- * Called when the driver should update it's state, based on the new_state
+ * Called when the driver should update its state, based on the new_state
  * flags.
  */
 void
-xmesa_update_state( GLcontext *ctx, GLuint new_state )
+xmesa_update_state( GLcontext *ctx, GLbitfield new_state )
 {
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
-   struct xmesa_renderbuffer *front_xrb, *back_xrb;
 
    /* Propagate statechange information to swrast and swrast_setup
     * modules.  The X11 driver has no internal GL-dependent state.
     */
    _swrast_InvalidateState( ctx, new_state );
-   _ac_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
+   _vbo_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
 
    if (ctx->DrawBuffer->Name != 0)
       return;
 
-   front_xrb = XMESA_BUFFER(ctx->DrawBuffer)->frontxrb;
-   if (front_xrb) {
-      /* XXX check for relevant new_state flags */
-      xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat,
-                                   xmesa->xm_visual->BitsPerPixel);
-      /* setup pointers to front and back buffer clear functions */
-      front_xrb->clearFunc = clear_pixmap;
-   }
-
-   back_xrb = XMESA_BUFFER(ctx->DrawBuffer)->backxrb;
-   if (back_xrb) {
+   /*
+    * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect
+    * renderbuffer span/clear funcs.
+    */
+   if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) {
       XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+      struct xmesa_renderbuffer *front_xrb, *back_xrb;
 
-      /* XXX check for relevant new_state flags */
-      xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat,
-                                   xmesa->xm_visual->BitsPerPixel);
-
-      if (xmbuf->backxrb->pixmap) {
-         back_xrb->clearFunc = clear_pixmap;
+      front_xrb = xmbuf->frontxrb;
+      if (front_xrb) {
+         xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat,
+                                      xmesa->xm_visual->BitsPerPixel);
+         front_xrb->clearFunc = clear_pixmap;
       }
-      else {
-         switch (xmesa->xm_visual->BitsPerPixel) {
-         case 8:
-            if (xmesa->xm_visual->hpcr_clear_flag) {
-               back_xrb->clearFunc = clear_HPCR_ximage;
-            }
-            else {
-               back_xrb->clearFunc = clear_8bit_ximage;
+
+      back_xrb = xmbuf->backxrb;
+      if (back_xrb) {
+         xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat,
+                                      xmesa->xm_visual->BitsPerPixel);
+         if (xmbuf->backxrb->pixmap) {
+            back_xrb->clearFunc = clear_pixmap;
+         }
+         else {
+            switch (xmesa->xm_visual->BitsPerPixel) {
+            case 8:
+               if (xmesa->xm_visual->hpcr_clear_flag) {
+                  back_xrb->clearFunc = clear_HPCR_ximage;
+               }
+               else {
+                  back_xrb->clearFunc = clear_8bit_ximage;
+               }
+               break;
+            case 16:
+               back_xrb->clearFunc = clear_16bit_ximage;
+               break;
+            case 24:
+               back_xrb->clearFunc = clear_24bit_ximage;
+               break;
+            case 32:
+               back_xrb->clearFunc = clear_32bit_ximage;
+               break;
+            default:
+               back_xrb->clearFunc = clear_nbit_ximage;
+               break;
             }
-            break;
-         case 16:
-            back_xrb->clearFunc = clear_16bit_ximage;
-            break;
-         case 24:
-            back_xrb->clearFunc = clear_24bit_ximage;
-            break;
-         case 32:
-            back_xrb->clearFunc = clear_32bit_ximage;
-            break;
-         default:
-            back_xrb->clearFunc = clear_nbit_ximage;
-            break;
          }
       }
    }
 
-#if OLD_RENDERBUFFER && 0
-   if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) {
-      xmesa_update_span_funcs(ctx);
-   }
-#endif
-
    if (xmesa->xm_visual->hpcr_clear_flag) {
       /* this depends on whether we're drawing to the front or back buffer */
       /* XXX FIX THIS! */
@@ -1176,33 +963,93 @@ choose_tex_format( GLcontext *ctx, GLint internalFormat,
  * Thus, we poll.
  * Note that this trick isn't fool-proof.  If the application never calls
  * glViewport, our notion of the current window size may be incorrect.
+ * That problem led to the GLX_MESA_resize_buffers extension.
  */
 static void
 xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
-#if 1
-   struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
-   GLuint newWidth, newHeight;
+   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;
+}
+
+
+#if ENABLE_EXT_timer_query
+
+/*
+ * The GL_EXT_timer_query extension is not enabled for the XServer
+ * indirect renderer.  Not sure about how/if wrapping of gettimeofday()
+ * is done, etc.
+ */
+
+struct xmesa_query_object
+{
+   struct gl_query_object Base;
+   struct timeval StartTime;
+};
 
-   /*
-   printf("%s before %d x %d\n", __FUNCTION__, fb->Width, fb->Height);
-   */
 
-   get_buffer_size(fb, &newWidth, &newHeight);
-   if (newWidth != fb->Width || newHeight != fb->Height) {
-      xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
-      ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
+static struct gl_query_object *
+xmesa_new_query_object(GLcontext *ctx, GLuint id)
+{
+   struct xmesa_query_object *q = CALLOC_STRUCT(xmesa_query_object);
+   if (q) {
+      q->Base.Id = id;
+      q->Base.Ready = GL_TRUE;
    }
-   /*
-   printf("%s after %d x %d\n", __FUNCTION__, fb->Width, fb->Height);
-   */
-#else
-   /* This also works: */
-   _mesa_ResizeBuffersMESA();
+   return &q->Base;
+}
+
+
+static void
+xmesa_begin_query(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+   if (target == GL_TIME_ELAPSED_EXT) {
+      struct xmesa_query_object *xq = (struct xmesa_query_object *) q;
+      (void) gettimeofday(&xq->StartTime, NULL);
+   }
+}
+
+
+/**
+ * Return the difference between the two given times in microseconds.
+ */
+#ifdef __VMS
+#define suseconds_t unsigned int
 #endif
+static GLuint64EXT
+time_diff(const struct timeval *t0, const struct timeval *t1)
+{
+   GLuint64EXT seconds0 = t0->tv_sec & 0xff;  /* 0 .. 255 seconds */
+   GLuint64EXT seconds1 = t1->tv_sec & 0xff;  /* 0 .. 255 seconds */
+   GLuint64EXT nanosec0 = (seconds0 * 1000000 + t0->tv_usec) * 1000;
+   GLuint64EXT nanosec1 = (seconds1 * 1000000 + t1->tv_usec) * 1000;
+   return nanosec1 - nanosec0;
 }
 
 
+static void
+xmesa_end_query(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+   if (target == GL_TIME_ELAPSED_EXT) {
+      struct xmesa_query_object *xq = (struct xmesa_query_object *) q;
+      struct timeval endTime;
+      (void) gettimeofday(&endTime, NULL);
+      /* result is in nanoseconds! */
+      q->Result = time_diff(&xq->StartTime, &endTime);
+   }
+   q->Ready = GL_TRUE;
+}
+
+#endif /* ENABLE_timer_query */
+
+
 /**
  * Initialize the device driver function table with the functions
  * we implement in this driver.
@@ -1213,7 +1060,7 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
 {
    driver->GetString = get_string;
    driver->UpdateState = xmesa_update_state;
-   driver->GetBufferSize = get_buffer_size;
+   driver->GetBufferSize = NULL; /* OBSOLETE */
    driver->Flush = finish_or_flush;
    driver->Finish = finish_or_flush;
    driver->ClearIndex = clear_index;
@@ -1222,7 +1069,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;
@@ -1235,11 +1081,17 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
    }
 #endif
    driver->TestProxyTexImage = test_proxy_teximage;
-#if SWTC
+#if ENABLE_EXT_texure_compression_s3tc
    driver->ChooseTextureFormat = choose_tex_format;
 #else
    (void) choose_tex_format;
 #endif
+
+#if ENABLE_EXT_timer_query
+   driver->NewQueryObject = xmesa_new_query_object;
+   driver->BeginQuery = xmesa_begin_query;
+   driver->EndQuery = xmesa_end_query;
+#endif
 }
 
 
@@ -1262,21 +1114,21 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
                             _SWRAST_NEW_RASTERMASK)
 
 
-/* Extend the software rasterizer with our line/point/triangle
+/**
+ * Extend the software rasterizer with our line/point/triangle
  * functions.
+ * Called during context creation only.
  */
 void xmesa_register_swrast_functions( GLcontext *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT( ctx );
-   struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx);
-
-   dd->SetBuffer = xmesa_set_buffer;
 
    swrast->choose_point = xmesa_choose_point;
    swrast->choose_line = xmesa_choose_line;
    swrast->choose_triangle = xmesa_choose_triangle;
 
-   swrast->invalidate_point |= XMESA_NEW_POINT;
-   swrast->invalidate_line |= XMESA_NEW_LINE;
-   swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE;
+   /* XXX these lines have no net effect.  Remove??? */
+   swrast->InvalidatePointMask |= XMESA_NEW_POINT;
+   swrast->InvalidateLineMask |= XMESA_NEW_LINE;
+   swrast->InvalidateTriangleMask |= XMESA_NEW_TRIANGLE;
 }