summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c117
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h14
2 files changed, 73 insertions, 58 deletions
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 94c0ad496d..e7c1979b42 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -70,21 +70,56 @@
* 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 );
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 258abf9255..11a08962b7 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -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.