cell: fix tile twidding bug seen in the event of multiple expose events
[mesa.git] / src / gallium / winsys / xlib / xm_api.c
index e5fef1d7a81abcb2684f137b6b0ffb97a8b62ad0..d28a6423b9e4a92ab6e52adede9bf5d525ed2b24 100644 (file)
 #include "xmesaP.h"
 #include "main/context.h"
 #include "main/framebuffer.h"
-#include "glapi/glthread.h"
 
 #include "state_tracker/st_public.h"
 #include "state_tracker/st_context.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 
 #include "xm_winsys_aub.h"
@@ -74,7 +74,7 @@
 /**
  * Global X driver lock
  */
-_glthread_Mutex _xmesa_lock;
+pipe_mutex _xmesa_lock;
 
 
 int xmesa_mode;
@@ -104,12 +104,19 @@ static int host_byte_order( void )
  *          1 = shared XImage support available
  *          2 = shared Pixmap support available also
  */
-static int check_for_xshm( XMesaDisplay *display )
+int xmesa_check_for_xshm( XMesaDisplay *display )
 {
 #if defined(USE_XSHM) && !defined(XFree86Server)
    int major, minor, ignore;
    Bool pixmaps;
 
+   if (getenv("SP_NO_RAST")) 
+      return 0;
+
+   if (getenv("MESA_NOSHM")) {
+      return 0;
+   }
+
    if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
       if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
         return (pixmaps==True) ? 2 : 1;
@@ -237,10 +244,10 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
 #else
    Status stat;
 
-   _glthread_LOCK_MUTEX(_xmesa_lock);
+   pipe_mutex_lock(_xmesa_lock);
    XSync(b->xm_visual->display, 0); /* added for Chromium */
    stat = get_drawable_size(dpy, b->drawable, width, height);
-   _glthread_UNLOCK_MUTEX(_xmesa_lock);
+   pipe_mutex_unlock(_xmesa_lock);
 
    if (!stat) {
       /* probably querying a window that's recently been destroyed */
@@ -342,12 +349,17 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
 
    if (vis->mesa_visual.depthBits == 0)
       depthFormat = PIPE_FORMAT_NONE;
+#ifdef GALLIUM_CELL /* XXX temporary for Cell! */
+   else
+      depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+#else
    else if (vis->mesa_visual.depthBits <= 16)
       depthFormat = PIPE_FORMAT_Z16_UNORM;
    else if (vis->mesa_visual.depthBits <= 24)
       depthFormat = PIPE_FORMAT_S8Z24_UNORM;
    else
       depthFormat = PIPE_FORMAT_Z32_UNORM;
+#endif
 
    if (vis->mesa_visual.stencilBits == 8) {
       if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
@@ -356,7 +368,12 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
          stencilFormat = PIPE_FORMAT_S8_UNORM;
    }
    else {
+      /* no stencil */
       stencilFormat = PIPE_FORMAT_NONE;
+      if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) {
+         /* use 24-bit Z, undefined stencil channel */
+         depthFormat = PIPE_FORMAT_X8Z24_UNORM;
+      }
    }
 
 
@@ -507,6 +524,14 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
         return GL_FALSE;
       }
       v->mesa_visual.indexBits = 0;
+
+      if (v->BitsPerPixel == 32) {
+         /* We use XImages for all front/back buffers.  If an X Window or
+          * X Pixmap is 32bpp, there's no guarantee that the alpha channel
+          * will be preserved.  For XImages we're in luck.
+          */
+         v->mesa_visual.alphaBits = 8;
+      }
    }
 
    /*
@@ -528,7 +553,7 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
       /* Setup for single/double buffering */
       if (v->mesa_visual.doubleBufferMode) {
          /* Double buffered */
-         b->shm = check_for_xshm( v->display );
+         b->shm = xmesa_check_for_xshm( v->display );
       }
 
       /* X11 graphics context */
@@ -758,7 +783,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    uint pf;
 
    if (firstTime) {
-      _glthread_INIT_MUTEX(_xmesa_lock);
+      pipe_mutex_init(_xmesa_lock);
       firstTime = GL_FALSE;
    }
 
@@ -770,17 +795,26 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    pf = choose_pixel_format(v);
    assert(pf);
 
+   c->xm_visual = v;
+   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
+
    if (!getenv("XM_AUB")) {
       xmesa_mode = XMESA_SOFTPIPE;
       pipe = xmesa_create_pipe_context( c, pf );
    }
    else {
       xmesa_mode = XMESA_AUB;
-      pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() );
+      pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v));
    }
 
+   if (pipe == NULL)
+      goto fail;
+
    c->st = st_create_context(pipe, &v->mesa_visual,
                              share_list ? share_list->st : NULL);
+   if (c->st == NULL)
+      goto fail;
+   
    mesaCtx = c->st->ctx;
    c->st->ctx->DriverCtx = c;
 
@@ -799,13 +833,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    mesaCtx->Const.CheckArrayBounds = GL_TRUE;
 #endif
 
-   /* finish up xmesa context initializations */
-   c->xm_visual = v;
-   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
-
-   c->st->haveFramebufferSurfaces = GL_TRUE;
-
    return c;
+
+ fail:
+   if (c->st)
+      st_destroy_context(c->st);
+   else if (pipe)
+      pipe->destroy(pipe);
+   FREE(c);
+   return NULL;
 }
 
 
@@ -813,7 +849,12 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
 PUBLIC
 void XMesaDestroyContext( XMesaContext c )
 {
+   struct pipe_screen *screen = c->st->pipe->screen;
    st_destroy_context(c->st);
+   /* FIXME: We should destroy the screen here, but if we do so, surfaces may 
+    * outlive it, causing segfaults
+   screen->destroy(screen);
+   */
    _mesa_free(c);
 }
 
@@ -1262,6 +1303,7 @@ void XMesaFlush( XMesaContext c )
 #ifdef XFree86Server
       /* NOT_NEEDED */
 #else
+      st_finish(c->st);
       XSync( c->xm_visual->display, False );
 #endif
    }