Overhaul the Xlib winsys layer.

Front/back color buffers are now allocated with ordinary malloc() via the
winsys buffer functions.
To display surfaces in SwapBuffers() or flush_frontbuffer() we create an
XImage that wraps the surface, then use XPutImage to copy to the window.
Shared memory transport disabled for now.
This commit is contained in:
Brian 2007-12-07 07:57:54 -07:00
parent f77ce9e4fa
commit 749d723287
7 changed files with 259 additions and 2365 deletions

View file

@ -1433,7 +1433,6 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
return NULL;
}
glxCtx->xmesaContext->direct = GL_FALSE;
glxCtx->glxContext.isDirect = GL_FALSE;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
@ -1565,7 +1564,7 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
if (!b) {
return 0;
}
return b->frontxrb->pixmap;
return b->drawable;
}
@ -1591,7 +1590,7 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
if (!b) {
return 0;
}
return b->frontxrb->pixmap;
return b->drawable;
}
@ -1662,9 +1661,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
static Bool
Fake_glXIsDirect( Display *dpy, GLXContext ctx )
{
struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
(void) dpy;
return glxCtx->xmesaContext->direct;
(void) ctx;
return False;
}
@ -2360,7 +2359,7 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
* glXMakeCurrent takes.
*/
if (xmbuf)
return (GLXPbuffer) xmbuf->frontxrb->pixmap;
return (GLXPbuffer) xmbuf->drawable;
else
return 0;
}
@ -2444,7 +2443,6 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
return NULL;
}
glxCtx->xmesaContext->direct = GL_FALSE;
glxCtx->glxContext.isDirect = GL_FALSE;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
@ -2642,7 +2640,7 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
return xmbuf->frontxrb->pixmap; /* need to return an X ID */
return xmbuf->drawable; /* need to return an X ID */
}
@ -2667,7 +2665,6 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re
return NULL;
}
glxCtx->xmesaContext->direct = GL_FALSE;
glxCtx->glxContext.isDirect = GL_FALSE;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
@ -2736,7 +2733,7 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
/* A GLXPbuffer handle must be an X Drawable because that's what
* glXMakeCurrent takes.
*/
return (GLXPbuffer) xmbuf->frontxrb->pixmap;
return (GLXPbuffer) xmbuf->drawable;
}

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,6 @@
#include "state_tracker/st_context.h"
#if defined(USE_XSHM) && !defined(XFree86Server)
static volatile int mesaXErrorFlag = 0;
/**
@ -458,8 +457,8 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
if (!xmesa_find_buffer(b->display, b->cmap, b)) {
#ifdef XFree86Server
int client = 0;
if (b->frontxrb->drawable)
client = CLIENT_ID(b->frontxrb->drawable->id);
if (b->drawable)
client = CLIENT_ID(b->drawable->id);
(void)FreeColors(b->cmap, client,
b->num_alloced, b->alloced_colors, 0);
#else
@ -478,21 +477,6 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb)
if (fb->Visual.doubleBufferMode) {
/* free back ximage/pixmap/shmregion */
if (b->backxrb->ximage) {
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
XShmDetach( b->display, &b->shminfo );
XDestroyImage( b->backxrb->ximage );
shmdt( b->shminfo.shmaddr );
}
else
#endif
XMesaDestroyImage( b->backxrb->ximage );
b->backxrb->ximage = NULL;
}
if (b->backxrb->pixmap) {
XMesaFreePixmap( b->display, b->backxrb->pixmap );
}
}
if (b->rowimage) {

View file

@ -70,689 +70,6 @@ const int xmesa_kernel1[16] = {
#define CLIP_TILE \
do { \
if (x >= ps->width) \
return; \
if (y >= ps->height) \
return; \
if (x + w > ps->width) \
w = ps->width - x; \
if (y + h > ps->height) \
h = ps->height -y; \
} while(0)
/*
* The following functions are used to trap XGetImage() calls which
* generate BadMatch errors if the drawable isn't mapped.
*/
#ifndef XFree86Server
static int caught_xgetimage_error = 0;
static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev );
static unsigned long xgetimage_serial;
/*
* This is the error handler which will be called if XGetImage fails.
*/
static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev )
{
if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
/* caught the expected error */
caught_xgetimage_error = 0;
}
else {
/* call the original X error handler, if any. otherwise ignore */
if (old_xerror_handler) {
(*old_xerror_handler)( dpy, ev );
}
}
return 0;
}
/*
* Call this right before XGetImage to setup error trap.
*/
static void catch_xgetimage_errors( XMesaDisplay *dpy )
{
xgetimage_serial = NextRequest( dpy );
old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
caught_xgetimage_error = 0;
}
/*
* Call this right after XGetImage to check if an error occured.
*/
static int check_xgetimage_errors( void )
{
/* restore old handler */
(void) XSetErrorHandler( old_xerror_handler );
/* return 0=no error, 1=error caught */
return caught_xgetimage_error;
}
#endif
/**
* Wrapper for XGetImage() that catches BadMatch errors that can occur
* when the window is unmapped or the x/y/w/h extend beyond the window
* bounds.
* If build into xserver, wrap the internal GetImage method.
*/
static XMesaImage *
xget_image(XMesaDisplay *dpy, Drawable d, int x, int y, uint w, uint h)
{
#ifdef XFree86Server
uint bpp = 4; /* XXX fix this */
XMesaImage *ximage = (XMesaImage *) malloc(sizeof(XMesaImage));
if (ximage) {
ximage->data = malloc(width * height * bpp);
}
(*dpy->GetImage)(d, x, y, w, h, ZPixmap, ~0L, (pointer)ximage->data);
ximage->width = w;
ximage->height = h;
ximage->bytes_per_row = w * bpp;
return ximage;
#else
int error;
XMesaImage *ximage;
catch_xgetimage_errors(dpy);
ximage = XGetImage(dpy, d, x, y, w, h, AllPlanes, ZPixmap);
error = check_xgetimage_errors();
return ximage;
#endif
}
/**
* 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)
{
const uint w0 = w;
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;
}
CLIP_TILE;
if (!xms->ximage) {
/* XImage = pixmap data */
assert(xms->drawable);
ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
if (!ximage)
return;
x = y = 0;
}
else {
ximage = xms->ximage;
}
/* this could be optimized/simplified */
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
if (!dst_stride) {
dst_stride = w0 * 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 = w0 * 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)
{
const uint w0 = w;
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;
}
CLIP_TILE;
if (xms->ximage) {
/* put to ximage */
ximage = xms->ximage;
char *dst;
uint i;
/* this could be optimized/simplified */
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
if (!src_stride) {
src_stride = w0 * 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 = w0 * 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);
}
}
void
xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h, float *pixels)
{
const uint w0 = w;
struct xmesa_surface *xms = xmesa_surface(ps);
XMesaImage *ximage = NULL;
float *pRow = pixels;
uint i, j;
if (!xms->drawable && !xms->ximage) {
/* not an X surface */
softpipe_get_tile_rgba(pipe, ps, x, y, w, h, pixels);
return;
}
CLIP_TILE;
if (!xms->ximage) {
/* XImage = pixmap data */
assert(xms->drawable);
ximage = xget_image(xms->display, xms->drawable, x, y, w, h);
if (!ximage)
return;
x = y = 0;
}
else {
ximage = xms->ximage;
}
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
{
const uint *src
= (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
for (i = 0; i < h; i++) {
float *p = pRow;
for (j = 0; j < w; j++) {
uint pix = src[j];
ubyte r = ((pix >> 16) & 0xff);
ubyte g = ((pix >> 8) & 0xff);
ubyte b = ( pix & 0xff);
ubyte a = ((pix >> 24) & 0xff);
p[0] = UBYTE_TO_FLOAT(r);
p[1] = UBYTE_TO_FLOAT(g);
p[2] = UBYTE_TO_FLOAT(b);
p[3] = UBYTE_TO_FLOAT(a);
p += 4;
}
src += ximage->width;
pRow += 4 * w0;
}
}
break;
case PIPE_FORMAT_U_B8_G8_R8_A8:
{
const uint *src
= (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
for (i = 0; i < h; i++) {
float *p = pRow;
for (j = 0; j < w; j++) {
uint pix = src[j];
ubyte r = ((pix >> 8) & 0xff);
ubyte g = ((pix >> 16) & 0xff);
ubyte b = ((pix >> 24) & 0xff);
ubyte a = ( pix & 0xff);
p[0] = UBYTE_TO_FLOAT(r);
p[1] = UBYTE_TO_FLOAT(g);
p[2] = UBYTE_TO_FLOAT(b);
p[3] = UBYTE_TO_FLOAT(a);
p += 4;
}
src += ximage->width;
pRow += 4 * w0;
}
}
break;
case PIPE_FORMAT_U_R5_G6_B5:
{
ushort *src
= (ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
for (i = 0; i < h; i++) {
float *p = pRow;
for (j = 0; j < w; j++) {
uint pix = src[j];
ubyte r = (pix >> 8) | ((pix >> 13) & 0x7);
ubyte g = (pix >> 3) | ((pix >> 9) & 0x3);
ubyte b = ((pix & 0x1f) << 3) | ((pix >> 2) & 0x3);
p[0] = UBYTE_TO_FLOAT(r);
p[1] = UBYTE_TO_FLOAT(g);
p[2] = UBYTE_TO_FLOAT(b);
p[3] = 1.0;
p += 4;
}
src += ximage->width;
pRow += 4 * w0;
}
}
break;
default:
fprintf(stderr, "Bad format in xmesa_get_tile_rgba()\n");
assert(0);
}
if (!xms->ximage) {
XMesaDestroyImage(ximage);
}
}
void
xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps,
uint x, uint y, uint w, uint h, const float *pixels)
{
const uint x0 = x, y0 = y, w0 = w;
struct xmesa_surface *xms = xmesa_surface(ps);
XMesaImage *ximage;
uint i, j;
if (!xms->drawable && !xms->ximage) {
/* not an X surface */
softpipe_put_tile_rgba(pipe, ps, x, y, w, h, pixels);
return;
}
CLIP_TILE;
if (!xms->ximage) {
/* create temp XImage */
char *data = (char *) malloc(w * h * 4);
#ifdef XFree86Server
ximage = XMesaCreateImage(GET_VISUAL_DEPTH(v), w, h, data);
#else
XVisualInfo *visinfo = xms->xrb->Parent->xm_visual->visinfo;
ximage = XCreateImage(xms->display,
visinfo->visual,
visinfo->depth,
ZPixmap, 0, /* format, offset */
data, /* data */
w, h, /* width, height */
32, /* bitmap_pad */
0); /* bytes_per_line */
#endif
x = y = 0;
}
else {
ximage = xms->ximage;
}
/* convert floats to ximage's format */
switch (ps->format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
{
uint *dst
= (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
const float *pRow = pixels;
for (i = 0; i < h; i++) {
const float *p = pRow;
for (j = 0; j < w; j++) {
ubyte r, g, b, a;
UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
UNCLAMPED_FLOAT_TO_UBYTE(a, p[3]);
dst[j] = PACK_8A8R8G8B(r, g, b, a);
p += 4;
}
dst += ximage->width;
pRow += 4 * w0;
}
}
break;
case PIPE_FORMAT_U_B8_G8_R8_A8:
{
uint *dst
= (uint *) (ximage->data + y * ximage->bytes_per_line + x * 4);
const float *pRow = pixels;
for (i = 0; i < h; i++) {
const float *p = pRow;
for (j = 0; j < w; j++) {
ubyte r, g, b, a;
UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
UNCLAMPED_FLOAT_TO_UBYTE(a, p[3]);
dst[j] = PACK_8B8G8R8A(r, g, b, a);
p += 4;
}
dst += ximage->width;
pRow += 4 * w0;
}
}
break;
case PIPE_FORMAT_U_R5_G6_B5:
{
ushort *dst =
(ushort *) (ximage->data + y * ximage->bytes_per_line + x * 2);
const float *pRow = pixels;
for (i = 0; i < h; i++) {
const float *p = pRow;
for (j = 0; j < w; j++) {
ubyte r, g, b;
UNCLAMPED_FLOAT_TO_UBYTE(r, p[0]);
UNCLAMPED_FLOAT_TO_UBYTE(g, p[1]);
UNCLAMPED_FLOAT_TO_UBYTE(b, p[2]);
dst[j] = PACK_5R6G5B(r, g, b);
p += 4;
}
dst += ximage->width;
pRow += 4 * w0;
}
}
break;
default:
fprintf(stderr, "Bad format in xmesa_put_tile_rgba()\n");
assert(0);
}
if (!xms->ximage) {
/* send XImage data to pixmap */
XPutImage(xms->display, xms->drawable, xms->gc,
ximage, 0, 0, x0, y0, w, h);
/* clean-up */
free(ximage->data);
ximage->data = NULL;
XMesaDestroyImage(ximage);
}
}
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.
* Note: this is being used instead of pipe->surface_alloc() since we
* have special/unique quad read/write functions for X.
*/
struct pipe_surface *
xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint pipeFormat)
{
struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
assert(pipeFormat);
xms->surface.format = pipeFormat;
xms->surface.refcount = 1;
xms->surface.winsys = winsys;
/* Note, the buffer we allocate doesn't actually have any storage
* since we're drawing into an XImage or Pixmap.
* The surface's size will get set in the xmesa_alloc_front/back_storage()
* functions.
*/
xms->surface.buffer = winsys->buffer_create(winsys, 0x0);
return &xms->surface;
}
/**
* Called via pipe->surface_alloc() to create new surfaces (textures,
* renderbuffers, etc.
*/
struct pipe_surface *
xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat)
{
struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
assert(pipe);
assert(pipeFormat);
xms->surface.format = pipeFormat;
xms->surface.refcount = 1;
xms->surface.winsys = pipe->winsys;
return &xms->surface;
}
/**
* 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, uint value)
{
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.
*/
pipe->flush(pipe, 0);
{
struct softpipe_context *sp = softpipe_context(pipe);
if (ps == sp_tile_cache_get_surface(sp, sp->cbuf_cache[0])) {
float clear[4];
clear[0] = 0.2; /* XXX hack */
clear[1] = 0.2;
clear[2] = 0.2;
clear[3] = 0.2;
sp_tile_cache_clear(sp->cbuf_cache[0], clear);
}
}
#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:
case PIPE_FORMAT_U_B8_G8_R8_A8:
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 {
/* other kind of buffer */
softpipe_clear(pipe, ps, value);
}
}
/** XXX unfinished sketch... */
struct pipe_surface *

View file

@ -38,6 +38,8 @@
#include "main/macros.h"
#include "pipe/p_winsys.h"
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/softpipe/sp_winsys.h"
@ -54,17 +56,52 @@ struct xm_buffer
};
struct xmesa_surface
{
struct pipe_surface surface;
/* no extra fields for now */
};
/* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque
/**
* Derived from softpipe_winsys.
* We just need one extra field which indicates the pixel format to use for
* drawing surfaces so that we're compatible with the XVisual/window format.
*/
struct xmesa_softpipe_winsys
{
struct softpipe_winsys spws;
uint pixelformat;
};
/** Cast wrapper */
static INLINE struct xmesa_surface *
xmesa_surface(struct pipe_surface *ps)
{
assert(0);
return (struct xmesa_surface *) ps;
}
/** cast wrapper */
static INLINE struct xmesa_softpipe_winsys *
xmesa_softpipe_winsys(struct softpipe_winsys *spws)
{
return (struct xmesa_softpipe_winsys *) spws;
}
/**
* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque
* buffer pointer...
*/
static inline struct xm_buffer *
static INLINE struct xm_buffer *
xm_bo( struct pipe_buffer_handle *bo )
{
return (struct xm_buffer *) bo;
}
static inline struct pipe_buffer_handle *
static INLINE struct pipe_buffer_handle *
pipe_bo( struct xm_buffer *bo )
{
return (struct pipe_buffer_handle *) bo;
@ -156,6 +193,33 @@ xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
memcpy(data, b + offset, size);
}
/**
* Display/copy the image in the surface into the X window specified
* by the XMesaBuffer.
*/
void
xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
{
XImage *ximage = b->tempImage;
struct xm_buffer *xm_buf = xm_bo(surf->buffer);
/* check that the XImage has been previously initialized */
assert(ximage->format);
assert(ximage->bitmap_unit);
/* update XImage's fields */
ximage->width = surf->width;
ximage->height = surf->height;
ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8);
ximage->data = xm_buf->data;
/* display image in Window */
XPutImage(b->xm_visual->display, b->drawable, b->gc,
ximage, 0, 0, 0, 0, surf->width, surf->height);
}
static void
xm_flush_frontbuffer(struct pipe_winsys *pws,
struct pipe_surface *surf,
@ -166,9 +230,13 @@ xm_flush_frontbuffer(struct pipe_winsys *pws,
* If we instead did front buffer rendering to a temporary XImage,
* this would be the place to copy the Ximage to the on-screen Window.
*/
XMesaContext xmctx = (XMesaContext) context_private;
xmesa_display_surface(xmctx->xm_buffer, surf);
}
static void
xm_printf(struct pipe_winsys *pws, const char *fmtString, ...)
{
@ -178,6 +246,7 @@ xm_printf(struct pipe_winsys *pws, const char *fmtString, ...)
va_end( args );
}
static const char *
xm_get_name(struct pipe_winsys *pws)
{
@ -219,7 +288,6 @@ round_up(unsigned n, unsigned multiple)
return (n + multiple - 1) & ~(multiple - 1);
}
static unsigned
xm_surface_pitch(struct pipe_winsys *winsys, unsigned cpp, unsigned width,
unsigned flags)
@ -243,12 +311,7 @@ xm_surface_alloc(struct pipe_winsys *ws, GLuint pipeFormat)
xms->surface.format = pipeFormat;
xms->surface.refcount = 1;
xms->surface.winsys = ws;
#if 0
/*
* This is really just a softpipe surface, not an XImage/Pixmap surface.
*/
softpipe_init_surface_funcs(&xms->surface);
#endif
return &xms->surface;
}
@ -261,7 +324,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
surf->refcount--;
if (surf->refcount == 0) {
if (surf->buffer)
winsys->buffer_reference(winsys, &surf->buffer, NULL);
winsys->buffer_reference(winsys, &surf->buffer, NULL);
free(surf);
}
*s = NULL;
@ -274,7 +337,7 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
* For Xlib, this is a singleton object.
* Nothing special for the Xlib driver so no subclassing or anything.
*/
struct pipe_winsys *
static struct pipe_winsys *
xmesa_get_pipe_winsys(void)
{
static struct pipe_winsys *ws = NULL;
@ -308,59 +371,65 @@ xmesa_get_pipe_winsys(void)
/**
* XXX this depends on the depths supported by the screen (8/16/32/etc).
* Maybe when we're about to create a context/drawable we create a new
* softpipe_winsys object that corresponds to the specified screen...
* The winsys being queried will have been created at glXCreateContext
* time, with a pixel format corresponding to the context's visual.
*
* Also, this query only really matters for on-screen drawables.
* For textures and FBOs we (softpipe) can support any format.o
* XXX we should pass a flag indicating if the format is going to be
* use for a drawing surface vs. a texture. In the later case, we
* can support any format.
*/
static boolean
xmesa_is_format_supported(struct softpipe_winsys *sws, uint format)
{
/* Any format supported by softpipe can be listed here.
* This query is not used for allocating window-system color buffers
* (which would depend on the screen depth/bpp).
*/
switch (format) {
case PIPE_FORMAT_U_A8_R8_G8_B8:
case PIPE_FORMAT_S_R16_G16_B16_A16:
case PIPE_FORMAT_S8_Z24:
case PIPE_FORMAT_U_S8:
case PIPE_FORMAT_U_Z16:
case PIPE_FORMAT_U_Z32:
struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws);
if (format == xmws->pixelformat) {
return TRUE;
default:
return FALSE;
};
}
else {
/* non-color / window surface format */
switch (format) {
case PIPE_FORMAT_S_R16_G16_B16_A16:
case PIPE_FORMAT_S8_Z24:
case PIPE_FORMAT_U_S8:
case PIPE_FORMAT_U_Z16:
case PIPE_FORMAT_U_Z32:
return TRUE;
default:
return FALSE;
};
}
}
/**
* Return pointer to a softpipe_winsys object.
* For Xlib, this is a singleton object.
*/
static struct softpipe_winsys *
xmesa_get_softpipe_winsys(void)
xmesa_get_softpipe_winsys(uint pixelformat)
{
static struct softpipe_winsys *spws = NULL;
struct xmesa_softpipe_winsys *xmws
= CALLOC_STRUCT(xmesa_softpipe_winsys);
if (!xmws)
return NULL;
if (!spws) {
spws = CALLOC_STRUCT(softpipe_winsys);
if (spws) {
spws->is_format_supported = xmesa_is_format_supported;
}
}
xmws->spws.is_format_supported = xmesa_is_format_supported;
xmws->pixelformat = pixelformat;
return spws;
return &xmws->spws;
}
struct pipe_context *
xmesa_create_context(XMesaContext xmesa)
xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat)
{
struct pipe_winsys *pws = xmesa_get_pipe_winsys();
struct softpipe_winsys *spws = xmesa_get_softpipe_winsys();
struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat);
struct pipe_context *pipe;
return softpipe_create( pws, spws );
pipe = softpipe_create( pws, spws );
if (pipe)
pipe->priv = xmesa;
return pipe;
}

View file

@ -32,42 +32,15 @@
#ifdef XFree86Server
#include "xm_image.h"
#endif
#include "state_tracker/st_cb_fbo.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "pipe/softpipe/sp_context.h"
#include "pipe/softpipe/sp_surface.h"
extern _glthread_Mutex _xmesa_lock;
extern XMesaBuffer XMesaBufferList;
/* for PF_8R8G8B24 pixel format */
typedef struct {
GLubyte b;
GLubyte g;
GLubyte r;
} bgr_t;
/** Framebuffer pixel formats */
enum pixel_format {
PF_Index, /**< Color Index mode */
PF_Truecolor, /**< TrueColor or DirectColor, any depth */
PF_Dither_True, /**< TrueColor with dithering */
PF_8A8R8G8B, /**< 32-bit TrueColor: 8-A, 8-R, 8-G, 8-B bits */
PF_8A8B8G8R, /**< 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R bits */
PF_8R8G8B, /**< 32-bit TrueColor: 8-R, 8-G, 8-B bits */
PF_8R8G8B24, /**< 24-bit TrueColor: 8-R, 8-G, 8-B bits */
PF_5R6G5B, /**< 16-bit TrueColor: 5-R, 6-G, 5-B bits */
PF_Dither, /**< Color-mapped RGB with dither */
PF_Lookup, /**< Color-mapped RGB without dither */
PF_1Bit, /**< monochrome dithering of RGB */
PF_Grayscale, /**< Grayscale or StaticGray */
PF_Dither_5R6G5B /**< 16-bit dithered TrueColor: 5-R, 6-G, 5-B */
};
/**
* Visual inforation, derived from GLvisual.
@ -86,47 +59,17 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
enum pixel_format dithered_pf; /* Pixel format when dithering */
enum pixel_format undithered_pf;/* Pixel format when not dithering */
GLfloat RedGamma; /* Gamma values, 1.0 is default */
GLfloat GreenGamma;
GLfloat BlueGamma;
/* For PF_TRUECOLOR */
GLint rshift, gshift, bshift;/* Pixel color component shifts */
GLubyte Kernel[16]; /* Dither kernel */
unsigned long RtoPixel[512]; /* RGB to pixel conversion */
unsigned long GtoPixel[512];
unsigned long BtoPixel[512];
GLubyte PixelToR[256]; /* Pixel to RGB conversion */
GLubyte PixelToG[256];
GLubyte PixelToB[256];
/* For PF_1BIT */
int bitFlip;
};
/**
* Context info, derived from GLcontext.
* Context info, derived from st_context.
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
struct st_context *st;
XMesaVisual xm_visual; /* Describes the buffers */
XMesaBuffer xm_buffer; /* current span/point/line/triangle buffer */
XMesaDisplay *display; /* == xm_visual->display */
GLboolean swapbytes; /* Host byte order != display byte order? */
GLboolean direct; /* Direct rendering context? */
enum pixel_format pixelformat;
GLubyte clearcolor[4]; /* current clearing color */
unsigned long clearpixel; /* current clearing pixel value */
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
};
@ -141,46 +84,6 @@ typedef enum {
} BufferType;
/** Values for db_mode: */
/*@{*/
#define BACK_PIXMAP 1
#define BACK_XIMAGE 2
/*@}*/
/**
* An xmesa_renderbuffer represents the back or front color buffer.
* For the front color buffer:
* <drawable> is the X window
* For the back color buffer:
* Either <ximage> or <pixmap> will be used, never both.
* In any case, <drawable> always equals <pixmap>.
* For stand-alone Mesa, we could merge <drawable> and <pixmap> into one
* field. We don't do that for the server-side GLcore module because
* pixmaps and drawables are different and we'd need a bunch of casts.
*/
struct xmesa_renderbuffer
{
struct st_renderbuffer St; /**< Base class (XXX temporary?) */
XMesaBuffer Parent; /**< The XMesaBuffer this renderbuffer belongs to */
XMesaDrawable drawable; /* Usually the X window ID */
XMesaPixmap pixmap; /* Back color buffer */
XMesaImage *ximage; /* The back buffer, if not using a Pixmap */
GLubyte *origin1; /* used for PIXEL_ADDR1 macro */
GLint width1;
GLushort *origin2; /* used for PIXEL_ADDR2 macro */
GLint width2;
GLubyte *origin3; /* used for PIXEL_ADDR3 macro */
GLint width3;
GLuint *origin4; /* used for PIXEL_ADDR4 macro */
GLint width4;
GLint bottom; /* used for FLIP macro, equals height - 1 */
};
/**
* Framebuffer information, derived from.
* Basically corresponds to a GLXDrawable.
@ -190,22 +93,13 @@ struct xmesa_buffer {
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
XMesaDisplay *display;
XMesaDrawable drawable; /* Usually the X window ID */
XMesaColormap cmap; /* the X colormap */
BufferType type; /* window, pixmap, pbuffer or glxwindow */
struct xmesa_renderbuffer *frontxrb; /* front color renderbuffer */
struct xmesa_renderbuffer *backxrb; /* back color renderbuffer */
XMesaColormap cmap; /* the X colormap */
XMesaImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
GLint db_mode; /* 0 = single buffered */
/* BACK_PIXMAP = use Pixmap for back buffer */
/* BACK_XIMAGE = use XImage for back buffer */
GLboolean swAlpha;
GLuint shm; /* X Shared Memory extension status: */
/* 0 = not available */
/* 1 = XImage support available */
@ -214,33 +108,7 @@ struct xmesa_buffer {
XShmSegmentInfo shminfo;
#endif
XMesaImage *rowimage; /* Used for optimized span writing */
XMesaPixmap stipple_pixmap; /* For polygon stippling */
XMesaGC stipple_gc; /* For polygon stippling */
XMesaGC gc; /* scratch GC for span, line, tri drawing */
XMesaGC cleargc; /* GC for clearing the color buffer */
XMesaGC swapgc; /* GC for swapping the color buffers */
/* The following are here instead of in the XMesaVisual
* because they depend on the window's colormap.
*/
/* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
unsigned long color_table[576]; /* RGB -> pixel value */
/* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
GLubyte pixel_to_r[65536]; /* pixel value -> red */
GLubyte pixel_to_g[65536]; /* pixel value -> green */
GLubyte pixel_to_b[65536]; /* pixel value -> blue */
/* Used to do XAllocColor/XFreeColors accounting: */
int num_alloced;
#if defined(XFree86Server)
Pixel alloced_colors[256];
#else
unsigned long alloced_colors[256];
#endif
/* GLX_EXT_texture_from_pixmap */
GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */
@ -251,209 +119,23 @@ struct xmesa_buffer {
};
/**
* If pixelformat==PF_TRUECOLOR:
*/
#define PACK_TRUECOLOR( PIXEL, R, G, B ) \
PIXEL = xmesa->xm_visual->RtoPixel[R] \
| xmesa->xm_visual->GtoPixel[G] \
| xmesa->xm_visual->BtoPixel[B]; \
/**
* If pixelformat==PF_TRUEDITHER:
*/
#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
{ \
int d = xmesa->xm_visual->Kernel[((X)&3) | (((Y)&3)<<2)]; \
PIXEL = xmesa->xm_visual->RtoPixel[(R)+d] \
| xmesa->xm_visual->GtoPixel[(G)+d] \
| xmesa->xm_visual->BtoPixel[(B)+d]; \
/** cast wrapper */
static INLINE XMesaContext
xmesa_context(GLcontext *ctx)
{
return (XMesaContext) ctx->DriverCtx;
}
/** cast wrapper */
static INLINE XMesaBuffer
xmesa_buffer(GLframebuffer *fb)
{
struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
return (XMesaBuffer) st_framebuffer_private(stfb);
}
/**
* If pixelformat==PF_8A8B8G8R:
*/
#define PACK_8A8B8G8R( R, G, B, A ) \
( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
/**
* Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
* shortcut.
*/
#define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
#define PACK_8B8G8R8A( R, G, B, A ) \
( ((B) << 24) | ((G) << 16) | ((R) << 8) | (A) )
/**
* If pixelformat==PF_8R8G8B:
*/
#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
/**
* If pixelformat==PF_5R6G5B:
*/
#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
/**
* If pixelformat==PF_8A8R8G8B:
*/
#define PACK_8A8R8G8B( R, G, B, A ) \
( ((A) << 24) | ((R) << 16) | ((G) << 8) | (B) )
/**
* If pixelformat==PF_DITHER:
*
* Improved 8-bit RGB dithering code contributed by Bob Mercier
* (mercier@hollywood.cinenet.net). Thanks Bob!
*/
#ifdef DITHER666
# define DITH_R 6
# define DITH_G 6
# define DITH_B 6
# define DITH_MIX(r,g,b) (((r) * DITH_G + (g)) * DITH_B + (b))
#else
# define DITH_R 5
# define DITH_G 9
# define DITH_B 5
# define DITH_MIX(r,g,b) (((g) << 6) | ((b) << 3) | (r))
#endif
#define DITH_DX 4
#define DITH_DY 4
#define DITH_N (DITH_DX * DITH_DY)
#define _dither(C, c, d) (((unsigned)((DITH_N * (C - 1) + 1) * c + d)) >> 12)
#define MAXC 256
extern const int xmesa_kernel8[DITH_DY * DITH_DX];
/* Dither for random X,Y */
#define DITHER_SETUP \
int __d; \
unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table;
#define DITHER( X, Y, R, G, B ) \
(__d = xmesa_kernel8[(((Y)&3)<<2) | ((X)&3)], \
ctable[DITH_MIX(_dither(DITH_R, (R), __d), \
_dither(DITH_G, (G), __d), \
_dither(DITH_B, (B), __d))])
/* Dither for random X, fixed Y */
#define XDITHER_SETUP(Y) \
int __d; \
unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table; \
const int *kernel = &xmesa_kernel8[ ((Y)&3) << 2 ];
#define XDITHER( X, R, G, B ) \
(__d = kernel[(X)&3], \
ctable[DITH_MIX(_dither(DITH_R, (R), __d), \
_dither(DITH_G, (G), __d), \
_dither(DITH_B, (B), __d))])
/*
* Dithering for flat-shaded triangles. Precompute all 16 possible
* pixel values given the triangle's RGB color. Contributed by Martin Shenk.
*/
#define FLAT_DITHER_SETUP( R, G, B ) \
GLushort ditherValues[16]; \
{ \
unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table; \
int msdr = (DITH_N*((DITH_R)-1)+1) * (R); \
int msdg = (DITH_N*((DITH_G)-1)+1) * (G); \
int msdb = (DITH_N*((DITH_B)-1)+1) * (B); \
int i; \
for (i=0;i<16;i++) { \
int k = xmesa_kernel8[i]; \
int j = DITH_MIX( (msdr+k)>>12, (msdg+k)>>12, (msdb+k)>>12 );\
ditherValues[i] = (GLushort) ctable[j]; \
} \
}
#define FLAT_DITHER_ROW_SETUP(Y) \
GLushort *ditherRow = ditherValues + ( ((Y)&3) << 2);
#define FLAT_DITHER(X) ditherRow[(X)&3]
/**
* If pixelformat==PF_LOOKUP:
*/
#define _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12)
#define LOOKUP_SETUP \
unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table
#define LOOKUP( R, G, B ) \
ctable[DITH_MIX(_dither_lookup(DITH_R, (R)), \
_dither_lookup(DITH_G, (G)), \
_dither_lookup(DITH_B, (B)))]
/**
* If pixelformat==PF_1BIT:
*/
extern const int xmesa_kernel1[16];
#define SETUP_1BIT int bitFlip = xmesa->xm_visual->bitFlip
#define DITHER_1BIT( X, Y, R, G, B ) \
(( ((int)(R)+(int)(G)+(int)(B)) > xmesa_kernel1[(((Y)&3) << 2) | ((X)&3)] ) ^ bitFlip)
/**
* If pixelformat==PF_GRAYSCALE:
*/
#define GRAY_RGB( R, G, B ) XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3]
/**
* Converts a GL window Y coord to an X window Y coord:
*/
#define YFLIP(XRB, Y) ((XRB)->bottom - (Y))
/**
* Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
* X==0 is left, Y==0 is bottom.
*/
#define PIXEL_ADDR1(XRB, X, Y) \
( (XRB)->origin1 - (Y) * (XRB)->width1 + (X) )
#define PIXEL_ADDR2(XRB, X, Y) \
( (XRB)->origin2 - (Y) * (XRB)->width2 + (X) )
#define PIXEL_ADDR3(XRB, X, Y) \
( (bgr_t *) ( (XRB)->origin3 - (Y) * (XRB)->width3 + 3 * (X) ))
#define PIXEL_ADDR4(XRB, X, Y) \
( (XRB)->origin4 - (Y) * (XRB)->width4 + (X) )
/*
* External functions:
*/
extern struct xmesa_renderbuffer *
xmesa_create_renderbuffer(struct pipe_winsys *winsys,
GLuint name, XMesaVisual xmvis,
GLboolean backBuffer);
extern void
xmesa_delete_framebuffer(struct gl_framebuffer *fb);
@ -461,115 +143,14 @@ xmesa_delete_framebuffer(struct gl_framebuffer *fb);
extern XMesaBuffer
xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis);
extern unsigned long
xmesa_color_to_pixel( XMesaContext xmesa,
GLubyte r, GLubyte g, GLubyte b, GLubyte a,
GLuint pixelFormat );
extern void
xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
extern void
xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
/**
* Using a function instead of an ordinary cast is safer.
*/
static INLINE struct xmesa_renderbuffer *
xmesa_renderbuffer(struct gl_renderbuffer *rb)
{
return (struct xmesa_renderbuffer *) rb;
}
/**
* Return pointer to XMesaContext corresponding to a Mesa GLcontext.
* Since we're using structure containment, it's just a cast!.
* XXX should use inlined function for better type safety.
*/
static INLINE XMesaContext
XMESA_CONTEXT(GLcontext *ctx)
{
return (XMesaContext) ctx->DriverCtx;
}
/**
* Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer.
* Since we're using structure containment, it's just a cast!.
* XXX should use inlined function for better type safety.
*/
static INLINE XMesaBuffer
XMESA_BUFFER(GLframebuffer *fb)
{
struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
return (XMesaBuffer) st_framebuffer_private(stfb);
}
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, uint value);
extern struct pipe_context *
xmesa_create_context(XMesaContext xm);
extern struct pipe_surface *
xmesa_surface_alloc(struct pipe_context *pipe, GLuint format);
extern struct pipe_surface *
xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint format);
extern struct pipe_winsys *
xmesa_get_pipe_winsys(void);
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);
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);
xmesa_create_pipe_context(XMesaContext xm, uint pixelformat);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
@ -583,5 +164,7 @@ xmesa_buffer_height(XMesaBuffer b)
return b->stfb->Base.Height;
}
extern void
xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf);
#endif

View file

@ -334,9 +334,7 @@ X11_DRIVER_SOURCES = \
pipe/xlib/fakeglx.c \
pipe/xlib/xfonts.c \
pipe/xlib/xm_api.c \
pipe/xlib/xm_buffer.c \
pipe/xlib/xm_winsys.c \
pipe/xlib/xm_surface.c
pipe/xlib/xm_winsys.c
OSMESA_DRIVER_SOURCES = \
drivers/osmesa/osmesa.c