@@ -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; | |||
@@ -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; | |||
} |
@@ -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 <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; | |||
} | |||
@@ -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) |
@@ -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 |