implement get/put_tile() for xlib driver

This commit is contained in:
Brian 2007-11-01 11:23:50 -06:00
parent 0d6608ee68
commit a333088986
3 changed files with 132 additions and 6 deletions

View file

@ -502,9 +502,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
/**
* Move raw block of pixels from surface to user memory.
*/
static void
softpipe_get_tile(struct pipe_context *pipe,
struct pipe_surface *ps,
void
softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
void *p, int dst_stride)
{
@ -535,9 +534,8 @@ softpipe_get_tile(struct pipe_context *pipe,
/**
* Move raw block of pixels from user memory to surface.
*/
static void
softpipe_put_tile(struct pipe_context *pipe,
struct pipe_surface *ps,
void
softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
const void *p, int src_stride)
{

View file

@ -45,6 +45,15 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
unsigned face, unsigned level, unsigned zslice);
extern void
softpipe_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
softpipe_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
softpipe_get_tile_rgba(struct pipe_context *pipe,
struct pipe_surface *ps,

View file

@ -70,19 +70,138 @@ xmesa_rb(struct pipe_surface *ps)
#define FLIP(Y) Y = xrb->St.Base.Height - (Y) - 1;
/**
* Return raw pixels from pixmap or XImage.
*/
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)
{
struct xmesa_surface *xms = xmesa_surface(ps);
XMesaImage *ximage = NULL;
ubyte *dst = (ubyte *) p;
uint i;
if (!xms->drawable && !xms->ximage) {
/* not an X surface */
softpipe_get_tile(pipe, ps, x, y, w, h, p, dst_stride);
return;
}
if (!xms->ximage) {
/* XImage = pixmap data */
assert(xms->drawable);
ximage = XGetImage(xms->display, xms->drawable, x, y, w, h,
AllPlanes, ZPixmap);
x = y = 0;
}
else {
ximage = xms->ximage;
}
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
if (!dst_stride) {
dst_stride = w * 4;
}
for (i = 0; i < h; i++) {
memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 4, 4 * w);
dst += dst_stride;
}
break;
case PIPE_FORMAT_U_R5_G6_B5:
if (!dst_stride) {
dst_stride = w * 2;
}
for (i = 0; i < h; i++) {
memcpy(dst, ximage->data + y * ximage->bytes_per_line + x * 2, 4 * 2);
dst += dst_stride;
}
break;
default:
assert(0);
}
if (!xms->ximage) {
XMesaDestroyImage(ximage);
}
}
/**
* Put raw pixels into pixmap or XImage.
*/
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)
{
struct xmesa_surface *xms = xmesa_surface(ps);
const ubyte *src = (const ubyte *) p;
XMesaImage *ximage;
if (!xms->drawable && !xms->ximage) {
/* not an X surface */
softpipe_put_tile(pipe, ps, x, y, w, h, p, src_stride);
return;
}
if (xms->ximage) {
/* put to ximage */
ximage = xms->ximage;
char *dst;
int i;
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
if (!src_stride) {
src_stride = w * 4;
}
dst = ximage->data + y * ximage->bytes_per_line + x * 4;
for (i = 0; i < h; i++) {
memcpy(dst, src, w * 4);
dst += ximage->bytes_per_line;
src += src_stride;
}
break;
case PIPE_FORMAT_U_R5_G6_B5:
if (!src_stride) {
src_stride = w * 2;
}
dst = ximage->data + y * ximage->bytes_per_line + x * 2;
for (i = 0; i < h; i++) {
memcpy(dst, src, w * 2);
dst += ximage->bytes_per_line;
src += src_stride;
}
break;
default:
assert(0);
}
}
else {
/* put to pixmap/window */
/* Create temp XImage for data */
#ifdef XFree86Server
ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, p);
#else
XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo;
ximage = XCreateImage(xms->display,
visinfo->visual,
visinfo->depth,
ZPixmap, 0, /* format, offset */
(char *) p, /* data */
w, h, /* width, height */
32, /* bitmap_pad */
0); /* bytes_per_line */
#endif
/* send XImage data to pixmap */
XPutImage(xms->display, xms->drawable, xms->gc,
ximage, 0, 0, x, y, w, h);
/* clean-up */
ximage->data = NULL; /* prevents freeing user data at 'p' */
XMesaDestroyImage(ximage);
}
}