st/glx: Add xmesa_display to hold per-display variables.
authorChia-I Wu <olv@lunarg.com>
Sun, 14 Mar 2010 03:20:58 +0000 (11:20 +0800)
committerChia-I Wu <olv@lunarg.com>
Sun, 14 Mar 2010 03:27:53 +0000 (11:27 +0800)
This basically adds a static xmesa_display to collect per-display static
variables in xm_api.c.  Multiple display support is still missing, but
this is a step forward.

src/gallium/state_trackers/glx/xlib/xm_api.c
src/gallium/state_trackers/glx/xlib/xm_api.h

index 94c0ad496d43df78964ec86e8ec366baf2553267..e7c1979b4243723be2fb6a31624f2b5bc0f4c80f 100644 (file)
  * global.
  */
 static struct xm_driver driver;
+static struct st_api *stapi;
 
 void xmesa_set_driver( const struct xm_driver *templ )
 {
    driver = *templ;
+   stapi = driver.create_st_api();
 }
 
-/**
- * Global X driver lock
- */
-pipe_mutex _xmesa_lock;
+static XMesaDisplay
+xmesa_init_display( Display *display )
+{
+   pipe_static_mutex(init_mutex);
+   static struct xmesa_display xm_display;
+   XMesaDisplay xmdpy;
+   
+   pipe_mutex_lock(init_mutex);
+
+   /* TODO support for multiple displays */
+   xmdpy = &xm_display;
+
+   if (!xmdpy->display && display) {
+      xmdpy->display = display;
+      xmdpy->screen = driver.create_pipe_screen(display);
+      xmdpy->smapi = CALLOC_STRUCT(st_manager);
+      if (xmdpy->smapi)
+         xmdpy->smapi->screen = xmdpy->screen;
+
+      if (xmdpy->screen && xmdpy->smapi) {
+         pipe_mutex_init(xmdpy->mutex);
+      }
+      else {
+         if (xmdpy->screen) {
+            xmdpy->screen->destroy(xmdpy->screen);
+            xmdpy->screen = NULL;
+         }
+         if (xmdpy->smapi) {
+            FREE(xmdpy->smapi);
+            xmdpy->smapi = NULL;
+         }
 
-static struct pipe_screen *screen = NULL;
-static struct st_api *stapi = NULL;
-static struct st_manager *smapi = NULL;
+         xmdpy->display = NULL;
+      }
+   }
+   if (!xmdpy->display || xmdpy->display != display)
+      xmdpy = NULL;
 
+   pipe_mutex_unlock(init_mutex);
+
+   return xmdpy;
+}
 
 /**********************************************************************/
 /*****                     X Utility Functions                    *****/
@@ -194,12 +229,13 @@ void
 xmesa_get_window_size(Display *dpy, XMesaBuffer b,
                       GLuint *width, GLuint *height)
 {
+   XMesaDisplay xmdpy = xmesa_init_display(dpy);
    Status stat;
 
-   pipe_mutex_lock(_xmesa_lock);
+   pipe_mutex_lock(xmdpy->mutex);
    XSync(b->xm_visual->display, 0); /* added for Chromium */
    stat = get_drawable_size(dpy, b->ws.drawable, width, height);
-   pipe_mutex_unlock(_xmesa_lock);
+   pipe_mutex_unlock(xmdpy->mutex);
 
    if (!stat) {
       /* probably querying a window that's recently been destroyed */
@@ -278,7 +314,7 @@ choose_pixel_format(XMesaVisual v)
  * stencil sizes.
  */
 static enum pipe_format
-choose_depth_stencil_format(int depth, int stencil)
+choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
 {
    const enum pipe_texture_target target = PIPE_TEXTURE_2D;
    const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
@@ -287,8 +323,6 @@ choose_depth_stencil_format(int depth, int stencil)
    enum pipe_format formats[8], fmt;
    int count, i;
 
-   assert(screen);
-
    count = 0;
    if (depth <= 24 && stencil <= 8) {
       formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
@@ -304,7 +338,7 @@ choose_depth_stencil_format(int depth, int stencil)
 
    fmt = PIPE_FORMAT_NONE;
    for (i = 0; i < count; i++) {
-      if (screen->is_format_supported(screen, formats[i],
+      if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
                                       target, tex_usage, geom_flags)) {
          fmt = formats[i];
          break;
@@ -320,7 +354,7 @@ choose_depth_stencil_format(int depth, int stencil)
 /*****                Linked list of XMesaBuffers                 *****/
 /**********************************************************************/
 
-XMesaBuffer XMesaBufferList = NULL;
+static XMesaBuffer XMesaBufferList = NULL;
 
 
 /**
@@ -338,13 +372,13 @@ static XMesaBuffer
 create_xmesa_buffer(Drawable d, BufferType type,
                     XMesaVisual vis, Colormap cmap)
 {
+   XMesaDisplay xmdpy = xmesa_init_display(vis->display);
    XMesaBuffer b;
    uint width, height;
 
    ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
 
-   xmesa_init(vis->display);
-   if (!screen)
+   if (!xmdpy)
       return NULL;
 
    b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
@@ -364,7 +398,7 @@ create_xmesa_buffer(Drawable d, BufferType type,
    /*
     * Create framebuffer, but we'll plug in our own renderbuffers below.
     */
-   b->stfb = xmesa_create_st_framebuffer(screen, b);
+   b->stfb = xmesa_create_st_framebuffer(xmdpy->screen, b);
 
    /* GLX_EXT_texture_from_pixmap */
    b->TextureTarget = 0;
@@ -579,10 +613,12 @@ XMesaVisual XMesaCreateVisual( Display *display,
                                GLint level,
                                GLint visualCaveat )
 {
+   XMesaDisplay xmdpy = xmesa_init_display(display);
    XMesaVisual v;
    GLint red_bits, green_bits, blue_bits, alpha_bits;
 
-   xmesa_init( display );
+   if (!xmdpy)
+      return NULL;
 
    /* For debugging only */
    if (_mesa_getenv("MESA_XSYNC")) {
@@ -675,7 +711,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
 
    v->stvis.color_format = choose_pixel_format(v);
    v->stvis.depth_stencil_format =
-      choose_depth_stencil_format(depth_size, stencil_size);
+      choose_depth_stencil_format(xmdpy, depth_size, stencil_size);
 
    v->stvis.accum_format = (accum_red_size +
          accum_green_size + accum_blue_size + accum_alpha_size) ?
@@ -699,37 +735,12 @@ void XMesaDestroyVisual( XMesaVisual v )
 
 
 /**
- * Do one-time initializations.
+ * Do per-display initializations.
  */
 void
 xmesa_init( Display *display )
 {
-   static GLboolean firstTime = GL_TRUE;
-   if (firstTime) {
-      pipe_mutex_init(_xmesa_lock);
-      screen = driver.create_pipe_screen( display );
-      stapi = driver.create_st_api();
-      smapi = CALLOC_STRUCT(st_manager);
-      if (smapi)
-         smapi->screen = screen;
-
-      if (!screen || !stapi || !smapi) {
-         if (screen) {
-            screen->destroy(screen);
-            screen = NULL;
-         }
-         if (stapi) {
-            stapi->destroy(stapi);
-            stapi = NULL;
-         }
-         if (smapi) {
-            FREE(smapi);
-            smapi = NULL;
-         }
-      }
-
-      firstTime = GL_FALSE;
-   }
+   xmesa_init_display(display);
 }
 
 
@@ -743,9 +754,11 @@ xmesa_init( Display *display )
 PUBLIC
 XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
 {
+   XMesaDisplay xmdpy = xmesa_init_display(v->display);
    XMesaContext c;
 
-   xmesa_init( v->display );
+   if (!xmdpy)
+      return NULL;
 
    /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
    c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
@@ -756,10 +769,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
    c->xm_read_buffer = NULL;
 
-   if (screen == NULL)
-      goto fail;
-
-   c->st = stapi->create_context(stapi, smapi,
+   c->st = stapi->create_context(stapi, xmdpy->smapi,
          &v->stvis, (share_list) ? share_list->st : NULL);
    if (c->st == NULL)
       goto fail;
@@ -1094,12 +1104,13 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
 void XMesaFlush( XMesaContext c )
 {
    if (c && c->xm_visual->display) {
+      XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
       struct pipe_fence_handle *fence = NULL;
 
       c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
       if (fence) {
-         screen->fence_finish(screen, fence, 0);
-         screen->fence_reference(screen, &fence, NULL);
+         xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
+         xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
       }
       XSync( c->xm_visual->display, False );
    }
index 258abf92554bda53a11d35d39cc151ed5463f5a0..11a08962b74e50fe86b68821573c18127ddeb753 100644 (file)
@@ -67,11 +67,20 @@ and create a window, you must do the following to use the X/Mesa interface:
 # include <X11/Xlibint.h>
 # include <X11/Xutil.h>
 
+typedef struct xmesa_display *XMesaDisplay;
 typedef struct xmesa_buffer *XMesaBuffer;
 typedef struct xmesa_context *XMesaContext;
 typedef struct xmesa_visual *XMesaVisual;
 
 
+struct xmesa_display {
+   pipe_mutex mutex;
+
+   Display *display;
+   struct pipe_screen *screen;
+   struct st_manager *smapi;
+};
+
 
 /*
  * Create a new X/Mesa visual.
@@ -264,11 +273,6 @@ XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
 /***********************************************************************
  */
 
-extern pipe_mutex _xmesa_lock;
-
-extern struct xmesa_buffer *XMesaBufferList;
-
-
 /**
  * Visual inforation, derived from GLvisual.
  * Basically corresponds to an XVisualInfo.