X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Ffakeglx.c;h=eecd52aa32b079fc82733abe2e18312263d7ef29;hb=0c54e47c0e93f725b8bc028b0d4614011dbe3fef;hp=a616915f1d9c5cb5c2fc21f0eb576721f9226928;hpb=529614cd1a1e426ca7ad019795a6b72ad51cd9e6;p=mesa.git diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index a616915f1d9..eecd52aa32b 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.0.1 + * Version: 6.5.2 * - * Copyright (C) 1999-2004 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"), @@ -52,6 +52,9 @@ #include "xfonts.h" #include "xmesaP.h" +#ifdef __VMS +#define _mesa_sprintf sprintf +#endif /* This indicates the client-side GLX API and GLX encoder version. */ #define CLIENT_MAJOR_VERSION 1 @@ -77,23 +80,9 @@ "GLX_ARB_get_proc_address " \ "GLX_EXT_visual_info " \ "GLX_EXT_visual_rating " \ - "GLX_SGI_video_sync " \ + /*"GLX_SGI_video_sync "*/ \ "GLX_SGIX_fbconfig " \ "GLX_SGIX_pbuffer " -/* - "GLX_ARB_render_texture" -*/ - -/* Silence compiler warnings */ -extern void Fake_glXDummyFunc( void ); -void Fake_glXDummyFunc( void ) -{ - (void) kernel8; - (void) DitherValues; - (void) HPCR_DRGB; - (void) kernel1; -} - /* * Our fake GLX context will contain a "real" GLX context and an XMesa context. @@ -119,8 +108,7 @@ struct fake_glx_context { #define DONT_CARE -1 -#define MAX_VISUALS 100 -static XMesaVisual VisualTable[MAX_VISUALS]; +static XMesaVisual *VisualTable = NULL; static int NumVisuals = 0; @@ -150,11 +138,11 @@ typedef struct _OverlayInfo { - /* * Test if the given XVisualInfo is usable for Mesa rendering. */ -static GLboolean is_usable_visual( XVisualInfo *vinfo ) +static GLboolean +is_usable_visual( XVisualInfo *vinfo ) { switch (vinfo->CLASS) { case StaticGray: @@ -182,25 +170,22 @@ static GLboolean is_usable_visual( XVisualInfo *vinfo ) -/* - * Return the level (overlay, normal, underlay) of a given XVisualInfo. - * Input: dpy - the X display - * vinfo - the XVisualInfo to test - * Return: level of the visual: - * 0 = normal planes - * >0 = overlay planes - * <0 = underlay planes +/** + * Get an array OverlayInfo records for specified screen. + * \param dpy the display + * \param screen screen number + * \param numOverlays returns numver of OverlayInfo records + * \return pointer to OverlayInfo array, free with XFree() */ -static int level_of_visual( Display *dpy, XVisualInfo *vinfo ) +static OverlayInfo * +GetOverlayInfo(Display *dpy, int screen, int *numOverlays) { Atom overlayVisualsAtom; - OverlayInfo *overlay_info = NULL; - int numOverlaysPerScreen; - Status status; Atom actualType; - int actualFormat; + Status status; + unsigned char *ovInfo; unsigned long sizeData, bytesLeft; - int i; + int actualFormat; /* * The SERVER_OVERLAY_VISUALS property on the root window contains @@ -211,25 +196,50 @@ static int level_of_visual( Display *dpy, XVisualInfo *vinfo ) return 0; } - status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ), + status = XGetWindowProperty(dpy, RootWindow(dpy, screen), overlayVisualsAtom, 0L, (long) 10000, False, overlayVisualsAtom, &actualType, &actualFormat, &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); + &ovInfo); if (status != Success || actualType != overlayVisualsAtom || actualFormat != 32 || sizeData < 4) { /* something went wrong */ - XFree((void *) overlay_info); + XFree((void *) ovInfo); + *numOverlays = 0; + return NULL; + } + + *numOverlays = sizeData / 4; + return (OverlayInfo *) ovInfo; +} + + + +/** + * Return the level (overlay, normal, underlay) of a given XVisualInfo. + * Input: dpy - the X display + * vinfo - the XVisualInfo to test + * Return: level of the visual: + * 0 = normal planes + * >0 = overlay planes + * <0 = underlay planes + */ +static int +level_of_visual( Display *dpy, XVisualInfo *vinfo ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { return 0; } /* search the overlay visual list for the visual ID of interest */ - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ioverlay_visual==vinfo->visualid) { + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { /* found the visual */ if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { int level = ov->layer; @@ -262,7 +272,7 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, GLint depth_size, GLint stencil_size, GLint accumRedSize, GLint accumGreenSize, GLint accumBlueSize, GLint accumAlphaSize, - GLint level ) + GLint level, GLint numAuxBuffers ) { GLboolean ximageFlag = GL_TRUE; XMesaVisual xmvis; @@ -292,11 +302,16 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, else comparePointers = GL_FALSE; + /* Force the visual to have an alpha channel */ + if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + alphaFlag = GL_TRUE; + /* First check if a matching visual is already in the list */ for (i=0; idisplay == dpy - && v->level == level + && v->mesa_visual.level == level + && v->mesa_visual.numAuxBuffers == numAuxBuffers && v->ximage_flag == ximageFlag && v->mesa_visual.rgbMode == rgbFlag && v->mesa_visual.doubleBufferMode == dbFlag @@ -318,11 +333,6 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, /* Create a new visual and add it to the list. */ - if (NumVisuals >= MAX_VISUALS) { - _mesa_problem(NULL, "GLX Error: maximum number of visuals exceeded"); - return NULL; - } - xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, stereoFlag, ximageFlag, depth_size, stencil_size, @@ -334,14 +344,59 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, * if we need to search for it in find_glx_visual(). */ xmvis->vishandle = vinfo; + /* Allocate more space for additional visual */ + VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, + sizeof(XMesaVisual) * NumVisuals, + sizeof(XMesaVisual) * (NumVisuals + 1)); /* add xmvis to the list */ VisualTable[NumVisuals] = xmvis; NumVisuals++; + /* XXX minor hack, because XMesaCreateVisual doesn't support an + * aux buffers parameter. + */ + xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; } return xmvis; } +/** + * Return the default number of bits for the Z buffer. + * If defined, use the MESA_GLX_DEPTH_BITS env var value. + * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. + * XXX probably do the same thing for stencil, accum, etc. + */ +static GLint +default_depth_bits(void) +{ + int zBits; + const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + if (zEnv) + zBits = _mesa_atoi(zEnv); + else + zBits = DEFAULT_SOFTWARE_DEPTH_BITS; + return zBits; +} + +static GLint +default_alpha_bits(void) +{ + int aBits; + const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); + if (aEnv) + aBits = _mesa_atoi(aEnv); + else + aBits = 0; + return aBits; +} + +static GLint +default_accum_bits(void) +{ + return 16; +} + + /* * Create a GLX visual from a regular XVisualInfo. @@ -355,6 +410,9 @@ static XMesaVisual create_glx_visual( Display *dpy, XVisualInfo *visinfo ) { int vislevel; + GLint zBits = default_depth_bits(); + GLint accBits = default_accum_bits(); + GLboolean alphaFlag = default_alpha_bits() > 0; vislevel = level_of_visual( dpy, visinfo ); if (vislevel) { @@ -367,7 +425,8 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) 0, /* depth bits */ 0, /* stencil bits */ 0,0,0,0, /* accum bits */ - vislevel /* level */ + vislevel, /* level */ + 0 /* numAux */ ); } else if (is_usable_visual( visinfo )) { @@ -378,13 +437,11 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) GL_FALSE, /* alpha */ GL_TRUE, /* double */ GL_FALSE, /* stereo */ - DEFAULT_SOFTWARE_DEPTH_BITS, - 8 * sizeof(GLstencil), - 0 * sizeof(GLaccum), /* r */ - 0 * sizeof(GLaccum), /* g */ - 0 * sizeof(GLaccum), /* b */ - 0 * sizeof(GLaccum), /* a */ - 0 /* level */ + zBits, + STENCIL_BITS, + 0, 0, 0, 0, /* accum bits */ + 0, /* level */ + 0 /* numAux */ ); } else { @@ -393,16 +450,17 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) /* can be done? They should use glXChooseVisual(). */ return save_glx_visual( dpy, visinfo, GL_TRUE, /* rgb */ - GL_FALSE, /* alpha */ + alphaFlag, /* alpha */ GL_TRUE, /* double */ GL_FALSE, /* stereo */ - DEFAULT_SOFTWARE_DEPTH_BITS, - 8 * sizeof(GLstencil), - 8 * sizeof(GLaccum), /* r */ - 8 * sizeof(GLaccum), /* g */ - 8 * sizeof(GLaccum), /* b */ - 8 * sizeof(GLaccum), /* a */ - 0 /* level */ + zBits, + STENCIL_BITS, + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ + 0, /* level */ + 0 /* numAux */ ); } } @@ -442,54 +500,29 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo ) -/* +/** * Return the transparent pixel value for a GLX visual. * Input: glxvis - the glx_visual * Return: a pixel value or -1 if no transparent pixel */ -static int transparent_pixel( XMesaVisual glxvis ) +static int +transparent_pixel( XMesaVisual glxvis ) { Display *dpy = glxvis->display; XVisualInfo *vinfo = glxvis->visinfo; - Atom overlayVisualsAtom; - OverlayInfo *overlay_info = NULL; - int numOverlaysPerScreen; - Status status; - Atom actualType; - int actualFormat; - unsigned long sizeData, bytesLeft; - int i; - - /* - * The SERVER_OVERLAY_VISUALS property on the root window contains - * a list of overlay visuals. Get that list now. - */ - overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); - if (overlayVisualsAtom == None) { - return -1; - } - - status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ), - overlayVisualsAtom, 0L, (long) 10000, False, - overlayVisualsAtom, &actualType, &actualFormat, - &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; - if (status != Success || actualType != overlayVisualsAtom || - actualFormat != 32 || sizeData < 4) { - /* something went wrong */ - XFree((void *) overlay_info); + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { return -1; } - /* search the overlay visual list for the visual ID of interest */ - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ioverlay_visual==vinfo->visualid) { + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { /* found it! */ - if (ov->transparent_type==0) { + if (ov->transparent_type == 0) { /* type 0 indicates no transparency */ XFree((void *) overlay_info); return -1; @@ -509,11 +542,11 @@ static int transparent_pixel( XMesaVisual glxvis ) -/* +/** * Try to get an X visual which matches the given arguments. */ -static XVisualInfo *get_visual( Display *dpy, int scr, - unsigned int depth, int xclass ) +static XVisualInfo * +get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) { XVisualInfo temp, *vis; long mask; @@ -566,7 +599,8 @@ static XVisualInfo *get_visual( Display *dpy, int scr, * varname - the name of the environment variable * Return: an XVisualInfo pointer to NULL if error. */ -static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname) +static XVisualInfo * +get_env_visual(Display *dpy, int scr, const char *varname) { char value[100], type[100]; int depth, xclass = -1; @@ -611,9 +645,9 @@ static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname) * preferred_class - preferred GLX visual class or DONT_CARE * Return: pointer to an XVisualInfo or NULL. */ -static XVisualInfo *choose_x_visual( Display *dpy, int screen, - GLboolean rgba, int min_depth, - int preferred_class ) +static XVisualInfo * +choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, + int preferred_class ) { XVisualInfo *vis; int xclass, visclass = 0; @@ -781,20 +815,13 @@ static XVisualInfo *choose_x_visual( Display *dpy, int screen, * preferred_class - preferred GLX visual class or DONT_CARE * Return: pointer to an XVisualInfo or NULL. */ -static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, - GLboolean rgbFlag, - int level, int trans_type, - int trans_value, - int min_depth, - int preferred_class ) +static XVisualInfo * +choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, + int level, int trans_type, int trans_value, + int min_depth, int preferred_class ) { - Atom overlayVisualsAtom; OverlayInfo *overlay_info; int numOverlaysPerScreen; - Status status; - Atom actualType; - int actualFormat; - unsigned long sizeData, bytesLeft; int i; XVisualInfo *deepvis; int deepest; @@ -811,24 +838,8 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, default: preferred_class = DONT_CARE; } - /* - * The SERVER_OVERLAY_VISUALS property on the root window contains - * a list of overlay visuals. Get that list now. - */ - overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); - if (overlayVisualsAtom == (Atom) None) { - return NULL; - } - - status = XGetWindowProperty(dpy, RootWindow( dpy, scr ), - overlayVisualsAtom, 0L, (long) 10000, False, - overlayVisualsAtom, &actualType, &actualFormat, - &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); - - if (status != Success || actualType != overlayVisualsAtom || - actualFormat != 32 || sizeData < 4) { - /* something went wrong */ + overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); + if (!overlay_info) { return NULL; } @@ -836,12 +847,10 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, deepest = min_depth; deepvis = NULL; - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ilayer!=level) { /* failed overlay level criteria */ @@ -906,14 +915,96 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, } +/**********************************************************************/ +/*** Display-related functions ***/ +/**********************************************************************/ + + +/** + * Free all XMesaVisuals which are associated with the given display. + */ +static void +destroy_visuals_on_display(Display *dpy) +{ + int i; + for (i = 0; i < NumVisuals; i++) { + if (VisualTable[i]->display == dpy) { + /* remove this visual */ + int j; + free(VisualTable[i]); + for (j = i; j < NumVisuals - 1; j++) + VisualTable[j] = VisualTable[j + 1]; + NumVisuals--; + } + } +} + + +/** + * Called from XCloseDisplay() to let us free our display-related data. + */ +static int +close_display_callback(Display *dpy, XExtCodes *codes) +{ + destroy_visuals_on_display(dpy); + xmesa_destroy_buffers_on_display(dpy); + return 0; +} + + +/** + * Look for the named extension on given display and return a pointer + * to the _XExtension data, or NULL if extension not found. + */ +static _XExtension * +lookup_extension(Display *dpy, const char *extName) +{ + _XExtension *ext; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->name && strcmp(ext->name, extName) == 0) { + return ext; + } + } + return NULL; +} + + +/** + * Whenever we're given a new Display pointer, call this function to + * register our close_display_callback function. + */ +static void +register_with_display(Display *dpy) +{ + const char *extName = "MesaGLX"; + _XExtension *ext; + + ext = lookup_extension(dpy, extName); + if (!ext) { + XExtCodes *c = XAddExtension(dpy); + ext = dpy->ext_procs; /* new extension is at head of list */ + assert(c->extension == ext->codes.extension); + ext->name = _mesa_strdup(extName); + ext->close_display = close_display_callback; + } +} + + /**********************************************************************/ /*** Begin Fake GLX API Functions ***/ /**********************************************************************/ -static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, - GLboolean rgbModeDefault ) +/** + * Helper used by glXChooseVisual and glXChooseFBConfig. + * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for + * the later. + * In either case, the attribute list is terminated with the value 'None'. + */ +static XMesaVisual +choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) { + const GLboolean rgbModeDefault = fbConfig; const int *parselist; XVisualInfo *vis; int min_ci = 0; @@ -935,6 +1026,7 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, GLint caveat = DONT_CARE; XMesaVisual xmvis = NULL; int desiredVisualID = -1; + int numAux = 0; parselist = list; @@ -942,8 +1034,14 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, switch (*parselist) { case GLX_USE_GL: - /* ignore */ - parselist++; + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + /* skip */ + parselist++; + } break; case GLX_BUFFER_SIZE: parselist++; @@ -954,20 +1052,38 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, level = *parselist++; break; case GLX_RGBA: - rgb_flag = GL_TRUE; - parselist++; + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + rgb_flag = GL_TRUE; + parselist++; + } break; case GLX_DOUBLEBUFFER: - double_flag = GL_TRUE; - parselist++; + parselist++; + if (fbConfig) { + double_flag = *parselist++; + } + else { + double_flag = GL_TRUE; + } break; case GLX_STEREO: - stereo_flag = GL_TRUE; - return NULL; + parselist++; + if (fbConfig) { + stereo_flag = *parselist++; + } + else { + stereo_flag = GL_TRUE; + } + return NULL; /* stereo not supported */ case GLX_AUX_BUFFERS: - /* ignore */ - parselist++; parselist++; + numAux = *parselist++; + if (numAux > MAX_AUX_BUFFERS) + return NULL; break; case GLX_RED_SIZE: parselist++; @@ -985,7 +1101,7 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, parselist++; { GLint size = *parselist++; - alpha_flag = size>0 ? 1 : 0; + alpha_flag = size ? GL_TRUE : GL_FALSE; } break; case GLX_DEPTH_SIZE: @@ -1071,6 +1187,8 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, * FBConfig attribs. */ case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; parselist++; if (*parselist == GLX_RGBA_BIT) { rgb_flag = GL_TRUE; @@ -1084,6 +1202,8 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, parselist++; break; case GLX_DRAWABLE_TYPE: + if (!fbConfig) + return NULL; parselist++; if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { return NULL; /* bad bit */ @@ -1091,8 +1211,16 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, parselist++; break; case GLX_FBCONFIG_ID: + if (!fbConfig) + return NULL; parselist++; - desiredVisualID = *parselist; + desiredVisualID = *parselist++; + break; + case GLX_X_RENDERABLE: + if (!fbConfig) + return NULL; + parselist += 2; + /* ignore */ break; case None: @@ -1128,7 +1256,7 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, double_flag = GL_TRUE; if (vis->depth > 8) rgb_flag = GL_TRUE; - depth_size = DEFAULT_SOFTWARE_DEPTH_BITS; + depth_size = default_depth_bits(); stencil_size = STENCIL_BITS; /* XXX accum??? */ } @@ -1176,27 +1304,32 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, * return 16 to maintain performance with earlier versions of Mesa. */ if (depth_size > 24) - depth_size = 31; /* 32 causes int overflow problems */ + depth_size = 32; else if (depth_size > 16) depth_size = 24; - else if (depth_size > 0) - depth_size = DEFAULT_SOFTWARE_DEPTH_BITS; /*16*/ + else if (depth_size > 0) { + depth_size = default_depth_bits(); + } + + if (!alpha_flag) { + alpha_flag = default_alpha_bits() > 0; + } /* we only support one size of stencil and accum buffers. */ if (stencil_size > 0) stencil_size = STENCIL_BITS; if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || accumAlphaSize > 0) { - accumRedSize = ACCUM_BITS; - accumGreenSize = ACCUM_BITS; - accumBlueSize = ACCUM_BITS; - accumAlphaSize = alpha_flag ? ACCUM_BITS : 0; + accumRedSize = + accumGreenSize = + accumBlueSize = default_accum_bits(); + accumAlphaSize = alpha_flag ? accumRedSize : 0; } xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, stereo_flag, depth_size, stencil_size, accumRedSize, accumGreenSize, - accumBlueSize, accumAlphaSize, level ); + accumBlueSize, accumAlphaSize, level, numAux ); } return xmvis; @@ -1206,7 +1339,12 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list, static XVisualInfo * Fake_glXChooseVisual( Display *dpy, int screen, int *list ) { - XMesaVisual xmvis = choose_visual(dpy, screen, list, GL_FALSE); + XMesaVisual xmvis; + + /* register ourselves as an extension on this display */ + register_with_display(dpy); + + xmvis = choose_visual(dpy, screen, list, GL_FALSE); if (xmvis) { #if 0 return xmvis->vishandle; @@ -1240,7 +1378,9 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, return 0; /* deallocate unused windows/buffers */ +#if 0 XMesaGarbageCollect(); +#endif xmvis = find_glx_visual( dpy, visinfo ); if (!xmvis) { @@ -1248,7 +1388,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, xmvis = create_glx_visual( dpy, visinfo ); if (!xmvis) { /* unusable visual */ - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } } @@ -1256,7 +1396,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -1335,11 +1475,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { ((__GLXcontext *) ctx)->currentDpy = dpy; ((__GLXcontext *) ctx)->currentDrawable = draw; -#ifndef GLX_BUILT_IN_XMESA ((__GLXcontext *) ctx)->currentReadable = read; -#else - __glXSetCurrentContext(ctx); -#endif return True; } else { @@ -1354,9 +1490,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, MakeCurrent_PrevReadable = 0; MakeCurrent_PrevDrawBuffer = 0; MakeCurrent_PrevReadBuffer = 0; -#ifdef GLX_BUILT_IN_XMESA - /* XXX bind dummy context with __glXSetCurrentContext(ctx); */ -#endif return True; } else { @@ -1368,7 +1501,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } - static Bool Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) { @@ -1376,7 +1508,6 @@ Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) } - static GLXPixmap Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) { @@ -1396,7 +1527,7 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) if (!b) { return 0; } - return b->frontbuffer; + return b->frontxrb->pixmap; } @@ -1422,7 +1553,7 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, if (!b) { return 0; } - return b->frontbuffer; + return b->frontxrb->pixmap; } @@ -1439,7 +1570,6 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) } - static void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask ) @@ -1449,11 +1579,13 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, XMesaContext xm_src = fakeSrc->xmesaContext; XMesaContext xm_dst = fakeDst->xmesaContext; (void) dpy; + if (MakeCurrent_PrevContext == src) { + _mesa_Flush(); + } _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask ); } - static Bool Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) { @@ -1485,10 +1617,10 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) MakeCurrent_PrevReadBuffer = 0; XMesaDestroyContext( glxCtx->xmesaContext ); XMesaGarbageCollect(); + _mesa_free(glxCtx); } - static Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx ) { @@ -1508,7 +1640,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) XMesaSwapBuffers(buffer); } else if (_mesa_getenv("MESA_DEBUG")) { - _mesa_warning(NULL, "Mesa: glXSwapBuffers: invalid drawable\n"); + _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", + (int) drawable); } } @@ -1530,7 +1663,6 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, } - static Bool Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) { @@ -1543,7 +1675,6 @@ Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) } - /* * Query the GLX attributes of the given XVisualInfo. */ @@ -1553,15 +1684,19 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) ASSERT(xmvis); switch(attrib) { case GLX_USE_GL: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; *value = (int) True; return 0; case GLX_BUFFER_SIZE: *value = xmvis->visinfo->depth; return 0; case GLX_LEVEL: - *value = xmvis->level; + *value = xmvis->mesa_visual.level; return 0; case GLX_RGBA: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; if (xmvis->mesa_visual.rgbMode) { *value = True; } @@ -1576,7 +1711,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = (int) xmvis->mesa_visual.stereoMode; return 0; case GLX_AUX_BUFFERS: - *value = (int) False; + *value = xmvis->mesa_visual.numAuxBuffers; return 0; case GLX_RED_SIZE: *value = xmvis->mesa_visual.redBits; @@ -1623,11 +1758,11 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) } return 0; case GLX_TRANSPARENT_TYPE_EXT: - if (xmvis->level==0) { + if (xmvis->mesa_visual.level==0) { /* normal planes */ *value = GLX_NONE_EXT; } - else if (xmvis->level>0) { + else if (xmvis->mesa_visual.level>0) { /* overlay */ if (xmvis->mesa_visual.rgbMode) { *value = GLX_TRANSPARENT_RGB_EXT; @@ -1636,7 +1771,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = GLX_TRANSPARENT_INDEX_EXT; } } - else if (xmvis->level<0) { + else if (xmvis->mesa_visual.level<0) { /* underlay */ *value = GLX_NONE_EXT; } @@ -1668,8 +1803,8 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) */ case GLX_VISUAL_CAVEAT_EXT: /* test for zero, just in case */ - if (xmvis->VisualCaveat > 0) - *value = xmvis->VisualCaveat; + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; else *value = GLX_NONE_EXT; return 0; @@ -1750,7 +1885,7 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value ) { XMesaVisual xmvis; - + int k; if (!dpy || !visinfo) return GLX_BAD_ATTRIBUTE; @@ -1770,7 +1905,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, } } - return get_config(xmvis, attrib, value, GL_FALSE); + k = get_config(xmvis, attrib, value, GL_FALSE); + return k; } @@ -1870,28 +2006,6 @@ Fake_glXGetClientString( Display *dpy, int name ) */ -static GLXFBConfig * -Fake_glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - XMesaVisual xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); - if (xmvis) { - GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); - if (!config) { - *nitems = 0; - return NULL; - } - *nitems = 1; - config[0] = (GLXFBConfig) xmvis; - return (GLXFBConfig *) config; - } - else { - *nitems = 0; - return NULL; - } -} - - static int Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, int attribute, int *value ) @@ -1933,6 +2047,35 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) } +static GLXFBConfig * +Fake_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + XMesaVisual xmvis; + + if (!attribList || !attribList[0]) { + /* return list of all configs (per GLX_SGIX_fbconfig spec) */ + return Fake_glXGetFBConfigs(dpy, screen, nitems); + } + + xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); + if (xmvis) { + GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + if (!config) { + *nitems = 0; + return NULL; + } + *nitems = 1; + config[0] = (GLXFBConfig) xmvis; + return (GLXFBConfig *) config; + } + else { + *nitems = 0; + return NULL; + } +} + + static XVisualInfo * Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) { @@ -2066,7 +2209,10 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - return (GLXPbuffer) xmbuf->frontbuffer; + if (xmbuf) + return (GLXPbuffer) xmbuf->frontxrb->pixmap; + else + return 0; } @@ -2090,16 +2236,16 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, switch (attribute) { case GLX_WIDTH: - *value = xmbuf->width; + *value = xmbuf->mesa_buffer.Width; break; case GLX_HEIGHT: - *value = xmbuf->height; + *value = xmbuf->mesa_buffer.Height; break; case GLX_PRESERVED_CONTENTS: *value = True; break; case GLX_LARGEST_PBUFFER: - *value = xmbuf->width * xmbuf->height; + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; @@ -2132,7 +2278,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -2211,19 +2357,26 @@ Fake_glXSwapIntervalSGI(int interval) /*** GLX_SGI_video_sync ***/ +static unsigned int FrameCounter = 0; + static int Fake_glXGetVideoSyncSGI(unsigned int *count) { - (void) count; + /* this is a bogus implementation */ + *count = FrameCounter++; return 0; } static int Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { - (void) divisor; - (void) remainder; - (void) count; + if (divisor <= 0 || remainder < 0) + return GLX_BAD_VALUE; + /* this is a bogus implementation */ + FrameCounter++; + while (FrameCounter % divisor != remainder) + FrameCounter++; + *count = FrameCounter; return 0; } @@ -2327,7 +2480,7 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); - return xmbuf->frontbuffer; /* need to return an X ID */ + return xmbuf->frontxrb->pixmap; /* need to return an X ID */ } @@ -2348,7 +2501,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -2398,7 +2551,7 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, (void) dpy; - for (attrib = attribList; *attrib; attrib++) { + for (attrib = attribList; attrib && *attrib; attrib++) { switch (*attrib) { case GLX_PRESERVED_CONTENTS_SGIX: attrib++; @@ -2421,7 +2574,7 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - return (GLXPbuffer) xmbuf->frontbuffer; + return (GLXPbuffer) xmbuf->frontxrb->pixmap; } @@ -2450,13 +2603,13 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un *value = True; break; case GLX_LARGEST_PBUFFER_SGIX: - *value = xmbuf->width * xmbuf->height; + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; break; case GLX_WIDTH_SGIX: - *value = xmbuf->width; + *value = xmbuf->mesa_buffer.Width; break; case GLX_HEIGHT_SGIX: - *value = xmbuf->height; + *value = xmbuf->mesa_buffer.Height; break; case GLX_EVENT_MASK_SGIX: *value = 0; /* XXX might be wrong */ @@ -2691,32 +2844,19 @@ Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) } -/*** GLX_ARB_render_texture ***/ - -static Bool -Fake_glXBindTexImageARB( Display *dpy, GLXPbuffer pbuffer, int buffer ) -{ - return False; -} - - -static Bool -Fake_glXReleaseTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer ) -{ - return False; -} - - -static Bool -Fake_glXDrawableAttribARB( Display *dpy, GLXDrawable draw, const int *attribList ) -{ - return False; -} - +/* silence warning */ +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); -extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); -struct _glxapi_table *_mesa_GetGLXDispatchTable(void) +/** + * Create a new GLX API dispatch table with its function pointers + * initialized to point to Mesa's "fake" GLX API functions. + * Note: there's a similar function (_real_GetGLXDispatchTable) that + * returns a new dispatch table with all pointers initalized to point + * to "real" GLX functions (which understand GLX wire protocol, etc). + */ +struct _glxapi_table * +_mesa_GetGLXDispatchTable(void) { static struct _glxapi_table glx; @@ -2859,10 +2999,5 @@ struct _glxapi_table *_mesa_GetGLXDispatchTable(void) /*** GLX_MESA_agp_offset ***/ glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; - /*** GLX_ARB_render_texture ***/ - glx.BindTexImageARB = Fake_glXBindTexImageARB; - glx.ReleaseTexImageARB = Fake_glXReleaseTexImageARB; - glx.DrawableAttribARB = Fake_glXDrawableAttribARB; - return &glx; }