summaryrefslogtreecommitdiff
path: root/src/mesa/pipe/xlib/xm_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/pipe/xlib/xm_buffer.c')
-rw-r--r--src/mesa/pipe/xlib/xm_buffer.c168
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);