Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / winsys / xlib / xm_api.c
index 6b46327e21f07e35617ca4ebdaf118e4be55232c..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;
@@ -110,6 +110,9 @@ int xmesa_check_for_xshm( XMesaDisplay *display )
    int major, minor, ignore;
    Bool pixmaps;
 
+   if (getenv("SP_NO_RAST")) 
+      return 0;
+
    if (getenv("MESA_NOSHM")) {
       return 0;
    }
@@ -241,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 */
@@ -346,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)
@@ -360,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;
+      }
    }
 
 
@@ -511,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;
+      }
    }
 
    /*
@@ -762,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;
    }
 
@@ -786,8 +807,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
       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;
 
@@ -806,10 +833,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    mesaCtx->Const.CheckArrayBounds = GL_TRUE;
 #endif
 
-   /* finish up xmesa context initializations */
-   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;
 }
 
 
@@ -817,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);
 }
 
@@ -1266,6 +1303,7 @@ void XMesaFlush( XMesaContext c )
 #ifdef XFree86Server
       /* NOT_NEEDED */
 #else
+      st_finish(c->st);
       XSync( c->xm_visual->display, False );
 #endif
    }