diff options
author | Brian <brian.paul@tungstengraphics.com> | 2007-10-31 15:27:09 -0600 |
---|---|---|
committer | Brian <brian.paul@tungstengraphics.com> | 2007-10-31 15:27:09 -0600 |
commit | 8d0d6f04a15f31c4491966767c547fe1ffbeb362 (patch) | |
tree | 490d87a1ec00bee0c862c87cdf1a0b5541ed5d94 /src/mesa/pipe/xlib/xm_buffer.c | |
parent | 30fb4c43b02f4105944453e48d7a0f878746595d (diff) |
move surface clear functions to xm_buffer.c
Diffstat (limited to 'src/mesa/pipe/xlib/xm_buffer.c')
-rw-r--r-- | src/mesa/pipe/xlib/xm_buffer.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/mesa/pipe/xlib/xm_buffer.c b/src/mesa/pipe/xlib/xm_buffer.c index 56b797a6a9..183a7ec8f5 100644 --- a/src/mesa/pipe/xlib/xm_buffer.c +++ b/src/mesa/pipe/xlib/xm_buffer.c @@ -262,6 +262,146 @@ 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 <noz@xfree86.org> */ +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() */ @@ -269,6 +409,7 @@ static GLboolean xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); /* just clear these to be sure we don't accidentally use them */ @@ -287,6 +428,11 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, if (!xrb->St.surface || !xrb->St.surface->region) finish_surface_init(ctx, xrb); + 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; @@ -302,6 +448,7 @@ static GLboolean xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); /* reallocate the back buffer XImage or Pixmap */ @@ -339,6 +486,27 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, xrb->origin4 = NULL; } + 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); |