diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-14 22:52:17 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-14 22:52:17 +0000 |
commit | d21fa9cd79e4198b673c1453b8bc05749f8a73eb (patch) | |
tree | f10a9da5ea404ce5b0040f5682d7d9cdfb2b2391 /src/mesa/drivers/x11/xm_api.c | |
parent | 2b46f4b85330a579ae919f3f31af1550b5affdee (diff) |
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.
Diffstat (limited to 'src/mesa/drivers/x11/xm_api.c')
-rw-r--r-- | src/mesa/drivers/x11/xm_api.c | 582 |
1 files changed, 228 insertions, 354 deletions
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index e0187d2b20..6aa8dc5d7d 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 <GL/glxtokens.h> #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); } |