From d21fa9cd79e4198b673c1453b8bc05749f8a73eb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 14 Oct 2006 22:52:17 +0000 Subject: [PATCH] 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. --- src/mesa/drivers/x11/xm_api.c | 582 ++++++++++++------------------- src/mesa/drivers/x11/xm_buffer.c | 223 +++++++++++- src/mesa/drivers/x11/xm_dd.c | 100 +----- src/mesa/drivers/x11/xmesaP.h | 112 +++--- 4 files changed, 526 insertions(+), 491 deletions(-) diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index e0187d2b208..6aa8dc5d7d3 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -22,8 +22,10 @@ * 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: @@ -68,13 +70,8 @@ #include "framebuffer.h" #include "glthread.h" #include "imports.h" -#include "matrix.h" -#include "mtypes.h" #include "macros.h" #include "renderbuffer.h" -#include "texformat.h" -#include "texobj.h" -#include "texstore.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "array_cache/acache.h" @@ -87,14 +84,14 @@ #include #endif -/* +/** * Global X driver lock */ _glthread_Mutex _xmesa_lock; -/* +/** * Lookup tables for HPCR pixel format: */ 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. */ #ifndef XFree86Server @@ -174,23 +171,7 @@ static int host_byte_order( void ) #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. * Return: 0 = not 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 * 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) { 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. * For example, if we request a 24-bit deep visual we may actually need/get * 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 * 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; int i; assert(depth > 0); @@ -259,12 +241,7 @@ static int bits_per_pixel( XMesaVisual xmv ) return screenInfo.formats[i].bitsPerPixel; } return depth; /* should never get here, but this should be safe */ -} - #else - -static int bits_per_pixel( XMesaVisual xmv ) -{ XMesaDisplay *dpy = xmv->display; XMesaVisualInfo visinfo = xmv->visinfo; XMesaImage *img; @@ -285,8 +262,8 @@ static int bits_per_pixel( XMesaVisual xmv ) img->data = NULL; XMesaDestroyImage( img ); return bitsPerPixel; -} #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 *****/ /**********************************************************************/ @@ -333,80 +349,110 @@ static XMesaBuffer XMesaBufferList = NULL; /** - * Allocate a new XMesaBuffer, initialize basic fields and add to - * the list of all buffers. + * Allocate a new XMesaBuffer object which corresponds to the given drawable. + * 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 -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); - if (b) { - GLboolean swAlpha; + GLboolean swAlpha; + XMesaBuffer b; - b->display = vis->display; - b->xm_visual = vis; - b->type = type; - b->cmap = cmap; + ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); - _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); + b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); + if (!b) + return NULL; + + b->display = vis->display; + b->xm_visual = vis; + b->type = type; + b->cmap = cmap; - /* Allocate the framebuffer's renderbuffers */ - assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); - assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); - /* front renderbuffer */ - b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, + /* + * Front renderbuffer + */ + b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_FALSE); - _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); - /* 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); - } + if (!b->frontxrb) { + _mesa_free(b); + return NULL; + } + 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); - /* 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; + /* + * 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); + } - _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; + /* + * 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; } -/* +/** * Find an XMesaBuffer by matching X display and colormap but NOT matching * the notThis buffer. */ -static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy, - XMesaColormap cmap, - XMesaBuffer notThis) +static XMesaBuffer +find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) { XMesaBuffer b; 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 * entries. */ -static void free_xmesa_buffer(int client, XMesaBuffer buffer) +static void +free_xmesa_buffer(int client, XMesaBuffer buffer) { XMesaBuffer prev = NULL, b; (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->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 * fail to allocate a color. When XAllocColor fails, we return * the nearest matching color. If we have to allocate many colors @@ -715,10 +573,11 @@ noFaultXAllocColor( int client, if (AllocColor(cmap, &color->red, &color->green, &color->blue, &color->pixel, - client) == Success) { + client) == Success) #else - if (XAllocColor(dpy, cmap, color)) { + if (XAllocColor(dpy, cmap, color)) #endif + { *exact = 1; *alloced = 1; return; @@ -808,13 +667,13 @@ noFaultXAllocColor( int client, - -/* +/** * Do setup for PF_GRAYSCALE pixel format. * Note that buffer may be NULL. */ -static GLboolean setup_grayscale( int client, XMesaVisual v, - XMesaBuffer buffer, XMesaColormap cmap ) +static GLboolean +setup_grayscale(int client, XMesaVisual v, + XMesaBuffer buffer, XMesaColormap cmap) { if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 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, * 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 @@ -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. * Dithering code contributed by Bob Mercier. */ -static GLboolean setup_dithered_color( int client, XMesaVisual v, - XMesaBuffer buffer, XMesaColormap cmap ) +static GLboolean +setup_dithered_color(int client, XMesaVisual v, + XMesaBuffer buffer, XMesaColormap cmap) { if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 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. * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. * 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) * 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. */ -static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, - XMesaColormap cmap ) +static void +setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap) { unsigned long rmask, gmask, bmask; (void) buffer; @@ -1171,10 +1032,11 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, -/* +/** * 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; 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); assert(v->BitsPerPixel > 0); - if (rgb_flag==GL_FALSE) { + if (rgb_flag == GL_FALSE) { /* COLOR-INDEXED WINDOW: * Even if the visual is TrueColor or DirectColor we treat it as * 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) { /* Do window-specific initializations */ - b->frontxrb->drawable = window; - b->frontxrb->pixmap = (XMesaPixmap) window; + /* these should have been set in create_xmesa_buffer */ + ASSERT(b->frontxrb->drawable == window); + ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window); /* Setup for single/double buffering */ if (v->mesa_visual.doubleBufferMode) { /* Double buffered */ b->shm = check_for_xshm( v->display ); - xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height); } /* 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. - * Create a new XMesaBuffer from an X window. - * Input: v - the XMesaVisual - * w - the window - * c - the context - * Return: new XMesaBuffer or NULL if error +/** + * Private function for creating an XMesaBuffer which corresponds to an + * X window or pixmap. + * \param v the window's XMesaVisual + * \param w the window we're wrapping + * \param c context used to initialize the buffer if 3Dfx mode in use. + * \return new XMesaBuffer or NULL if error */ XMesaBuffer XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) @@ -1754,6 +1616,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) XMesaColormap cmap; assert(v); + assert(w); (void) c; /* Check that window depth matches visual depth */ @@ -1790,10 +1653,9 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) } #endif - b = alloc_xmesa_buffer(v, WINDOW, cmap); - if (!b) { + b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap); + if (!b) return NULL; - } if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, (XMesaDrawable) w, cmap )) { @@ -1908,10 +1770,9 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) assert(v); - b = alloc_xmesa_buffer(v, PIXMAP, cmap); - if (!b) { + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) return NULL; - } #ifdef XFree86Server client = CLIENT_ID(((XMesaDrawable)p)->id); @@ -1940,14 +1801,16 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, XMesaDrawable drawable; /* X Pixmap Drawable */ XMesaBuffer b; - b = alloc_xmesa_buffer(v, PBUFFER, cmap); - if (!b) { - return NULL; - } - /* allocate pixmap for front buffer */ 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, 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. @@ -2041,7 +1925,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, if (&(c->mesa) == _mesa_get_current_context() && c->mesa.DrawBuffer == &drawBuffer->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 */ return GL_TRUE; } @@ -2053,6 +1937,12 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, */ _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), &drawBuffer->mesa_buffer, &readBuffer->mesa_buffer); @@ -2123,7 +2013,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void ) { GET_CURRENT_CONTEXT(ctx); if (ctx) { - return (XMesaBuffer) (ctx->ReadBuffer); + return XMESA_BUFFER(ctx->ReadBuffer); } else { return 0; @@ -2212,9 +2102,7 @@ static void FXgetImage( XMesaBuffer b ) GET_CURRENT_CONTEXT(ctx); static unsigned short pixbuf[MAX_WIDTH]; GLuint x, y; - int xpos, ypos; - XMesaWindow root; - unsigned int bw, depth, width, height; + GLuint width, height; XMesaContext xmesa = XMESA_CONTEXT(ctx); #ifdef XFree86Server @@ -2224,15 +2112,14 @@ static void FXgetImage( XMesaBuffer b ) height = b->frontxrb->pixmap->height; depth = b->frontxrb->pixmap->depth; #else - XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, - &root, &xpos, &ypos, &width, &height, &bw, &depth); + xmesa_get_window_size(b->display, b, &width, &height); + x = y = 0; #endif if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); if (b->mesa_buffer.Width & 1) 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? */ @@ -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 * 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); - - winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); - 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 + XMesaContext xmctx = XMESA_CONTEXT(ctx); + xmesa_check_and_update_buffer_size(xmctx, b); } diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index 2a44e126f78..98ae372e162 100644 --- a/src/mesa/drivers/x11/xm_buffer.c +++ b/src/mesa/drivers/x11/xm_buffer.c @@ -1,8 +1,8 @@ /* * 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 * 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 "GL/xmesa.h" #include "xmesaP.h" @@ -30,6 +36,213 @@ #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 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. - * XXX we should resize the back pixmap/ximage here. */ static GLboolean 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); + /* reallocate the back buffer XImage or Pixmap */ + assert(xrb->Parent); + alloc_back_buffer(xrb->Parent, width, height); + /* same as front buffer */ + /* XXX why is this here? */ (void) xmesa_alloc_front_storage(ctx, rb, internalFormat, width, height); /* plus... */ diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index f48495366d1..df2fc48e93b 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -23,6 +23,11 @@ */ +/** + * \file xm_dd.h + * General device driver functions for Xlib driver. + */ + #include "glxheader.h" #include "bufferobj.h" #include "buffers.h" @@ -89,47 +94,12 @@ const int xmesa_kernel1[16] = { }; -/* - * 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. - */ +/** XXX obsolete ***/ static void get_buffer_size( 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. - */ - 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; + XMesaBuffer b = XMESA_BUFFER(buffer); + xmesa_get_window_size(b->display, b, width, height); } @@ -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 /* 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. * 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 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) y; (void) w; (void) h; - update_framebuffer_size(ctx); } @@ -1258,7 +1185,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual, driver->ColorMask = color_mask; driver->Enable = enable; driver->Clear = clear_buffers; - driver->ResizeBuffers = xmesa_resize_buffers; driver->Viewport = xmesa_viewport; #ifndef XFree86Server driver->CopyPixels = xmesa_CopyPixels; diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h index 4db0872621f..86b01e87378 100644 --- a/src/mesa/drivers/x11/xmesaP.h +++ b/src/mesa/drivers/x11/xmesaP.h @@ -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 { 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 { 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 { WINDOW, /* An X window */ GLXWINDOW, /* GLX window */ @@ -155,9 +159,11 @@ typedef enum { } BufferType; -/* Values for db_mode: */ +/** Values for db_mode: */ +/*@{*/ #define BACK_PIXMAP 1 #define BACK_XIMAGE 2 +/*@}*/ /** @@ -175,6 +181,7 @@ struct xmesa_renderbuffer { struct gl_renderbuffer Base; /* Base class */ + 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 */ @@ -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 { GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */ @@ -264,7 +272,7 @@ struct xmesa_buffer { }; -/* +/** * If pixelformat==PF_TRUECOLOR: */ #define PACK_TRUECOLOR( PIXEL, R, G, B ) \ @@ -273,7 +281,7 @@ struct xmesa_buffer { | xmesa->xm_visual->BtoPixel[B]; \ -/* +/** * If pixelformat==PF_TRUEDITHER: */ #define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \ @@ -286,14 +294,14 @@ struct xmesa_buffer { -/* +/** * 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. */ @@ -301,19 +309,19 @@ struct xmesa_buffer { -/* +/** * 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 ) \ @@ -321,7 +329,7 @@ struct xmesa_buffer { -/* +/** * If pixelformat==PF_DITHER: * * 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: */ #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)))] - -/* +/** * If pixelformat==PF_HPCR: * * 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: */ extern const int xmesa_kernel1[16]; @@ -444,20 +451,20 @@ extern const int xmesa_kernel1[16]; -/* +/** * 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. */ @@ -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: */ @@ -506,21 +496,25 @@ xmesa_color_to_pixel( GLcontext *ctx, GLuint pixelFormat ); 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, - GLuint width, GLuint height); +extern void +xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer); -extern void xmesa_init_driver_functions( XMesaVisual xmvisual, - struct dd_function_table *driver ); +extern void +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 xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb, 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 * swrast-style point, line and triangle functions. */ -- 2.30.2