diff options
author | Brian <brian.paul@tungstengraphics.com> | 2007-12-07 07:57:54 -0700 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-12-09 12:05:26 +1100 |
commit | 2a9c33f9fe4b78710bfa36f1309d791c294d7cc8 (patch) | |
tree | b1ffbec54a0f341b0633c527e5f906bfbd1e3de5 /src/mesa/pipe/xlib/xm_winsys.c | |
parent | 6397bef076271d36443ce9db5f80fa20b05ee60e (diff) |
Overhaul the Xlib winsys layer.
Front/back color buffers are now allocated with ordinary malloc() via the
winsys buffer functions.
To display surfaces in SwapBuffers() or flush_frontbuffer() we create an
XImage that wraps the surface, then use XPutImage to copy to the window.
Shared memory transport disabled for now.
Diffstat (limited to 'src/mesa/pipe/xlib/xm_winsys.c')
-rw-r--r-- | src/mesa/pipe/xlib/xm_winsys.c | 157 |
1 files changed, 113 insertions, 44 deletions
diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c index 295174d4bb..b9dd3e3b6e 100644 --- a/src/mesa/pipe/xlib/xm_winsys.c +++ b/src/mesa/pipe/xlib/xm_winsys.c @@ -38,6 +38,8 @@ #include "main/macros.h" #include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" #include "pipe/softpipe/sp_winsys.h" @@ -54,17 +56,52 @@ struct xm_buffer }; +struct xmesa_surface +{ + struct pipe_surface surface; + /* no extra fields for now */ +}; + + +/** + * Derived from softpipe_winsys. + * We just need one extra field which indicates the pixel format to use for + * drawing surfaces so that we're compatible with the XVisual/window format. + */ +struct xmesa_softpipe_winsys +{ + struct softpipe_winsys spws; + uint pixelformat; +}; + + -/* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque +/** Cast wrapper */ +static INLINE struct xmesa_surface * +xmesa_surface(struct pipe_surface *ps) +{ + assert(0); + return (struct xmesa_surface *) ps; +} + +/** cast wrapper */ +static INLINE struct xmesa_softpipe_winsys * +xmesa_softpipe_winsys(struct softpipe_winsys *spws) +{ + return (struct xmesa_softpipe_winsys *) spws; +} + +/** + * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque * buffer pointer... */ -static inline struct xm_buffer * +static INLINE struct xm_buffer * xm_bo( struct pipe_buffer_handle *bo ) { return (struct xm_buffer *) bo; } -static inline struct pipe_buffer_handle * +static INLINE struct pipe_buffer_handle * pipe_bo( struct xm_buffer *bo ) { return (struct pipe_buffer_handle *) bo; @@ -156,6 +193,33 @@ xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf, memcpy(data, b + offset, size); } + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +void +xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) +{ + XImage *ximage = b->tempImage; + struct xm_buffer *xm_buf = xm_bo(surf->buffer); + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8); + ximage->data = xm_buf->data; + + /* display image in Window */ + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); +} + + static void xm_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, @@ -166,9 +230,13 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, * If we instead did front buffer rendering to a temporary XImage, * this would be the place to copy the Ximage to the on-screen Window. */ + XMesaContext xmctx = (XMesaContext) context_private; + + xmesa_display_surface(xmctx->xm_buffer, surf); } + static void xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) { @@ -178,6 +246,7 @@ xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) va_end( args ); } + static const char * xm_get_name(struct pipe_winsys *pws) { @@ -219,7 +288,6 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } - static unsigned xm_surface_pitch(struct pipe_winsys *winsys, unsigned cpp, unsigned width, unsigned flags) @@ -243,12 +311,7 @@ xm_surface_alloc(struct pipe_winsys *ws, GLuint pipeFormat) xms->surface.format = pipeFormat; xms->surface.refcount = 1; xms->surface.winsys = ws; -#if 0 - /* - * This is really just a softpipe surface, not an XImage/Pixmap surface. - */ - softpipe_init_surface_funcs(&xms->surface); -#endif + return &xms->surface; } @@ -261,7 +324,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) - winsys->buffer_reference(winsys, &surf->buffer, NULL); + winsys->buffer_reference(winsys, &surf->buffer, NULL); free(surf); } *s = NULL; @@ -274,7 +337,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) * For Xlib, this is a singleton object. * Nothing special for the Xlib driver so no subclassing or anything. */ -struct pipe_winsys * +static struct pipe_winsys * xmesa_get_pipe_winsys(void) { static struct pipe_winsys *ws = NULL; @@ -308,59 +371,65 @@ xmesa_get_pipe_winsys(void) /** - * XXX this depends on the depths supported by the screen (8/16/32/etc). - * Maybe when we're about to create a context/drawable we create a new - * softpipe_winsys object that corresponds to the specified screen... + * The winsys being queried will have been created at glXCreateContext + * time, with a pixel format corresponding to the context's visual. * - * Also, this query only really matters for on-screen drawables. - * For textures and FBOs we (softpipe) can support any format.o + * XXX we should pass a flag indicating if the format is going to be + * use for a drawing surface vs. a texture. In the later case, we + * can support any format. */ static boolean xmesa_is_format_supported(struct softpipe_winsys *sws, uint format) { - /* Any format supported by softpipe can be listed here. - * This query is not used for allocating window-system color buffers - * (which would depend on the screen depth/bpp). - */ - switch (format) { - case PIPE_FORMAT_U_A8_R8_G8_B8: - case PIPE_FORMAT_S_R16_G16_B16_A16: - case PIPE_FORMAT_S8_Z24: - case PIPE_FORMAT_U_S8: - case PIPE_FORMAT_U_Z16: - case PIPE_FORMAT_U_Z32: + struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); + + if (format == xmws->pixelformat) { return TRUE; - default: - return FALSE; - }; + } + else { + /* non-color / window surface format */ + switch (format) { + case PIPE_FORMAT_S_R16_G16_B16_A16: + case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_U_S8: + case PIPE_FORMAT_U_Z16: + case PIPE_FORMAT_U_Z32: + return TRUE; + default: + return FALSE; + }; + } } /** * Return pointer to a softpipe_winsys object. - * For Xlib, this is a singleton object. */ static struct softpipe_winsys * -xmesa_get_softpipe_winsys(void) +xmesa_get_softpipe_winsys(uint pixelformat) { - static struct softpipe_winsys *spws = NULL; + struct xmesa_softpipe_winsys *xmws + = CALLOC_STRUCT(xmesa_softpipe_winsys); + if (!xmws) + return NULL; - if (!spws) { - spws = CALLOC_STRUCT(softpipe_winsys); - if (spws) { - spws->is_format_supported = xmesa_is_format_supported; - } - } + xmws->spws.is_format_supported = xmesa_is_format_supported; + xmws->pixelformat = pixelformat; - return spws; + return &xmws->spws; } struct pipe_context * -xmesa_create_context(XMesaContext xmesa) +xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_winsys *pws = xmesa_get_pipe_winsys(); - struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(); + struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); + struct pipe_context *pipe; - return softpipe_create( pws, spws ); + pipe = softpipe_create( pws, spws ); + if (pipe) + pipe->priv = xmesa; + + return pipe; } |