Selaa lähdekoodia

Implement surface clearing w/out dependency on XMesa/Mesa stuff.

tags/mesa_20090313
Brian 18 vuotta sitten
vanhempi
commit
0d6608ee68

+ 10
- 0
src/mesa/pipe/xlib/xm_api.c Näytä tiedosto

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


+ 18
- 162
src/mesa/pipe/xlib/xm_buffer.c Näytä tiedosto

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

+ 177
- 15
src/mesa/pipe/xlib/xm_surface.c Näytä tiedosto

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


+ 1
- 1
src/mesa/pipe/xlib/xm_winsys.c Näytä tiedosto

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

+ 29
- 18
src/mesa/pipe/xlib/xmesaP.h Näytä tiedosto

@@ -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

Loading…
Peruuta
Tallenna