Implement surface clearing w/out dependency on XMesa/Mesa stuff.
authorBrian <brian.paul@tungstengraphics.com>
Thu, 1 Nov 2007 16:52:31 +0000 (10:52 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 1 Nov 2007 16:52:31 +0000 (10:52 -0600)
src/mesa/pipe/xlib/xm_api.c
src/mesa/pipe/xlib/xm_buffer.c
src/mesa/pipe/xlib/xm_surface.c
src/mesa/pipe/xlib/xm_winsys.c
src/mesa/pipe/xlib/xmesaP.h

index a4874d3f8f81b42b3096c527f437ffe0989cd643..5e040922158ee0690cf0255f7048ca8c3c93bebe 100644 (file)
@@ -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;
 
index 8ac9fb55b6c6f60337b0f9474005d5932e10ad16..cd3b498b10f90e55a5f35595014a300a711ecb9c 100644 (file)
@@ -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 <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()
@@ -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;
 }
index b7e9d7811de832b1101407956cd9e70c9b5c3279..a5e0f7949451ecc16cff529e0a80eea0e7ca42c6 100644 (file)
    } 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 <noz@xfree86.org> */
+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;
+}
+
index ef8e78f441412ec9d06a2f3b50c28eaca70403fe..e6e98ed39605957d2e534177563a4d97b06de4ff 100644 (file)
@@ -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)
index d42b2b3fb91bff2d38768c629a1524623668e846..4454ab8003014919d8fd356edf0c0fb66e1d75db 100644 (file)
@@ -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