📄 glxcmds.c
字号:
fbconfigs_compatible( const __GLcontextModes * const a, const __GLcontextModes * const b ){ MATCH_DONT_CARE( doubleBufferMode ); MATCH_DONT_CARE( visualType ); MATCH_DONT_CARE( visualRating ); MATCH_DONT_CARE( xRenderable ); MATCH_DONT_CARE( fbconfigID ); MATCH_DONT_CARE( swapMethod ); MATCH_MINIMUM( rgbBits ); MATCH_MINIMUM( numAuxBuffers ); MATCH_MINIMUM( redBits ); MATCH_MINIMUM( greenBits ); MATCH_MINIMUM( blueBits ); MATCH_MINIMUM( alphaBits ); MATCH_MINIMUM( depthBits ); MATCH_MINIMUM( stencilBits ); MATCH_MINIMUM( accumRedBits ); MATCH_MINIMUM( accumGreenBits ); MATCH_MINIMUM( accumBlueBits ); MATCH_MINIMUM( accumAlphaBits ); MATCH_MINIMUM( sampleBuffers ); MATCH_MINIMUM( maxPbufferWidth ); MATCH_MINIMUM( maxPbufferHeight ); MATCH_MINIMUM( maxPbufferPixels ); MATCH_MINIMUM( samples ); MATCH_DONT_CARE( stereoMode ); MATCH_EXACT( level ); if ( ((a->drawableType & b->drawableType) == 0) || ((a->renderType & b->renderType) == 0) ) { return False; } /* There is a bug in a few of the XFree86 DDX drivers. They contain * visuals with a "transparent type" of 0 when they really mean GLX_NONE. * Technically speaking, it is a bug in the DDX driver, but there is * enough of an installed base to work around the problem here. In any * case, 0 is not a valid value of the transparent type, so we'll treat 0 * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and * 0 from the server to be a match to maintain backward compatibility with * the (broken) drivers. */ if ( a->transparentPixel != GLX_DONT_CARE && a->transparentPixel != 0 ) { if ( a->transparentPixel == GLX_NONE ) { if ( b->transparentPixel != GLX_NONE && b->transparentPixel != 0 ) return False; } else { MATCH_EXACT( transparentPixel ); } switch ( a->transparentPixel ) { case GLX_TRANSPARENT_RGB: MATCH_DONT_CARE( transparentRed ); MATCH_DONT_CARE( transparentGreen ); MATCH_DONT_CARE( transparentBlue ); MATCH_DONT_CARE( transparentAlpha ); break; case GLX_TRANSPARENT_INDEX: MATCH_DONT_CARE( transparentIndex ); break; default: break; } } return True;}/* There's some trickly language in the GLX spec about how this is supposed * to work. Basically, if a given component size is either not specified * or the requested size is zero, it is supposed to act like PERFER_SMALLER. * Well, that's really hard to do with the code as-is. This behavior is * closer to correct, but still not technically right. */#define PREFER_LARGER_OR_ZERO(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ if ( ((*a)-> comp) == 0 ) { \ return -1; \ } \ else if ( ((*b)-> comp) == 0 ) { \ return 1; \ } \ else { \ return ((*b)-> comp) - ((*a)-> comp) ; \ } \ } \ } while( 0 )#define PREFER_LARGER(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ return ((*b)-> comp) - ((*a)-> comp) ; \ } \ } while( 0 )#define PREFER_SMALLER(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ return ((*a)-> comp) - ((*b)-> comp) ; \ } \ } while( 0 )/** * Compare two GLXFBConfigs. This function is intended to be used as the * compare function passed in to qsort. * * \returns If \c a is a "better" config, according to the specification of * SGIX_fbconfig, a number less than zero is returned. If \c b is * better, then a number greater than zero is return. If both are * equal, zero is returned. * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */static intfbconfig_compare( const __GLcontextModes * const * const a, const __GLcontextModes * const * const b ){ /* The order of these comparisons must NOT change. It is defined by * the GLX 1.3 spec and ARB_multisample. */ PREFER_SMALLER( visualSelectGroup ); /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the * numerical sort order of the enums (0x8000, 0x8001, and 0x800D). */ PREFER_SMALLER( visualRating ); /* This isn't quite right. It is supposed to compare the sum of the * components the user specifically set minimums for. */ PREFER_LARGER_OR_ZERO( redBits ); PREFER_LARGER_OR_ZERO( greenBits ); PREFER_LARGER_OR_ZERO( blueBits ); PREFER_LARGER_OR_ZERO( alphaBits ); PREFER_SMALLER( rgbBits ); if ( ((*a)->doubleBufferMode != (*b)->doubleBufferMode) ) { /* Prefer single-buffer. */ return ( !(*a)->doubleBufferMode ) ? -1 : 1; } PREFER_SMALLER( numAuxBuffers ); PREFER_LARGER_OR_ZERO( depthBits ); PREFER_SMALLER( stencilBits ); /* This isn't quite right. It is supposed to compare the sum of the * components the user specifically set minimums for. */ PREFER_LARGER_OR_ZERO( accumRedBits ); PREFER_LARGER_OR_ZERO( accumGreenBits ); PREFER_LARGER_OR_ZERO( accumBlueBits ); PREFER_LARGER_OR_ZERO( accumAlphaBits ); PREFER_SMALLER( visualType ); /* None of the multisample specs say where this comparison should happen, * so I put it near the end. */ PREFER_SMALLER( sampleBuffers ); PREFER_SMALLER( samples ); /* None of the pbuffer or fbconfig specs say that this comparison needs * to happen at all, but it seems like it should. */ PREFER_LARGER( maxPbufferWidth ); PREFER_LARGER( maxPbufferHeight ); PREFER_LARGER( maxPbufferPixels ); return 0;}/** * Selects and sorts a subset of the supplied configs based on the attributes. * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig, * and \c glXChooseFBConfigSGIX. * * \param configs Array of pointers to possible configs. The elements of * this array that do not meet the criteria will be set to * NULL. The remaining elements will be sorted according to * the various visual / FBConfig selection rules. * \param num_configs Number of elements in the \c configs array. * \param attribList Attributes used select from \c configs. This array is * terminated by a \c None tag. The array can either take * the form expected by \c glXChooseVisual (where boolean * tags do not have a value) or by \c glXChooseFBConfig * (where every tag has a value). * \param fbconfig_style_tags Selects whether \c attribList is in * \c glXChooseVisual style or * \c glXChooseFBConfig style. * \returns The number of valid elements left in \c configs. * * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */static intchoose_visual( __GLcontextModes ** configs, int num_configs, const int *attribList, GLboolean fbconfig_style_tags ){ __GLcontextModes test_config; int base; int i; /* This is a fairly direct implementation of the selection method * described by GLX_SGIX_fbconfig. Start by culling out all the * configs that are not compatible with the selected parameter * list. */ init_fbconfig_for_chooser( & test_config, fbconfig_style_tags ); __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, fbconfig_style_tags ); base = 0; for ( i = 0 ; i < num_configs ; i++ ) { if ( fbconfigs_compatible( & test_config, configs[i] ) ) { configs[ base ] = configs[ i ]; base++; } } if ( base == 0 ) { return 0; } if ( base < num_configs ) { (void) memset( & configs[ base ], 0, sizeof( void * ) * (num_configs - base) ); } /* After the incompatible configs are removed, the resulting * list is sorted according to the rules set out in the various * specifications. */ qsort( configs, base, sizeof( __GLcontextModes * ), (int (*)(const void*, const void*)) fbconfig_compare ); return base;}/*** Return the visual that best matches the template. Return None if no** visual matches the template.*/PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList){ XVisualInfo *visualList = NULL; __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; __GLcontextModes test_config; __GLcontextModes *modes; const __GLcontextModes *best_config = NULL; /* ** Get a list of all visuals, return if list is empty */ if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return None; } /* ** Build a template from the defaults and the attribute list ** Free visual list and return if an unexpected token is encountered */ init_fbconfig_for_chooser( & test_config, GL_FALSE ); __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, GL_FALSE ); /* ** Eliminate visuals that don't meet minimum requirements ** Compute a score for those that do ** Remember which visual, if any, got the highest score */ for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { best_config = modes; } } /* ** If no visual is acceptable, return None ** Otherwise, create an XVisualInfo list with just the selected X visual ** and return this. */ if (best_config != NULL) { XVisualInfo visualTemplate; int i; visualTemplate.screen = screen; visualTemplate.visualid = best_config->visualID; visualList = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask, &visualTemplate, &i ); } return visualList;}PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen ){ __GLXscreenConfigs *psc; __GLXdisplayPrivate *priv; if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return NULL; } if (!psc->effectiveGLXexts) { if (!psc->serverGLXexts) { psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString, screen, GLX_EXTENSIONS); } __glXCalculateUsableExtensions(psc,#ifdef GLX_DIRECT_RENDERING (psc->driScreen != NULL),#else GL_FALSE,#endif priv->minorVersion); } return psc->effectiveGLXexts;}PUBLIC const char *glXGetClientString( Display *dpy, int name ){ switch(name) { case GLX_VENDOR: return (__glXGLXClientVendorName); case GLX_VERSION: return (__glXGLXClientVersion); case GLX_EXTENSIONS: return (__glXGetClientExtensions()); default: return NULL; }}PUBLIC const char *glXQueryServerString( Display *dpy, int screen, int name ){ __GLXscreenConfigs *psc; __GLXdisplayPrivate *priv; const char ** str; if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) { return NULL; } switch(name) { case GLX_VENDOR: str = & priv->serverGLXvendor; break; case GLX_VERSION: str = & priv->serverGLXversion; break; case GLX_EXTENSIONS: str = & psc->serverGLXexts; break; default: return NULL; } if ( *str == NULL ) { *str = __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString, screen, name); } return *str;}void __glXClientInfo ( Display *dpy, int opcode ){ xGLXClientInfoReq *req; int size; char * ext_str = __glXGetClientGLExtensionString(); /* Send the glXClientInfo request */ LockDisplay(dpy); GetReq(GLXClientInfo,req); req->reqType = opcode; req->glxCode = X_GLXClientInfo; req->major = GLX_MAJOR_VERSION; req->minor = GLX_MINOR_VERSION; size = strlen( ext_str ) + 1; req->length += (size + 3) >> 2; req->numbytes = size; Data(dpy, ext_str, size); UnlockDisplay(dpy); SyncHandle(); Xfree( ext_str );}/*** EXT_import_context*/PUBLIC Display *glXGetCurrentDisplay(void){ GLXContext gc = __glXGetCurrentContext(); if (NULL == gc) return NULL; return gc->currentDpy;}PUBLIC GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (), glXGetCurrentDisplay)/** * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests * to the X-server. * * \param dpy Display where \c ctx was created. * \param ctx Context to query. * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid, * or zero if the request failed due to internal problems (i.e., * unable to allocate temporary memory, etc.) * * \note * This function dynamically determines whether to use the EXT_import_context * version of the protocol or the GLX 1.3 version of the protocol. */static int __glXQueryContextInfo(Display *dpy, GLXContext ctx){ __GLXdisplayPrivate *priv = __glXInitialize(dpy); xGLXQueryContextReply reply; CARD8 opcode; GLuint numValues; int retval; if (ctx == NULL) { return GLX_BAD_CONTEXT; } opcode = __glXSetupForCommand(dpy); if (!opcode) { return 0; } /* Send the glXQueryContextInfoEXT request */ LockDisplay(dpy); if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { xGLXQueryContextReq *req; GetReq(GLXQueryContext, req); req->reqType = opcode; req->glxCode = X_GLXQueryContext; req->context = (unsigned int)(ctx->xid); } else { xGLXVendorPrivateReq *vpreq; xGLXQueryContextInfoEXTReq *req; GetReqExtra( GLXVendorPrivate, sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, vpreq ); req = (xGLXQueryContextInfoEXTReq *)vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_QueryContextInfoEXT; req->context = (unsigned int)(ctx->xid); } _XReply(dpy, (xReply*) &reply, 0, False); numValues = reply.n;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -