Big re-org of buffer size management.

All buffer resizes now handled by xmesa_check_and_update_buffer_size() which
uses the _mesa_resize_framebuffer() function.
Moved all low-level XImage/Pixmap resizing into xm_buffers.c file.
Also, update lots of comments for Doxygen.
This commit is contained in:
Brian Paul
2006-10-14 22:52:17 +00:00
parent 2b46f4b853
commit d21fa9cd79
4 changed files with 529 additions and 494 deletions

View File

@@ -22,8 +22,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
/* /**
* This file contains the implementations of all the XMesa* functions. * \file xm_api.c
*
* All the XMesa* API functions.
* *
* *
* NOTES: * NOTES:
@@ -68,13 +70,8 @@
#include "framebuffer.h" #include "framebuffer.h"
#include "glthread.h" #include "glthread.h"
#include "imports.h" #include "imports.h"
#include "matrix.h"
#include "mtypes.h"
#include "macros.h" #include "macros.h"
#include "renderbuffer.h" #include "renderbuffer.h"
#include "texformat.h"
#include "texobj.h"
#include "texstore.h"
#include "swrast/swrast.h" #include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h" #include "swrast_setup/swrast_setup.h"
#include "array_cache/acache.h" #include "array_cache/acache.h"
@@ -87,14 +84,14 @@
#include <GL/glxtokens.h> #include <GL/glxtokens.h>
#endif #endif
/* /**
* Global X driver lock * Global X driver lock
*/ */
_glthread_Mutex _xmesa_lock; _glthread_Mutex _xmesa_lock;
/* /**
* Lookup tables for HPCR pixel format: * Lookup tables for HPCR pixel format:
*/ */
static short hpcr_rgbTbl[3][256] = { static short hpcr_rgbTbl[3][256] = {
@@ -161,7 +158,7 @@ static short hpcr_rgbTbl[3][256] = {
/**********************************************************************/ /**********************************************************************/
/* /**
* Return the host's byte order as LSBFirst or MSBFirst ala X. * Return the host's byte order as LSBFirst or MSBFirst ala X.
*/ */
#ifndef XFree86Server #ifndef XFree86Server
@@ -174,23 +171,7 @@ static int host_byte_order( void )
#endif #endif
/* /**
* Error handling.
*/
#ifndef XFree86Server
static volatile int mesaXErrorFlag = 0;
static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
{
(void) dpy;
(void) event;
mesaXErrorFlag = 1;
return 0;
}
#endif
/*
* Check if the X Shared Memory extension is available. * Check if the X Shared Memory extension is available.
* Return: 0 = not available * Return: 0 = not available
* 1 = shared XImage support available * 1 = shared XImage support available
@@ -222,11 +203,12 @@ static int check_for_xshm( XMesaDisplay *display )
} }
/* /**
* Apply gamma correction to an intensity value in [0..max]. Return the * Apply gamma correction to an intensity value in [0..max]. Return the
* new intensity value. * new intensity value.
*/ */
static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max ) static GLint
gamma_adjust( GLfloat gamma, GLint value, GLint max )
{ {
if (gamma == 1.0) { if (gamma == 1.0) {
return value; return value;
@@ -239,7 +221,7 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
/* /**
* Return the true number of bits per pixel for XImages. * Return the true number of bits per pixel for XImages.
* For example, if we request a 24-bit deep visual we may actually need/get * For example, if we request a 24-bit deep visual we may actually need/get
* 32bpp XImages. This function returns the appropriate bpp. * 32bpp XImages. This function returns the appropriate bpp.
@@ -247,10 +229,10 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
* visinfo - desribes the visual to be used for XImages * visinfo - desribes the visual to be used for XImages
* Return: true number of bits per pixel for XImages * Return: true number of bits per pixel for XImages
*/ */
#ifdef XFree86Server static int
bits_per_pixel( XMesaVisual xmv )
static int bits_per_pixel( XMesaVisual xmv )
{ {
#ifdef XFree86Server
const int depth = xmv->nplanes; const int depth = xmv->nplanes;
int i; int i;
assert(depth > 0); assert(depth > 0);
@@ -259,12 +241,7 @@ static int bits_per_pixel( XMesaVisual xmv )
return screenInfo.formats[i].bitsPerPixel; return screenInfo.formats[i].bitsPerPixel;
} }
return depth; /* should never get here, but this should be safe */ return depth; /* should never get here, but this should be safe */
}
#else #else
static int bits_per_pixel( XMesaVisual xmv )
{
XMesaDisplay *dpy = xmv->display; XMesaDisplay *dpy = xmv->display;
XMesaVisualInfo visinfo = xmv->visinfo; XMesaVisualInfo visinfo = xmv->visinfo;
XMesaImage *img; XMesaImage *img;
@@ -285,8 +262,8 @@ static int bits_per_pixel( XMesaVisual xmv )
img->data = NULL; img->data = NULL;
XMesaDestroyImage( img ); XMesaDestroyImage( img );
return bitsPerPixel; return bitsPerPixel;
}
#endif #endif
}
@@ -325,6 +302,45 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
/**
* Return the size of the window (or pixmap) that corresponds to the
* given XMesaBuffer.
* \param width returns width in pixels
* \param height returns height in pixels
*/
void
xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
GLuint *width, GLuint *height)
{
#ifdef XFree86Server
*width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
*height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
#else
Window root;
Status stat;
int xpos, ypos;
unsigned int w, h, bw, depth;
_glthread_LOCK_MUTEX(_xmesa_lock);
XSync(b->xm_visual->display, 0); /* added for Chromium */
stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
&w, &h, &bw, &depth);
_glthread_UNLOCK_MUTEX(_xmesa_lock);
if (stat) {
*width = w;
*height = h;
}
else {
/* probably querying a window that's recently been destroyed */
_mesa_warning(NULL, "XGetGeometry failed!\n");
*width = *height = 1;
}
#endif
}
/**********************************************************************/ /**********************************************************************/
/***** Linked list of XMesaBuffers *****/ /***** Linked list of XMesaBuffers *****/
/**********************************************************************/ /**********************************************************************/
@@ -333,80 +349,110 @@ static XMesaBuffer XMesaBufferList = NULL;
/** /**
* Allocate a new XMesaBuffer, initialize basic fields and add to * Allocate a new XMesaBuffer object which corresponds to the given drawable.
* the list of all buffers. * Note that XMesaBuffer is derived from GLframebuffer.
* The new XMesaBuffer will not have any size (Width=Height=0).
*
* \param d the corresponding X drawable (window or pixmap)
* \param type either WINDOW, PIXMAP or PBUFFER, describing d
* \param vis the buffer's visual
* \param cmap the window's colormap, if known.
* \return new XMesaBuffer or NULL if any problem
*/ */
static XMesaBuffer static XMesaBuffer
alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap) create_xmesa_buffer(XMesaDrawable d, BufferType type,
XMesaVisual vis, XMesaColormap cmap)
{ {
XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); GLboolean swAlpha;
if (b) { XMesaBuffer b;
GLboolean swAlpha;
b->display = vis->display; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
b->xm_visual = vis;
b->type = type;
b->cmap = cmap;
_mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
/* Allocate the framebuffer's renderbuffers */ b->display = vis->display;
assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); b->xm_visual = vis;
assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer); b->type = type;
b->cmap = cmap;
/* front renderbuffer */ _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
/*
* Front renderbuffer
*/
b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
GL_FALSE); GL_FALSE);
_mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, if (!b->frontxrb) {
&b->frontxrb->Base); _mesa_free(b);
return NULL;
/* back renderbuffer */
if (vis->mesa_visual.doubleBufferMode) {
b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
GL_TRUE);
/* determine back buffer implementation */
b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
_mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
&b->backxrb->Base);
}
/* determine if we need software alpha planes */
if (vis->mesa_visual.alphaBits > 0
&& vis->undithered_pf != PF_8A8B8G8R
&& vis->undithered_pf != PF_8A8R8G8B) {
/* Visual has alpha, but pixel format doesn't support it.
* We'll use an alpha renderbuffer wrapper.
*/
swAlpha = GL_TRUE;
}
else {
swAlpha = GL_FALSE;
}
_mesa_add_soft_renderbuffers(&b->mesa_buffer,
GL_FALSE, /* color */
vis->mesa_visual.haveDepthBuffer,
vis->mesa_visual.haveStencilBuffer,
vis->mesa_visual.haveAccumBuffer,
swAlpha,
vis->mesa_visual.numAuxBuffers > 0 );
/* insert into linked list */
b->Next = XMesaBufferList;
XMesaBufferList = b;
} }
b->frontxrb->Parent = b;
b->frontxrb->drawable = d;
b->frontxrb->pixmap = (XMesaPixmap) d;
_mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
&b->frontxrb->Base);
/*
* Back renderbuffer
*/
if (vis->mesa_visual.doubleBufferMode) {
b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
GL_TRUE);
if (!b->backxrb) {
/* XXX free front xrb too */
_mesa_free(b);
return NULL;
}
b->backxrb->Parent = b;
/* determine back buffer implementation */
b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
_mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
&b->backxrb->Base);
}
/*
* Software alpha planes
*/
if (vis->mesa_visual.alphaBits > 0
&& vis->undithered_pf != PF_8A8B8G8R
&& vis->undithered_pf != PF_8A8R8G8B) {
/* Visual has alpha, but pixel format doesn't support it.
* We'll use an alpha renderbuffer wrapper.
*/
swAlpha = GL_TRUE;
}
else {
swAlpha = GL_FALSE;
}
/*
* Other renderbuffer (depth, stencil, etc)
*/
_mesa_add_soft_renderbuffers(&b->mesa_buffer,
GL_FALSE, /* color */
vis->mesa_visual.haveDepthBuffer,
vis->mesa_visual.haveStencilBuffer,
vis->mesa_visual.haveAccumBuffer,
swAlpha,
vis->mesa_visual.numAuxBuffers > 0 );
/* insert buffer into linked list */
b->Next = XMesaBufferList;
XMesaBufferList = b;
return b; return b;
} }
/* /**
* Find an XMesaBuffer by matching X display and colormap but NOT matching * Find an XMesaBuffer by matching X display and colormap but NOT matching
* the notThis buffer. * the notThis buffer.
*/ */
static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy, static XMesaBuffer
XMesaColormap cmap, find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
XMesaBuffer notThis)
{ {
XMesaBuffer b; XMesaBuffer b;
for (b=XMesaBufferList; b; b=b->Next) { for (b=XMesaBufferList; b; b=b->Next) {
@@ -418,11 +464,12 @@ static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
} }
/* /**
* Free an XMesaBuffer, remove from linked list, perhaps free X colormap * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
* entries. * entries.
*/ */
static void free_xmesa_buffer(int client, XMesaBuffer buffer) static void
free_xmesa_buffer(int client, XMesaBuffer buffer)
{ {
XMesaBuffer prev = NULL, b; XMesaBuffer prev = NULL, b;
(void) client; (void) client;
@@ -461,8 +508,11 @@ static void free_xmesa_buffer(int client, XMesaBuffer buffer)
} }
/* Copy X color table stuff from one XMesaBuffer to another. */ /**
static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src) * Copy X color table stuff from one XMesaBuffer to another.
*/
static void
copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
{ {
MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table)); MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r)); MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
@@ -481,198 +531,6 @@ static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
/** /**
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
* Return: GL_TRUE if success, GL_FALSE if error
*/
#ifndef XFree86Server
static GLboolean
alloc_shm_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
{
#ifdef USE_XSHM
/*
* We have to do a _lot_ of error checking here to be sure we can
* really use the XSHM extension. It seems different servers trigger
* errors at different points if the extension won't work. Therefore
* we have to be very careful...
*/
GC gc;
int (*old_handler)( XMesaDisplay *, XErrorEvent * );
if (width == 0 || height == 0) {
/* this will be true the first time we're called on 'b' */
return GL_FALSE;
}
b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
b->xm_visual->visinfo->visual,
b->xm_visual->visinfo->depth,
ZPixmap, NULL, &b->shminfo,
width, height);
if (b->backxrb->ximage == NULL) {
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
* b->backxrb->ximage->height, IPC_CREAT|0777 );
if (b->shminfo.shmid < 0) {
_mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
XDestroyImage( b->backxrb->ximage );
b->backxrb->ximage = NULL;
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.shmaddr = b->backxrb->ximage->data
= (char*)shmat( b->shminfo.shmid, 0, 0 );
if (b->shminfo.shmaddr == (char *) -1) {
_mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
XDestroyImage( b->backxrb->ximage );
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
b->backxrb->ximage = NULL;
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.readOnly = False;
mesaXErrorFlag = 0;
old_handler = XSetErrorHandler( mesaHandleXError );
/* This may trigger the X protocol error we're ready to catch: */
XShmAttach( b->xm_visual->display, &b->shminfo );
XSync( b->xm_visual->display, False );
if (mesaXErrorFlag) {
/* we are on a remote display, this error is normal, don't print it */
XFlush( b->xm_visual->display );
mesaXErrorFlag = 0;
XDestroyImage( b->backxrb->ximage );
shmdt( b->shminfo.shmaddr );
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
b->backxrb->ximage = NULL;
b->shm = 0;
(void) XSetErrorHandler( old_handler );
return GL_FALSE;
}
shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
/* Finally, try an XShmPutImage to be really sure the extension works */
gc = XCreateGC( b->xm_visual->display, b->frontxrb->drawable, 0, NULL );
XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, gc,
b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
XSync( b->xm_visual->display, False );
XFreeGC( b->xm_visual->display, gc );
(void) XSetErrorHandler( old_handler );
if (mesaXErrorFlag) {
XFlush( b->xm_visual->display );
mesaXErrorFlag = 0;
XDestroyImage( b->backxrb->ximage );
shmdt( b->shminfo.shmaddr );
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
b->backxrb->ximage = NULL;
b->shm = 0;
return GL_FALSE;
}
return GL_TRUE;
#else
/* Can't compile XSHM support */
return GL_FALSE;
#endif
}
#endif
/*
* Setup an off-screen pixmap or Ximage to use as the back buffer.
* Input: b - the X/Mesa buffer
*/
void
xmesa_alloc_back_buffer( XMesaBuffer b, GLuint width, GLuint height )
{
if (width == 0 || height == 0)
return;
if (b->db_mode == BACK_XIMAGE) {
/* Deallocate the old backxrb->ximage, if any */
if (b->backxrb->ximage) {
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
XShmDetach( b->xm_visual->display, &b->shminfo );
XDestroyImage( b->backxrb->ximage );
shmdt( b->shminfo.shmaddr );
}
else
#endif
XMesaDestroyImage( b->backxrb->ximage );
b->backxrb->ximage = NULL;
}
/* Allocate new back buffer */
#ifdef XFree86Server
/* Allocate a regular XImage for the back buffer. */
b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
width, height, NULL);
{
#else
if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) {
/* Allocate a regular XImage for the back buffer. */
b->backxrb->ximage = XCreateImage( b->xm_visual->display,
b->xm_visual->visinfo->visual,
GET_VISUAL_DEPTH(b->xm_visual),
ZPixmap, 0, /* format, offset */
NULL,
width, height,
8, 0 ); /* pad, bytes_per_line */
#endif
if (!b->backxrb->ximage) {
_mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
return;
}
b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height
* b->backxrb->ximage->bytes_per_line );
if (!b->backxrb->ximage->data) {
_mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
XMesaDestroyImage( b->backxrb->ximage );
b->backxrb->ximage = NULL;
}
else {
/* this call just updates the width/origin fields in the xrb */
b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base,
b->backxrb->Base.InternalFormat,
b->backxrb->ximage->width,
b->backxrb->ximage->height);
}
}
b->backxrb->pixmap = None;
}
else if (b->db_mode == BACK_PIXMAP) {
if (!width)
width = 1;
if (!height)
height = 1;
/* Free the old back pixmap */
if (b->backxrb->pixmap) {
XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap );
}
/* Allocate new back pixmap */
b->backxrb->pixmap = XMesaCreatePixmap( b->xm_visual->display,
b->frontxrb->drawable,
width, height,
GET_VISUAL_DEPTH(b->xm_visual) );
b->backxrb->ximage = NULL;
}
}
/*
* A replacement for XAllocColor. This function should never * A replacement for XAllocColor. This function should never
* fail to allocate a color. When XAllocColor fails, we return * fail to allocate a color. When XAllocColor fails, we return
* the nearest matching color. If we have to allocate many colors * the nearest matching color. If we have to allocate many colors
@@ -715,10 +573,11 @@ noFaultXAllocColor( int client,
if (AllocColor(cmap, if (AllocColor(cmap,
&color->red, &color->green, &color->blue, &color->red, &color->green, &color->blue,
&color->pixel, &color->pixel,
client) == Success) { client) == Success)
#else #else
if (XAllocColor(dpy, cmap, color)) { if (XAllocColor(dpy, cmap, color))
#endif #endif
{
*exact = 1; *exact = 1;
*alloced = 1; *alloced = 1;
return; return;
@@ -808,13 +667,13 @@ noFaultXAllocColor( int client,
/**
/*
* Do setup for PF_GRAYSCALE pixel format. * Do setup for PF_GRAYSCALE pixel format.
* Note that buffer may be NULL. * Note that buffer may be NULL.
*/ */
static GLboolean setup_grayscale( int client, XMesaVisual v, static GLboolean
XMesaBuffer buffer, XMesaColormap cmap ) setup_grayscale(int client, XMesaVisual v,
XMesaBuffer buffer, XMesaColormap cmap)
{ {
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
return GL_FALSE; return GL_FALSE;
@@ -893,7 +752,7 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
/* /**
* Setup RGB rendering for a window with a PseudoColor, StaticColor, * Setup RGB rendering for a window with a PseudoColor, StaticColor,
* or 8-bit TrueColor visual visual. We try to allocate a palette of 225 * or 8-bit TrueColor visual visual. We try to allocate a palette of 225
* colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
@@ -901,8 +760,9 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
* visuals, it has also proven to work from 4-bit up to 16-bit visuals. * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
* Dithering code contributed by Bob Mercier. * Dithering code contributed by Bob Mercier.
*/ */
static GLboolean setup_dithered_color( int client, XMesaVisual v, static GLboolean
XMesaBuffer buffer, XMesaColormap cmap ) setup_dithered_color(int client, XMesaVisual v,
XMesaBuffer buffer, XMesaColormap cmap)
{ {
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
return GL_FALSE; return GL_FALSE;
@@ -972,12 +832,13 @@ static GLboolean setup_dithered_color( int client, XMesaVisual v,
} }
/* /**
* Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode. * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
* HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
* Special dithering tables have to be initialized. * Special dithering tables have to be initialized.
*/ */
static void setup_8bit_hpcr( XMesaVisual v ) static void
setup_8bit_hpcr(XMesaVisual v)
{ {
/* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be) /* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be)
* To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
@@ -1027,11 +888,11 @@ static void setup_8bit_hpcr( XMesaVisual v )
} }
/* /**
* Setup RGB rendering for a window with a True/DirectColor visual. * Setup RGB rendering for a window with a True/DirectColor visual.
*/ */
static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, static void
XMesaColormap cmap ) setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
{ {
unsigned long rmask, gmask, bmask; unsigned long rmask, gmask, bmask;
(void) buffer; (void) buffer;
@@ -1171,10 +1032,11 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
/* /**
* Setup RGB rendering for a window with a monochrome visual. * Setup RGB rendering for a window with a monochrome visual.
*/ */
static void setup_monochrome( XMesaVisual v, XMesaBuffer b ) static void
setup_monochrome( XMesaVisual v, XMesaBuffer b )
{ {
(void) b; (void) b;
v->dithered_pf = v->undithered_pf = PF_1Bit; v->dithered_pf = v->undithered_pf = PF_1Bit;
@@ -1205,7 +1067,7 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
v->BitsPerPixel = bits_per_pixel(v); v->BitsPerPixel = bits_per_pixel(v);
assert(v->BitsPerPixel > 0); assert(v->BitsPerPixel > 0);
if (rgb_flag==GL_FALSE) { if (rgb_flag == GL_FALSE) {
/* COLOR-INDEXED WINDOW: /* COLOR-INDEXED WINDOW:
* Even if the visual is TrueColor or DirectColor we treat it as * Even if the visual is TrueColor or DirectColor we treat it as
* being color indexed. This is weird but might be useful to someone. * being color indexed. This is weird but might be useful to someone.
@@ -1264,14 +1126,14 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
if (b && window) { if (b && window) {
/* Do window-specific initializations */ /* Do window-specific initializations */
b->frontxrb->drawable = window; /* these should have been set in create_xmesa_buffer */
b->frontxrb->pixmap = (XMesaPixmap) window; ASSERT(b->frontxrb->drawable == window);
ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
/* Setup for single/double buffering */ /* Setup for single/double buffering */
if (v->mesa_visual.doubleBufferMode) { if (v->mesa_visual.doubleBufferMode) {
/* Double buffered */ /* Double buffered */
b->shm = check_for_xshm( v->display ); b->shm = check_for_xshm( v->display );
xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
} }
/* X11 graphics contexts */ /* X11 graphics contexts */
@@ -1732,13 +1594,13 @@ void XMesaDestroyContext( XMesaContext c )
/* /**
* XXX this isn't a public function! It's a hack for the 3Dfx driver. * Private function for creating an XMesaBuffer which corresponds to an
* Create a new XMesaBuffer from an X window. * X window or pixmap.
* Input: v - the XMesaVisual * \param v the window's XMesaVisual
* w - the window * \param w the window we're wrapping
* c - the context * \param c context used to initialize the buffer if 3Dfx mode in use.
* Return: new XMesaBuffer or NULL if error * \return new XMesaBuffer or NULL if error
*/ */
XMesaBuffer XMesaBuffer
XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
@@ -1754,6 +1616,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
XMesaColormap cmap; XMesaColormap cmap;
assert(v); assert(v);
assert(w);
(void) c; (void) c;
/* Check that window depth matches visual depth */ /* Check that window depth matches visual depth */
@@ -1790,10 +1653,9 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
} }
#endif #endif
b = alloc_xmesa_buffer(v, WINDOW, cmap); b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
if (!b) { if (!b)
return NULL; return NULL;
}
if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
(XMesaDrawable) w, cmap )) { (XMesaDrawable) w, cmap )) {
@@ -1908,10 +1770,9 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
assert(v); assert(v);
b = alloc_xmesa_buffer(v, PIXMAP, cmap); b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
if (!b) { if (!b)
return NULL; return NULL;
}
#ifdef XFree86Server #ifdef XFree86Server
client = CLIENT_ID(((XMesaDrawable)p)->id); client = CLIENT_ID(((XMesaDrawable)p)->id);
@@ -1940,14 +1801,16 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
XMesaDrawable drawable; /* X Pixmap Drawable */ XMesaDrawable drawable; /* X Pixmap Drawable */
XMesaBuffer b; XMesaBuffer b;
b = alloc_xmesa_buffer(v, PBUFFER, cmap);
if (!b) {
return NULL;
}
/* allocate pixmap for front buffer */ /* allocate pixmap for front buffer */
root = RootWindow( v->display, v->visinfo->screen ); root = RootWindow( v->display, v->visinfo->screen );
drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth ); drawable = XCreatePixmap(v->display, root, width, height,
v->visinfo->depth);
if (!drawable)
return NULL;
b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
if (!b)
return NULL;
if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
drawable, cmap)) { drawable, cmap)) {
@@ -2009,6 +1872,27 @@ void XMesaDestroyBuffer( XMesaBuffer b )
} }
/**
* Query the current window size and update the corresponding GLframebuffer
* and all attached renderbuffers.
* Called when:
* 1. the first time a buffer is bound to a context.
* 2. from glViewport to poll for window size changes
* 3. from the XMesaResizeBuffers() API function.
*/
void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
{
GLuint width, height;
xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height);
if (drawBuffer->mesa_buffer.Width != width ||
drawBuffer->mesa_buffer.Height != height) {
_mesa_resize_framebuffer(&(xmctx->mesa),
&(drawBuffer->mesa_buffer), width, height);
}
drawBuffer->mesa_buffer.Initialized = GL_TRUE;
}
/* /*
* Bind buffer b to context c and make c the current rendering context. * Bind buffer b to context c and make c the current rendering context.
@@ -2041,7 +1925,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
if (&(c->mesa) == _mesa_get_current_context() if (&(c->mesa) == _mesa_get_current_context()
&& c->mesa.DrawBuffer == &drawBuffer->mesa_buffer && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
&& c->mesa.ReadBuffer == &readBuffer->mesa_buffer && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
&& ((XMesaBuffer) c->mesa.DrawBuffer)->wasCurrent) { && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
/* same context and buffer, do nothing */ /* same context and buffer, do nothing */
return GL_TRUE; return GL_TRUE;
} }
@@ -2053,6 +1937,12 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
*/ */
_glapi_check_multithread(); _glapi_check_multithread();
if (!drawBuffer->mesa_buffer.Initialized)
xmesa_check_and_update_buffer_size(c, drawBuffer);
if (!readBuffer->mesa_buffer.Initialized)
xmesa_check_and_update_buffer_size(c, readBuffer);
_mesa_make_current(&(c->mesa), _mesa_make_current(&(c->mesa),
&drawBuffer->mesa_buffer, &drawBuffer->mesa_buffer,
&readBuffer->mesa_buffer); &readBuffer->mesa_buffer);
@@ -2123,7 +2013,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
{ {
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
if (ctx) { if (ctx) {
return (XMesaBuffer) (ctx->ReadBuffer); return XMESA_BUFFER(ctx->ReadBuffer);
} }
else { else {
return 0; return 0;
@@ -2212,9 +2102,7 @@ static void FXgetImage( XMesaBuffer b )
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
static unsigned short pixbuf[MAX_WIDTH]; static unsigned short pixbuf[MAX_WIDTH];
GLuint x, y; GLuint x, y;
int xpos, ypos; GLuint width, height;
XMesaWindow root;
unsigned int bw, depth, width, height;
XMesaContext xmesa = XMESA_CONTEXT(ctx); XMesaContext xmesa = XMESA_CONTEXT(ctx);
#ifdef XFree86Server #ifdef XFree86Server
@@ -2224,15 +2112,14 @@ static void FXgetImage( XMesaBuffer b )
height = b->frontxrb->pixmap->height; height = b->frontxrb->pixmap->height;
depth = b->frontxrb->pixmap->depth; depth = b->frontxrb->pixmap->depth;
#else #else
XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, xmesa_get_window_size(b->display, b, &width, &height);
&root, &xpos, &ypos, &width, &height, &bw, &depth); x = y = 0;
#endif #endif
if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
if (b->mesa_buffer.Width & 1) if (b->mesa_buffer.Width & 1)
b->mesa_buffer.Width--; /* prevent odd width */ b->mesa_buffer.Width--; /* prevent odd width */
xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height);
} }
/* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */ /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
@@ -2646,24 +2533,11 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
* This is typically called when the window size changes and we need * This is typically called when the window size changes and we need
* to reallocate the buffer's back/depth/stencil/accum buffers. * to reallocate the buffer's back/depth/stencil/accum buffers.
*/ */
void XMesaResizeBuffers( XMesaBuffer b ) void
XMesaResizeBuffers( XMesaBuffer b )
{ {
#ifdef XFree86Server
GLuint winwidth, winheight;
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
XMesaContext xmctx = XMESA_CONTEXT(ctx);
winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); xmesa_check_and_update_buffer_size(xmctx, b);
winheight = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
xmesa_resize_buffers(ctx, &(b->mesa_buffer), winwidth, winheight);
#else
Window root;
int xpos, ypos;
unsigned int width, height, bw, depth;
GET_CURRENT_CONTEXT(ctx);
XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap,
&root, &xpos, &ypos, &width, &height, &bw, &depth);
xmesa_resize_buffers(ctx, &(b->mesa_buffer), width, height);
#endif
} }

View File

@@ -1,8 +1,8 @@
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 6.5 * Version: 6.5.2
* *
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,12 @@
*/ */
/**
* \file xm_buffer.h
* Framebuffer and renderbuffer-related functions.
*/
#include "glxheader.h" #include "glxheader.h"
#include "GL/xmesa.h" #include "GL/xmesa.h"
#include "xmesaP.h" #include "xmesaP.h"
@@ -30,6 +36,213 @@
#include "renderbuffer.h" #include "renderbuffer.h"
#ifndef XFree86Server
static volatile int mesaXErrorFlag = 0;
/**
* Catches potential Xlib errors.
*/
static int
mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event)
{
(void) dpy;
(void) event;
mesaXErrorFlag = 1;
return 0;
}
#endif
/**
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
* Return: GL_TRUE if success, GL_FALSE if error
*/
#ifndef XFree86Server
static GLboolean
alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
{
#ifdef USE_XSHM
/*
* We have to do a _lot_ of error checking here to be sure we can
* really use the XSHM extension. It seems different servers trigger
* errors at different points if the extension won't work. Therefore
* we have to be very careful...
*/
GC gc;
int (*old_handler)(XMesaDisplay *, XErrorEvent *);
if (width == 0 || height == 0) {
/* this will be true the first time we're called on 'b' */
return GL_FALSE;
}
b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
b->xm_visual->visinfo->visual,
b->xm_visual->visinfo->depth,
ZPixmap, NULL, &b->shminfo,
width, height);
if (b->backxrb->ximage == NULL) {
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
* b->backxrb->ximage->height, IPC_CREAT|0777);
if (b->shminfo.shmid < 0) {
_mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
XDestroyImage(b->backxrb->ximage);
b->backxrb->ximage = NULL;
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.shmaddr = b->backxrb->ximage->data
= (char*)shmat(b->shminfo.shmid, 0, 0);
if (b->shminfo.shmaddr == (char *) -1) {
_mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
XDestroyImage(b->backxrb->ximage);
shmctl(b->shminfo.shmid, IPC_RMID, 0);
b->backxrb->ximage = NULL;
_mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
b->shm = 0;
return GL_FALSE;
}
b->shminfo.readOnly = False;
mesaXErrorFlag = 0;
old_handler = XSetErrorHandler(mesaHandleXError);
/* This may trigger the X protocol error we're ready to catch: */
XShmAttach(b->xm_visual->display, &b->shminfo);
XSync(b->xm_visual->display, False);
if (mesaXErrorFlag) {
/* we are on a remote display, this error is normal, don't print it */
XFlush(b->xm_visual->display);
mesaXErrorFlag = 0;
XDestroyImage(b->backxrb->ximage);
shmdt(b->shminfo.shmaddr);
shmctl(b->shminfo.shmid, IPC_RMID, 0);
b->backxrb->ximage = NULL;
b->shm = 0;
(void) XSetErrorHandler(old_handler);
return GL_FALSE;
}
shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */
/* Finally, try an XShmPutImage to be really sure the extension works */
gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL);
XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
XSync(b->xm_visual->display, False);
XFreeGC(b->xm_visual->display, gc);
(void) XSetErrorHandler(old_handler);
if (mesaXErrorFlag) {
XFlush(b->xm_visual->display);
mesaXErrorFlag = 0;
XDestroyImage(b->backxrb->ximage);
shmdt(b->shminfo.shmaddr);
shmctl(b->shminfo.shmid, IPC_RMID, 0);
b->backxrb->ximage = NULL;
b->shm = 0;
return GL_FALSE;
}
return GL_TRUE;
#else
/* Can't compile XSHM support */
return GL_FALSE;
#endif
}
#endif
/**
* Setup an off-screen pixmap or Ximage to use as the back buffer.
* Input: b - the X/Mesa buffer
*/
static void
alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
{
if (width == 0 || height == 0)
return;
if (b->db_mode == BACK_XIMAGE) {
/* Deallocate the old backxrb->ximage, if any */
if (b->backxrb->ximage) {
#if defined(USE_XSHM) && !defined(XFree86Server)
if (b->shm) {
XShmDetach(b->xm_visual->display, &b->shminfo);
XDestroyImage(b->backxrb->ximage);
shmdt(b->shminfo.shmaddr);
}
else
#endif
XMesaDestroyImage(b->backxrb->ximage);
b->backxrb->ximage = NULL;
}
/* Allocate new back buffer */
#ifdef XFree86Server
/* Allocate a regular XImage for the back buffer. */
b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
width, height, NULL);
{
#else
if (b->shm == 0 || !alloc_back_shm_ximage(b, width, height)) {
/* Allocate a regular XImage for the back buffer. */
b->backxrb->ximage = XCreateImage(b->xm_visual->display,
b->xm_visual->visinfo->visual,
GET_VISUAL_DEPTH(b->xm_visual),
ZPixmap, 0, /* format, offset */
NULL,
width, height,
8, 0); /* pad, bytes_per_line */
#endif
if (!b->backxrb->ximage) {
_mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.\n");
return;
}
b->backxrb->ximage->data = (char *) MALLOC(b->backxrb->ximage->height
* b->backxrb->ximage->bytes_per_line);
if (!b->backxrb->ximage->data) {
_mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.\n");
XMesaDestroyImage(b->backxrb->ximage);
b->backxrb->ximage = NULL;
}
else {
/* this call just updates the width/origin fields in the xrb */
b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base,
b->backxrb->Base.InternalFormat,
b->backxrb->ximage->width,
b->backxrb->ximage->height);
}
}
b->backxrb->pixmap = None;
}
else if (b->db_mode == BACK_PIXMAP) {
if (!width)
width = 1;
if (!height)
height = 1;
/* Free the old back pixmap */
if (b->backxrb->pixmap) {
XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap);
}
/* Allocate new back pixmap */
b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display,
b->frontxrb->drawable,
width, height,
GET_VISUAL_DEPTH(b->xm_visual));
b->backxrb->ximage = NULL;
}
}
static void static void
xmesa_delete_renderbuffer(struct gl_renderbuffer *rb) xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
{ {
@@ -68,7 +281,6 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
/** /**
* Reallocate renderbuffer storage for back color buffer. * Reallocate renderbuffer storage for back color buffer.
* XXX we should resize the back pixmap/ximage here.
*/ */
static GLboolean static GLboolean
xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
@@ -76,7 +288,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
{ {
struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
/* reallocate the back buffer XImage or Pixmap */
assert(xrb->Parent);
alloc_back_buffer(xrb->Parent, width, height);
/* same as front buffer */ /* same as front buffer */
/* XXX why is this here? */
(void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height); (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height);
/* plus... */ /* plus... */

View File

@@ -23,6 +23,11 @@
*/ */
/**
* \file xm_dd.h
* General device driver functions for Xlib driver.
*/
#include "glxheader.h" #include "glxheader.h"
#include "bufferobj.h" #include "bufferobj.h"
#include "buffers.h" #include "buffers.h"
@@ -89,47 +94,12 @@ const int xmesa_kernel1[16] = {
}; };
/* /** XXX obsolete ***/
* Return the size (width, height) of the X window for the given GLframebuffer.
* Output: width - width of buffer in pixels.
* height - height of buffer in pixels.
*/
static void static void
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
{ {
/* We can do this cast because the first field in the XMesaBuffer XMesaBuffer b = XMESA_BUFFER(buffer);
* struct is a GLframebuffer struct. If this weren't true, we'd xmesa_get_window_size(b->display, b, width, height);
* need a pointer from the GLframebuffer to the XMesaBuffer.
*/
const XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
unsigned int winwidth, winheight;
#ifdef XFree86Server
/* XFree86 GLX renderer */
winwidth = MIN2(xmBuffer->frontxrb->drawable->width, MAX_WIDTH);
winheight = MIN2(xmBuffer->frontxrb->drawable->height, MAX_HEIGHT);
#else
Window root;
Status stat;
int winx, winy;
unsigned int bw, d;
_glthread_LOCK_MUTEX(_xmesa_lock);
XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */
stat = XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap,
&root, &winx, &winy, &winwidth, &winheight, &bw, &d );
_glthread_UNLOCK_MUTEX(_xmesa_lock);
if (!stat) {
/* probably querying a window that's recently been destroyed */
_mesa_warning(NULL, "XGetGeometry failed!\n");
*width = *height = 1;
return;
}
#endif
*width = winwidth;
*height = winheight;
} }
@@ -567,26 +537,6 @@ clear_buffers( GLcontext *ctx, GLbitfield mask,
} }
/**
* Called by ctx->Driver.ResizeBuffers()
* Resize the front/back colorbuffers to match the latest window size.
*/
void
xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
GLuint width, GLuint height)
{
/* We can do this cast because the first field in the XMesaBuffer
* struct is a GLframebuffer struct. If this weren't true, we'd
* need a pointer from the GLframebuffer to the XMesaBuffer.
*/
XMesaBuffer xmBuffer = (XMesaBuffer) buffer;
xmesa_alloc_back_buffer(xmBuffer, width, height);
_mesa_resize_framebuffer(ctx, buffer, width, height);
}
#ifndef XFree86Server #ifndef XFree86Server
/* XXX this was never tested in the Xserver environment */ /* XXX this was never tested in the Xserver environment */
@@ -1120,33 +1070,6 @@ choose_tex_format( GLcontext *ctx, GLint internalFormat,
} }
/**
* Get the current drawing (and reading) window's size and update the
* corresponding gl_framebuffer(s) if needed.
*/
static void
update_framebuffer_size(GLcontext *ctx)
{
struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
GLuint newWidth, newHeight;
get_buffer_size(fb, &newWidth, &newHeight);
if (newWidth != fb->Width || newHeight != fb->Height) {
xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
}
if (ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
/* Update readbuffer's size */
struct gl_framebuffer *fb = ctx->WinSysReadBuffer;
GLuint newWidth, newHeight;
get_buffer_size(fb, &newWidth, &newHeight);
if (newWidth != fb->Width || newHeight != fb->Height) {
xmesa_resize_buffers(ctx, fb, newWidth, newHeight);
ctx->NewState |= _NEW_BUFFERS;
}
}
}
/** /**
* Called by glViewport. * Called by glViewport.
* This is a good time for us to poll the current X window size and adjust * This is a good time for us to poll the current X window size and adjust
@@ -1161,11 +1084,15 @@ update_framebuffer_size(GLcontext *ctx)
static void static void
xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{ {
XMesaContext xmctx = XMESA_CONTEXT(ctx);
XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer);
XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer);
xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf);
xmesa_check_and_update_buffer_size(xmctx, xmreadbuf);
(void) x; (void) x;
(void) y; (void) y;
(void) w; (void) w;
(void) h; (void) h;
update_framebuffer_size(ctx);
} }
@@ -1258,7 +1185,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
driver->ColorMask = color_mask; driver->ColorMask = color_mask;
driver->Enable = enable; driver->Enable = enable;
driver->Clear = clear_buffers; driver->Clear = clear_buffers;
driver->ResizeBuffers = xmesa_resize_buffers;
driver->Viewport = xmesa_viewport; driver->Viewport = xmesa_viewport;
#ifndef XFree86Server #ifndef XFree86Server
driver->CopyPixels = xmesa_CopyPixels; driver->CopyPixels = xmesa_CopyPixels;

View File

@@ -81,8 +81,9 @@ enum pixel_format {
}; };
/* /**
* "Derived" from GLvisual. Basically corresponds to an XVisualInfo. * Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
*/ */
struct xmesa_visual { struct xmesa_visual {
GLvisual mesa_visual; /* Device independent visual parameters */ GLvisual mesa_visual; /* Device independent visual parameters */
@@ -127,8 +128,9 @@ struct xmesa_visual {
}; };
/* /**
* "Derived" from __GLcontextRec. Basically corresponds to a GLXContext. * Context info, dDerived from GLcontext.
* Basically corresponds to a GLXContext.
*/ */
struct xmesa_context { struct xmesa_context {
GLcontext mesa; /* the core library context (containment) */ GLcontext mesa; /* the core library context (containment) */
@@ -146,7 +148,9 @@ struct xmesa_context {
}; };
/**
* Types of X/GLX drawables we might render into.
*/
typedef enum { typedef enum {
WINDOW, /* An X window */ WINDOW, /* An X window */
GLXWINDOW, /* GLX window */ GLXWINDOW, /* GLX window */
@@ -155,9 +159,11 @@ typedef enum {
} BufferType; } BufferType;
/* Values for db_mode: */ /** Values for db_mode: */
/*@{*/
#define BACK_PIXMAP 1 #define BACK_PIXMAP 1
#define BACK_XIMAGE 2 #define BACK_XIMAGE 2
/*@}*/
/** /**
@@ -175,6 +181,7 @@ struct xmesa_renderbuffer
{ {
struct gl_renderbuffer Base; /* Base class */ struct gl_renderbuffer Base; /* Base class */
XMesaBuffer Parent; /**< The XMesaBuffer this renderbuffer belongs to */
XMesaDrawable drawable; /* Usually the X window ID */ XMesaDrawable drawable; /* Usually the X window ID */
XMesaPixmap pixmap; /* Back color buffer */ XMesaPixmap pixmap; /* Back color buffer */
XMesaImage *ximage; /* The back buffer, if not using a Pixmap */ XMesaImage *ximage; /* The back buffer, if not using a Pixmap */
@@ -194,8 +201,9 @@ struct xmesa_renderbuffer
}; };
/* /**
* "Derived" from GLframebuffer. Basically corresponds to a GLXDrawable. * Framebuffer information, derived from.
* Basically corresponds to a GLXDrawable.
*/ */
struct xmesa_buffer { struct xmesa_buffer {
GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */ GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */
@@ -264,7 +272,7 @@ struct xmesa_buffer {
}; };
/* /**
* If pixelformat==PF_TRUECOLOR: * If pixelformat==PF_TRUECOLOR:
*/ */
#define PACK_TRUECOLOR( PIXEL, R, G, B ) \ #define PACK_TRUECOLOR( PIXEL, R, G, B ) \
@@ -273,7 +281,7 @@ struct xmesa_buffer {
| xmesa->xm_visual->BtoPixel[B]; \ | xmesa->xm_visual->BtoPixel[B]; \
/* /**
* If pixelformat==PF_TRUEDITHER: * If pixelformat==PF_TRUEDITHER:
*/ */
#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \ #define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
@@ -286,14 +294,14 @@ struct xmesa_buffer {
/* /**
* If pixelformat==PF_8A8B8G8R: * If pixelformat==PF_8A8B8G8R:
*/ */
#define PACK_8A8B8G8R( R, G, B, A ) \ #define PACK_8A8B8G8R( R, G, B, A ) \
( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) ) ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
/* /**
* Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
* shortcut. * shortcut.
*/ */
@@ -301,19 +309,19 @@ struct xmesa_buffer {
/* /**
* If pixelformat==PF_8R8G8B: * If pixelformat==PF_8R8G8B:
*/ */
#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) ) #define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
/* /**
* If pixelformat==PF_5R6G5B: * If pixelformat==PF_5R6G5B:
*/ */
#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) ) #define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
/* /**
* If pixelformat==PF_8A8R8G8B: * If pixelformat==PF_8A8R8G8B:
*/ */
#define PACK_8A8R8G8B( R, G, B, A ) \ #define PACK_8A8R8G8B( R, G, B, A ) \
@@ -321,7 +329,7 @@ struct xmesa_buffer {
/* /**
* If pixelformat==PF_DITHER: * If pixelformat==PF_DITHER:
* *
* Improved 8-bit RGB dithering code contributed by Bob Mercier * Improved 8-bit RGB dithering code contributed by Bob Mercier
@@ -398,7 +406,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
/* /**
* If pixelformat==PF_LOOKUP: * If pixelformat==PF_LOOKUP:
*/ */
#define _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12) #define _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12)
@@ -412,8 +420,7 @@ extern const int xmesa_kernel8[DITH_DY * DITH_DX];
_dither_lookup(DITH_B, (B)))] _dither_lookup(DITH_B, (B)))]
/**
/*
* If pixelformat==PF_HPCR: * If pixelformat==PF_HPCR:
* *
* HP Color Recovery dithering (ad@lms.be 30/08/95) * HP Color Recovery dithering (ad@lms.be 30/08/95)
@@ -433,7 +440,7 @@ extern const short xmesa_HPCR_DRGB[3][2][16];
/* /**
* If pixelformat==PF_1BIT: * If pixelformat==PF_1BIT:
*/ */
extern const int xmesa_kernel1[16]; extern const int xmesa_kernel1[16];
@@ -444,20 +451,20 @@ extern const int xmesa_kernel1[16];
/* /**
* If pixelformat==PF_GRAYSCALE: * If pixelformat==PF_GRAYSCALE:
*/ */
#define GRAY_RGB( R, G, B ) XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3] #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: * Converts a GL window Y coord to an X window Y coord:
*/ */
#define YFLIP(XRB, Y) ((XRB)->bottom - (Y)) #define YFLIP(XRB, Y) ((XRB)->bottom - (Y))
/* /**
* Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage: * Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage:
* X==0 is left, Y==0 is bottom. * X==0 is left, Y==0 is bottom.
*/ */
@@ -475,23 +482,6 @@ extern const int xmesa_kernel1[16];
/*
* 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.
*/
#define XMESA_CONTEXT(MESACTX) ((XMesaContext) (MESACTX))
/*
* 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.
*/
#define XMESA_BUFFER(MESABUFF) ((XMesaBuffer) (MESABUFF))
/* /*
* External functions: * External functions:
*/ */
@@ -506,21 +496,25 @@ xmesa_color_to_pixel( GLcontext *ctx,
GLuint pixelFormat ); GLuint pixelFormat );
extern void extern void
xmesa_alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height); xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, extern void
GLuint width, GLuint height); xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
extern void xmesa_init_driver_functions( XMesaVisual xmvisual, extern void
struct dd_function_table *driver ); xmesa_init_driver_functions( XMesaVisual xmvisual,
struct dd_function_table *driver );
extern void xmesa_update_state( GLcontext *ctx, GLbitfield new_state ); extern void
xmesa_update_state( GLcontext *ctx, GLbitfield new_state );
extern void extern void
xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb, xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb,
enum pixel_format pixelformat, GLint depth); enum pixel_format pixelformat, GLint depth);
extern void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy); extern void
xmesa_destroy_buffers_on_display(XMesaDisplay *dpy);
/** /**
@@ -533,6 +527,30 @@ xmesa_renderbuffer(struct gl_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;
}
/**
* 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 *b)
{
return (XMesaBuffer) b;
}
/* Plugged into the software rasterizer. Try to use internal /* Plugged into the software rasterizer. Try to use internal
* swrast-style point, line and triangle functions. * swrast-style point, line and triangle functions.
*/ */