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
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;
}
-/**
- * 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()
{
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;
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;
}
{
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);
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;
}
xrb->St.surface = xmesa_new_color_surface(pipe, pipeFormat);
xms = (struct xmesa_surface *) xrb->St.surface;
xms->xrb = xrb;
+
}
return xrb;
}
} 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)
{
#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)
}
+/**
+ * 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)
}
+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.
/**
- * 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.
}
}
- 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;
+}
+
* 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)
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 {
/**
- * Context info, dDerived from GLcontext.
+ * Context info, derived from GLcontext.
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
*/
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 */
GLint width4;
GLint bottom; /* used for FLIP macro, equals height - 1 */
-
- ClearFunc clearFunc;
-
- void *pSurface; /** pipe surface */
};
-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);
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);
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