From: Brian Date: Thu, 1 Nov 2007 16:52:31 +0000 (-0600) Subject: Implement surface clearing w/out dependency on XMesa/Mesa stuff. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0d6608ee6855e5605efc3bd9fec51ada59e208d9;p=mesa.git Implement surface clearing w/out dependency on XMesa/Mesa stuff. --- diff --git a/src/mesa/pipe/xlib/xm_api.c b/src/mesa/pipe/xlib/xm_api.c index a4874d3f8f8..5e040922158 100644 --- a/src/mesa/pipe/xlib/xm_api.c +++ b/src/mesa/pipe/xlib/xm_api.c @@ -333,6 +333,14 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->frontxrb->pixmap = (XMesaPixmap) d; _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, &b->frontxrb->St.Base); +#if 0 /* sketch... */ + { + struct pipe_surface *front_surf; + front_surf = xmesa_create_front_surface(vis, d); + } +#endif + + /* * Back renderbuffer @@ -1495,6 +1503,8 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) mesaCtx->st->pipe->surface_alloc = xmesa_surface_alloc; mesaCtx->st->pipe->is_format_supported = xmesa_is_format_supported; #endif + mesaCtx->st->pipe->get_tile = xmesa_get_tile; + mesaCtx->st->pipe->put_tile = xmesa_put_tile; mesaCtx->st->pipe->get_tile_rgba = xmesa_get_tile_rgba; mesaCtx->st->pipe->put_tile_rgba = xmesa_put_tile_rgba; diff --git a/src/mesa/pipe/xlib/xm_buffer.c b/src/mesa/pipe/xlib/xm_buffer.c index 8ac9fb55b6c..cd3b498b10f 100644 --- a/src/mesa/pipe/xlib/xm_buffer.c +++ b/src/mesa/pipe/xlib/xm_buffer.c @@ -261,146 +261,6 @@ finish_surface_init(GLcontext *ctx, struct xmesa_renderbuffer *xrb) } -/** - * Clear the front or back color buffer, if it's implemented with a pixmap. - */ -static void -clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLuint value) -{ - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); - - assert(xmbuf); - assert(xrb->pixmap); - assert(xmesa); - assert(xmesa->display); - assert(xrb->pixmap); - assert(xmbuf->cleargc); - - XMesaSetForeground( xmesa->display, xmbuf->cleargc, value ); - - XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, - 0, 0, xrb->St.Base.Width, xrb->St.Base.Height); -} - - -static void -clear_8bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLuint value) -{ - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - GLint width = xrb->St.Base.Width; - GLint height = xrb->St.Base.Height; - GLint i; - for (i = 0; i < height; i++) { - GLubyte *ptr = PIXEL_ADDR1(xrb, 0, i); - MEMSET( ptr, xmesa->clearpixel, width ); - } -} - - -static void -clear_16bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLuint value) -{ - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - GLint width = xrb->St.Base.Width; - GLint height = xrb->St.Base.Height; - GLint i, j; - - if (xmesa->swapbytes) { - value = ((value >> 8) & 0x00ff) | ((value << 8) & 0xff00); - } - - for (j = 0; j < height; j++) { - GLushort *ptr2 = PIXEL_ADDR2(xrb, 0, j); - for (i = 0; i < width; i++) { - ptr2[i] = value; - } - } -} - - -/* Optimized code provided by Nozomi Ytow */ -static void -clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, - GLuint value) -{ - GLint width = xrb->St.Base.Width; - GLint height = xrb->St.Base.Height; - const GLubyte r = (value ) & 0xff; - const GLubyte g = (value >> 8) & 0xff; - const GLubyte b = (value >> 16) & 0xff; - - if (r == g && g == b) { - /* same value for all three components (gray) */ - GLint j; - for (j = 0; j < height; j++) { - bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, j); - MEMSET(ptr3, r, 3 * width); - } - } - else { - /* non-gray clear color */ - GLint i, j; - for (j = 0; j < height; j++) { - bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, j); - for (i = 0; i < width; i++) { - ptr3->r = r; - ptr3->g = g; - ptr3->b = b; - ptr3++; - } - } - } -} - - -static void -clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, - GLuint value) -{ - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - GLint width = xrb->St.Base.Width; - GLint height = xrb->St.Base.Height; - const GLuint n = width * height; - GLuint *ptr4 = (GLuint *) xrb->ximage->data; - - if (!xrb->ximage) - return; - - if (xmesa->swapbytes) { - value = ((value >> 24) & 0x000000ff) - | ((value >> 8) & 0x0000ff00) - | ((value << 8) & 0x00ff0000) - | ((value << 24) & 0xff000000); - } - - if (value == 0) { - /* common case */ - _mesa_memset(ptr4, value, 4 * n); - } - else { - GLuint i; - for (i = 0; i < n; i++) - ptr4[i] = value; - } -} - - -static void -clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLuint value) -{ - XMesaImage *img = xrb->ximage; - GLint width = xrb->St.Base.Width; - GLint height = xrb->St.Base.Height; - GLint i, j; - for (j = 0; j < height; j++) { - for (i = 0; i < width; i++) { - XMesaPutPixel(img, i, j, value); - } - } -} - - /** * Reallocate renderbuffer storage for front color buffer. * Called via gl_renderbuffer::AllocStorage() @@ -411,6 +271,7 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, { const XMesaContext xmesa = XMESA_CONTEXT(ctx); struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); + struct xmesa_surface *xms = xmesa_surface(xrb->St.surface); /* just clear these to be sure we don't accidentally use them */ xrb->origin1 = NULL; @@ -431,10 +292,13 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, xmesa_set_renderbuffer_funcs(xrb, xmesa->pixelformat, xmesa->xm_visual->BitsPerPixel); - xrb->clearFunc = clear_pixmap; - - xrb->St.surface->width = width; - xrb->St.surface->height = height; + /* surface info */ + xms->surface.width = width; + xms->surface.height = height; + xms->display = xmesa->display; + xms->drawable = xrb->drawable; + xms->gc = xrb->Parent->cleargc; + xms->ximage = NULL; return GL_TRUE; } @@ -450,6 +314,7 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, { const XMesaContext xmesa = XMESA_CONTEXT(ctx); struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); + struct xmesa_surface *xms = xmesa_surface(xrb->St.surface); /* reallocate the back buffer XImage or Pixmap */ assert(xrb->Parent); @@ -489,30 +354,20 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, xmesa_set_renderbuffer_funcs(xrb, xmesa->pixelformat, xmesa->xm_visual->BitsPerPixel); - switch (xmesa->xm_visual->BitsPerPixel) { - case 8: - xrb->clearFunc = clear_8bit_ximage; - break; - case 16: - xrb->clearFunc = clear_16bit_ximage; - break; - case 24: - xrb->clearFunc = clear_24bit_ximage; - break; - case 32: - xrb->clearFunc = clear_32bit_ximage; - break; - default: - xrb->clearFunc = clear_nbit_ximage; - break; - } - if (!xrb->St.surface || !xrb->St.surface->region) finish_surface_init(ctx, xrb); xrb->St.surface->width = width; xrb->St.surface->height = height; + /* surface info */ + xms->surface.width = width; + xms->surface.height = height; + xms->display = xmesa->display; + xms->drawable = xrb->drawable; + xms->gc = xrb->Parent->cleargc; + xms->ximage = xrb->ximage; + return GL_TRUE; } @@ -561,6 +416,7 @@ xmesa_create_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual, xrb->St.surface = xmesa_new_color_surface(pipe, pipeFormat); xms = (struct xmesa_surface *) xrb->St.surface; xms->xrb = xrb; + } return xrb; } diff --git a/src/mesa/pipe/xlib/xm_surface.c b/src/mesa/pipe/xlib/xm_surface.c index b7e9d7811de..a5e0f794945 100644 --- a/src/mesa/pipe/xlib/xm_surface.c +++ b/src/mesa/pipe/xlib/xm_surface.c @@ -59,13 +59,6 @@ } while(0) -static INLINE struct xmesa_surface * -xmesa_surface(struct pipe_surface *ps) -{ - return (struct xmesa_surface *) ps; -} - - static INLINE struct xmesa_renderbuffer * xmesa_rb(struct pipe_surface *ps) { @@ -77,6 +70,26 @@ xmesa_rb(struct pipe_surface *ps) #define FLIP(Y) Y = xrb->St.Base.Height - (Y) - 1; +void +xmesa_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, void *p, int dst_stride) +{ + +} + + +void +xmesa_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, const void *p, int src_stride) +{ + +} + + + +/** + * XXX rewrite to stop using renderbuffer->GetRow() + */ void xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p) @@ -109,6 +122,9 @@ xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, } +/** + * XXX rewrite to stop using renderbuffer->PutRow() + */ void xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) @@ -145,6 +161,110 @@ xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, } +static void +clear_pixmap_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + assert(xms); + assert(xms->display); + assert(xms->drawable); + assert(xms->gc); + XMesaSetForeground( xms->display, xms->gc, value ); + XMesaFillRectangle( xms->display, xms->drawable, xms->gc, + 0, 0, ps->width, ps->height); +} + +static void +clear_nbit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + int width = xms->surface.width; + int height = xms->surface.height; + int i, j; + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + XMesaPutPixel(xms->ximage, i, j, value); + } + } +} + +static void +clear_8bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + memset(xms->ximage->data, + value, + xms->ximage->bytes_per_line * xms->ximage->height); +} + +static void +clear_16bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + const int n = xms->ximage->width * xms->ximage->height; + ushort *dst = (ushort *) xms->ximage->data; + int i; + for (i = 0; i < n; i++) { + dst[i] = value; + } +} + + +/* Optimized code provided by Nozomi Ytow */ +static void +clear_24bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + const ubyte r = (value ) & 0xff; + const ubyte g = (value >> 8) & 0xff; + const ubyte b = (value >> 16) & 0xff; + + if (r == g && g == b) { + /* same value for all three components (gray) */ + memset(xms->ximage->data, r, + xms->ximage->bytes_per_line * xms->ximage->height); + } + else { + /* non-gray clear color */ + const int n = xms->ximage->width * xms->ximage->height; + int i; + bgr_t *ptr3 = (bgr_t *) xms->ximage->data; + for (i = 0; i < n; i++) { + ptr3->r = r; + ptr3->g = g; + ptr3->b = b; + ptr3++; + } + } +} + +static void +clear_32bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps, + uint value) +{ + struct xmesa_surface *xms = xmesa_surface(ps); + + if (value == 0) { + /* common case */ + memset(xms->ximage->data, value, + xms->ximage->bytes_per_line * xms->ximage->height); + } + else { + const int n = xms->ximage->width * xms->ximage->height; + uint *dst = (uint *) xms->ximage->data; + int i; + for (i = 0; i < n; i++) + dst[i] = value; + } +} + + + /** * Called to create a pipe_surface for each X renderbuffer. @@ -194,13 +314,14 @@ xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat) /** - * Called via pipe->clear() + * Called via pipe->clear() to clear entire surface to a certain value. + * If the surface is not an X pixmap or XImage, pass the call to + * softpipe_clear(). */ void -xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value) +xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, uint value) { - GET_CURRENT_CONTEXT(ctx); - struct xmesa_renderbuffer *xrb = xmesa_rb(ps); + struct xmesa_surface *xms = xmesa_surface(ps); /* XXX actually, we should just discard any cached tiles from this * surface since we don't want to accidentally re-use them after clearing. @@ -219,13 +340,54 @@ xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value) } } - if (xrb) { - /* clearing front/back color buffer */ - xrb->clearFunc(ctx, xrb, value); +#if 1 + (void) clear_8bit_ximage_surface; + (void) clear_24bit_ximage_surface; +#endif + + if (xms->ximage) { + /* back color buffer */ + switch (xms->surface.format) { + case PIPE_FORMAT_U_R5_G6_B5: + clear_16bit_ximage_surface(pipe, ps, value); + break; + case PIPE_FORMAT_U_A8_R8_G8_B8: + clear_32bit_ximage_surface(pipe, ps, value); + break; + default: + clear_nbit_ximage_surface(pipe, ps, value); + break; + } + } + else if (xms->drawable) { + /* front color buffer */ + clear_pixmap_surface(pipe, ps, value); } else { - /* clearing other buffer */ + /* other kind of buffer */ softpipe_clear(pipe, ps, value); } } + +/** XXX unfinished sketch... */ +struct pipe_surface * +xmesa_create_front_surface(XMesaVisual vis, Window win) +{ + struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + if (!xms) { + return NULL; + } + + xms->display = vis->display; + xms->drawable = win; + + xms->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8; + xms->surface.refcount = 1; +#if 0 + xms->surface.region = pipe->winsys->region_alloc(pipe->winsys, + 1, 0, 0, 0x0); +#endif + return &xms->surface; +} + diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c index ef8e78f4414..e6e98ed3960 100644 --- a/src/mesa/pipe/xlib/xm_winsys.c +++ b/src/mesa/pipe/xlib/xm_winsys.c @@ -341,7 +341,7 @@ xmesa_get_pipe_winsys(void) * softpipe_winsys object that corresponds to the specified screen... * * Also, this query only really matters for on-screen drawables. - * For textures and FBOs we (softpipe) can support any format. + * For textures and FBOs we (softpipe) can support any format.o */ static boolean xmesa_is_format_supported(struct softpipe_winsys *sws, uint format) diff --git a/src/mesa/pipe/xlib/xmesaP.h b/src/mesa/pipe/xlib/xmesaP.h index d42b2b3fb91..4454ab80030 100644 --- a/src/mesa/pipe/xlib/xmesaP.h +++ b/src/mesa/pipe/xlib/xmesaP.h @@ -52,12 +52,6 @@ typedef struct { struct xmesa_renderbuffer; -/* Function pointer for clearing color buffers */ -typedef void (*ClearFunc)( GLcontext *ctx, struct xmesa_renderbuffer *xrb, - GLuint value ); - - - /** Framebuffer pixel formats */ enum pixel_format { @@ -118,7 +112,7 @@ struct xmesa_visual { /** - * Context info, dDerived from GLcontext. + * Context info, derived from GLcontext. * Basically corresponds to a GLXContext. */ struct xmesa_context { @@ -168,11 +162,7 @@ typedef enum { */ struct xmesa_renderbuffer { -#if 0 - struct gl_renderbuffer Base; /* Base class */ -#else - struct st_renderbuffer St; /**< Base class */ -#endif + struct st_renderbuffer St; /**< Base class (XXX temporary?) */ XMesaBuffer Parent; /**< The XMesaBuffer this renderbuffer belongs to */ XMesaDrawable drawable; /* Usually the X window ID */ @@ -189,10 +179,6 @@ struct xmesa_renderbuffer GLint width4; GLint bottom; /* used for FLIP macro, equals height - 1 */ - - ClearFunc clearFunc; - - void *pSurface; /** pipe surface */ }; @@ -526,18 +512,30 @@ XMESA_BUFFER(GLframebuffer *b) -struct pipe_surface; struct pipe_context; struct xmesa_surface { struct pipe_surface surface; struct xmesa_renderbuffer *xrb; + XMesaDisplay *display; + BufferType type; + XMesaDrawable drawable; + XMesaImage *ximage; + XMesaGC gc; }; +/** Cast wrapper */ +static INLINE struct xmesa_surface * +xmesa_surface(struct pipe_surface *ps) +{ + return (struct xmesa_surface *) ps; +} + + extern void -xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, GLuint value); +xmesa_clear(struct pipe_context *pipe, struct pipe_surface *ps, uint value); extern struct pipe_context * xmesa_create_softpipe(XMesaContext xm); @@ -548,6 +546,15 @@ xmesa_surface_alloc(struct pipe_context *pipe, GLuint format); extern struct pipe_surface * xmesa_new_color_surface(struct pipe_context *pipe, GLuint format); + +extern void +xmesa_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, void *p, int dst_stride); + +extern void +xmesa_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, + uint x, uint y, uint w, uint h, const void *p, int src_stride); + extern void xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p); @@ -556,4 +563,8 @@ extern void xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p); + +extern struct pipe_surface * +xmesa_create_front_surface(XMesaVisual vis, Window win); + #endif