X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Ffakeglx.c;h=1587df66bcd48f1ce8e8db76427d1cc30826326b;hb=a8ec5dac3c8c564b1c405798f7703e0d8e650f2d;hp=ca3b69370669c660ad1023988390e6d057cb14b6;hpb=ab7c6ffadccbeb96b6f4ac58fb75e90697cd30c5;p=mesa.git diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index ca3b6937066..1587df66bcd 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.3 + * Version: 7.1 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -78,9 +78,10 @@ "GLX_MESA_pixmap_colormap " \ "GLX_MESA_release_buffers " \ "GLX_ARB_get_proc_address " \ + "GLX_EXT_texture_from_pixmap " \ "GLX_EXT_visual_info " \ "GLX_EXT_visual_rating " \ - "GLX_SGI_video_sync " \ + /*"GLX_SGI_video_sync "*/ \ "GLX_SGIX_fbconfig " \ "GLX_SGIX_pbuffer " @@ -345,7 +346,7 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, */ xmvis->vishandle = vinfo; /* Allocate more space for additional visual */ - VisualTable = _mesa_realloc( VisualTable, + VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, sizeof(XMesaVisual) * NumVisuals, sizeof(XMesaVisual) * (NumVisuals + 1)); /* add xmvis to the list */ @@ -378,6 +379,24 @@ default_depth_bits(void) 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; +} + /* @@ -393,6 +412,8 @@ 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) { @@ -430,15 +451,15 @@ 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 */ zBits, STENCIL_BITS, - ACCUM_BITS, /* r */ - ACCUM_BITS, /* g */ - ACCUM_BITS, /* b */ - ACCUM_BITS, /* a */ + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ 0, /* level */ 0 /* numAux */ ); @@ -895,6 +916,81 @@ choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, } +/**********************************************************************/ +/*** 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 ***/ /**********************************************************************/ @@ -1006,7 +1102,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) parselist++; { GLint size = *parselist++; - alpha_flag = size>0 ? 1 : 0; + alpha_flag = size ? GL_TRUE : GL_FALSE; } break; case GLX_DEPTH_SIZE: @@ -1092,6 +1188,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) * FBConfig attribs. */ case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; parselist++; if (*parselist == GLX_RGBA_BIT) { rgb_flag = GL_TRUE; @@ -1105,6 +1203,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 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 */ @@ -1112,10 +1212,42 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 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; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + parselist++; + if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT)) { + /* invalid bit */ + return NULL; + } + break; + case GLX_Y_INVERTED_EXT: + parselist++; /*skip*/ + break; +#endif + case None: /* end of list */ break; @@ -1197,22 +1329,26 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) * 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_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, @@ -1228,7 +1364,12 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 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; @@ -1262,7 +1403,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) { @@ -1270,7 +1413,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, xmvis = create_glx_visual( dpy, visinfo ); if (!xmvis) { /* unusable visual */ - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } } @@ -1278,7 +1421,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; } @@ -1322,11 +1465,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } if (!drawBuffer) { /* drawable must be a new window! */ - drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx); + drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); if (!drawBuffer) { /* Out of memory, or context/drawable depth mismatch */ return False; } +#ifdef FX + FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); +#endif } /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ @@ -1339,12 +1485,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } if (!readBuffer) { /* drawable must be a new window! */ - readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual, - read, xmctx); + readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); if (!readBuffer) { /* Out of memory, or context/drawable depth mismatch */ return False; } +#ifdef FX + FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); +#endif } MakeCurrent_PrevContext = ctx; @@ -1461,6 +1609,9 @@ 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 ); } @@ -1496,6 +1647,7 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) MakeCurrent_PrevReadBuffer = 0; XMesaDestroyContext( glxCtx->xmesaContext ); XMesaGarbageCollect(); + _mesa_free(glxCtx); } @@ -1751,6 +1903,27 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = xmvis->visinfo->visualid; break; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + /* XXX review */ + *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value = (GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ + break; + case GLX_Y_INVERTED_EXT: + *value = True; /*XXX*/ + break; +#endif + default: return GLX_BAD_ATTRIBUTE; } @@ -1985,10 +2158,15 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, if (!xmvis) return 0; - xmbuf = XMesaCreateWindowBuffer2(xmvis, win, NULL); + xmbuf = XMesaCreateWindowBuffer(xmvis, win); if (!xmbuf) return 0; +#ifdef FX + /* XXX this will segfault if actually called */ + FXcreateContext(xmvis, win, NULL, xmbuf); +#endif + (void) dpy; (void) attribList; /* Ignored in GLX 1.3 */ @@ -2013,16 +2191,102 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, { XMesaVisual v = (XMesaVisual) config; XMesaBuffer b; - - (void) dpy; - (void) config; - (void) pixmap; - (void) attribList; /* Ignored in GLX 1.3 */ + const int *attr; + int target = 0, format = 0, mipmap = 0; + int value; if (!dpy || !config || !pixmap) return 0; - b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + for (attr = attribList; *attr; attr++) { + switch (*attr) { + case GLX_TEXTURE_FORMAT_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_FORMAT_NONE_EXT: + case GLX_TEXTURE_FORMAT_RGB_EXT: + case GLX_TEXTURE_FORMAT_RGBA_EXT: + format = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_TEXTURE_TARGET_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_1D_EXT: + case GLX_TEXTURE_2D_EXT: + case GLX_TEXTURE_RECTANGLE_EXT: + target = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_MIPMAP_TEXTURE_EXT: + attr++; + if (*attr) + mipmap = 1; + break; + default: + /* error */ + return 0; + } + } + + if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (mipmap) { + if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_1D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + else if (target == GLX_TEXTURE_2D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_RECTANGLE_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + + if (format || target || mipmap) { + /* texture from pixmap */ + b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); + } + else { + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + } if (!b) { return 0; } @@ -2087,7 +2351,10 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - return (GLXPbuffer) xmbuf->frontxrb->pixmap; + if (xmbuf) + return (GLXPbuffer) xmbuf->frontxrb->pixmap; + else + return 0; } @@ -2125,8 +2392,20 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; return; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_TEXTURE_FORMAT_EXT: + *value = xmbuf->TextureFormat; + break; + case GLX_TEXTURE_TARGET_EXT: + *value = xmbuf->TextureTarget; + break; + case GLX_MIPMAP_TEXTURE_EXT: + *value = xmbuf->TextureMipmap; + break; +#endif + default: - return; /* GLX_BAD_ATTRIBUTE? */ + return; /* raise BadValue error */ } } @@ -2153,7 +2432,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; } @@ -2232,19 +2511,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; } @@ -2369,7 +2655,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; } @@ -2712,6 +2998,26 @@ Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) } +/*** GLX_EXT_texture_from_pixmap ***/ + +static void +Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaBindTexImage(dpy, b, buffer, attrib_list); +} + +static void +Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaReleaseTexImage(dpy, b, buffer); +} + + /* silence warning */ extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); @@ -2867,5 +3173,9 @@ _mesa_GetGLXDispatchTable(void) /*** GLX_MESA_agp_offset ***/ glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + /*** GLX_EXT_texture_from_pixmap ***/ + glx.BindTexImageEXT = Fake_glXBindTexImageEXT; + glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + return &glx; }