📄 glxext.c
字号:
/* $XFree86: xc/lib/GL/glx/glxext.c,v 1.22 2003/12/08 17:35:28 dawes Exp $ *//*** License Applicability. Except to the extent portions of this file are** made subject to an alternative license as permitted in the SGI Free** Software License B, Version 1.1 (the "License"), the contents of this** file are subject only to the provisions of the License. You may not use** this file except in compliance with the License. You may obtain a copy** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:** ** http://oss.sgi.com/projects/FreeB** ** Note that, as provided in the License, the Software is distributed on an** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.** ** Original Code. The Original Code is: OpenGL Sample Implementation,** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.** Copyright in any portions created by third parties is as indicated** elsewhere herein. All Rights Reserved.** ** Additional Notice Provisions: The application programming interfaces** established by SGI in conjunction with the Original Code are The** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X** Window System(R) (Version 1.3), released October 19, 1998. This software** was created using the OpenGL(R) version 1.2.1 Sample Implementation** published by SGI, but has not been independently verified as being** compliant with the OpenGL(R) version 1.2.1 Specification.***//** * \file glxext.c * GLX protocol interface boot-strap code. * * Direct rendering support added by Precision Insight, Inc. * * \author Kevin E. Martin <kevin@precisioninsight.com> */ #include "glxclient.h"#include <stdio.h>#include <X11/extensions/Xext.h>#include <X11/extensions/extutil.h>#include <assert.h>#include "indirect_init.h"#include "glapi.h"#include "glxextensions.h"#include "glcontextmodes.h"#include "glheader.h"#ifdef GLX_DIRECT_RENDERING#include <inttypes.h>#include <sys/mman.h>#include "xf86dri.h"#include "sarea.h"#include "dri_glx.h"#endif#ifdef USE_XCB#include <X11/xcl.h>#include <X11/XCB/xcb.h>#include <X11/XCB/glx.h>#endif#include <assert.h>#ifdef DEBUGvoid __glXDumpDrawBuffer(__GLXcontext *ctx);#endif#ifdef USE_SPARC_ASM/* * This is where our dispatch table's bounds are. * And the static mesa_init is taken directly from * Mesa's 'sparc.c' initializer. * * We need something like this here, because this version * of openGL/glx never initializes a Mesa context, and so * the address of the dispatch table pointer never gets stuffed * into the dispatch jump table otherwise. * * It matters only on SPARC, and only if you are using assembler * code instead of C-code indirect dispatch. * * -- FEM, 04.xii.03 */extern unsigned int _mesa_sparc_glapi_begin;extern unsigned int _mesa_sparc_glapi_end;extern void __glapi_sparc_icache_flush(unsigned int *);static void _glx_mesa_init_sparc_glapi_relocs(void);static int _mesa_sparc_needs_init = 1;#define INIT_MESA_SPARC { \ if(_mesa_sparc_needs_init) { \ _glx_mesa_init_sparc_glapi_relocs(); \ _mesa_sparc_needs_init = 0; \ } \}#else#define INIT_MESA_SPARC#endif#ifdef GLX_DIRECT_RENDERINGstatic __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn);#endif /* GLX_DIRECT_RENDERING */static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc);/*** We setup some dummy structures here so that the API can be used** even if no context is current.*/static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];/*** Dummy context used by small commands when there is no current context.** All the** gl and glx entry points are designed to operate as nop's when using** the dummy context structure.*/static __GLXcontext dummyContext = { &dummyBuffer[0], &dummyBuffer[0], &dummyBuffer[0], &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE], sizeof(dummyBuffer),};/*** All indirect rendering contexts will share the same indirect dispatch table.*/static __GLapi *IndirectAPI = NULL;/* * Current context management and locking */#if defined( USE_XTHREADS )/* thread safe */static GLboolean TSDinitialized = GL_FALSE;static xthread_key_t ContextTSD;__GLXcontext *__glXGetCurrentContext(void){ if (!TSDinitialized) { xthread_key_create(&ContextTSD, NULL); TSDinitialized = GL_TRUE; return &dummyContext; } else { void *p; xthread_get_specific(ContextTSD, &p); if (!p) return &dummyContext; else return (__GLXcontext *) p; }}void __glXSetCurrentContext(__GLXcontext *c){ if (!TSDinitialized) { xthread_key_create(&ContextTSD, NULL); TSDinitialized = GL_TRUE; } xthread_set_specific(ContextTSD, c);}/* Used by the __glXLock() and __glXUnlock() macros */xmutex_rec __glXmutex;#elif defined( PTHREADS )pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;# if defined( GLX_USE_TLS )/** * Per-thread GLX context pointer. * * \c __glXSetCurrentContext is written is such a way that this pointer can * \b never be \c NULL. This is important! Because of this * \c __glXGetCurrentContext can be implemented as trivial macro. */__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec"))) = &dummyContext;void __glXSetCurrentContext( __GLXcontext * c ){ __glX_tls_Context = (c != NULL) ? c : &dummyContext;}# elsestatic pthread_once_t once_control = PTHREAD_ONCE_INIT;/** * Per-thread data key. * * Once \c init_thread_data has been called, the per-thread data key will * take a value of \c NULL. As each new thread is created the default * value, in that thread, will be \c NULL. */static pthread_key_t ContextTSD;/** * Initialize the per-thread data key. * * This function is called \b exactly once per-process (not per-thread!) to * initialize the per-thread data key. This is ideally done using the * \c pthread_once mechanism. */static void init_thread_data( void ){ if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) { perror( "pthread_key_create" ); exit( -1 ); }}void __glXSetCurrentContext( __GLXcontext * c ){ pthread_once( & once_control, init_thread_data ); pthread_setspecific( ContextTSD, c );}__GLXcontext * __glXGetCurrentContext( void ){ void * v; pthread_once( & once_control, init_thread_data ); v = pthread_getspecific( ContextTSD ); return (v == NULL) ? & dummyContext : (__GLXcontext *) v;}# endif /* defined( GLX_USE_TLS ) */#elif defined( THREADS )#error Unknown threading method specified.#else/* not thread safe */__GLXcontext *__glXcurrentContext = &dummyContext;#endif/*** You can set this cell to 1 to force the gl drawing stuff to be** one command per packet*/int __glXDebug = 0;/*** forward prototype declarations*/int __glXCloseDisplay(Display *dpy, XExtCodes *codes);/************************************************************************//* Extension required boiler plate */static char *__glXExtensionName = GLX_EXTENSION_NAME;XExtensionInfo *__glXExtensionInfo = NULL;static /* const */ char *error_list[] = { "GLXBadContext", "GLXBadContextState", "GLXBadDrawable", "GLXBadPixmap", "GLXBadContextTag", "GLXBadCurrentWindow", "GLXBadRenderRequest", "GLXBadLargeRequest", "GLXUnsupportedPrivateRequest",};int __glXCloseDisplay(Display *dpy, XExtCodes *codes){ GLXContext gc; gc = __glXGetCurrentContext(); if (dpy == gc->currentDpy) { __glXSetCurrentContext(&dummyContext);#ifdef GLX_DIRECT_RENDERING _glapi_set_dispatch(NULL); /* no-op functions */#endif __glXFreeContext(gc); } return XextRemoveDisplay(__glXExtensionInfo, dpy);}static XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName, __GLX_NUMBER_ERRORS, error_list)static /* const */ XExtensionHooks __glXExtensionHooks = { NULL, /* create_gc */ NULL, /* copy_gc */ NULL, /* flush_gc */ NULL, /* free_gc */ NULL, /* create_font */ NULL, /* free_font */ __glXCloseDisplay, /* close_display */ NULL, /* wire_to_event */ NULL, /* event_to_wire */ NULL, /* error */ __glXErrorString, /* error_string */};staticXEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, __glXExtensionName, &__glXExtensionHooks, __GLX_NUMBER_EVENTS, NULL)/************************************************************************//*** Free the per screen configs data as well as the array of** __glXScreenConfigs.*/static void FreeScreenConfigs(__GLXdisplayPrivate *priv){ __GLXscreenConfigs *psc; GLint i, screens; /* Free screen configuration information */ psc = priv->screenConfigs; screens = ScreenCount(priv->dpy); for (i = 0; i < screens; i++, psc++) { if (psc->configs) { _gl_context_modes_destroy( psc->configs ); if(psc->effectiveGLXexts) Xfree(psc->effectiveGLXexts); psc->configs = NULL; /* NOTE: just for paranoia */ }#ifdef GLX_DIRECT_RENDERING /* Free the direct rendering per screen data */ if (psc->driScreen.private) (*psc->driScreen.destroyScreen)(priv->dpy, i, psc->driScreen.private); psc->driScreen.private = NULL;#endif } XFree((char*) priv->screenConfigs);}/*** Release the private memory referred to in a display private** structure. The caller will free the extension structure.*/static int __glXFreeDisplayPrivate(XExtData *extension){ __GLXdisplayPrivate *priv; priv = (__GLXdisplayPrivate*) extension->private_data; FreeScreenConfigs(priv); if(priv->serverGLXvendor) { Xfree((char*)priv->serverGLXvendor); priv->serverGLXvendor = 0x0; /* to protect against double free's */ } if(priv->serverGLXversion) { Xfree((char*)priv->serverGLXversion); priv->serverGLXversion = 0x0; /* to protect against double free's */ }#if 0 /* GLX_DIRECT_RENDERING */ /* Free the direct rendering per display data */ if (priv->driDisplay.private) (*priv->driDisplay.destroyDisplay)(priv->dpy, priv->driDisplay.private); priv->driDisplay.private = NULL;#endif Xfree((char*) priv); return 0;}/************************************************************************//*** Query the version of the GLX extension. This procedure works even if** the client extension is not completely set up.*/static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor){ xGLXQueryVersionReq *req; xGLXQueryVersionReply reply; /* Send the glXQueryVersion request */ LockDisplay(dpy); GetReq(GLXQueryVersion,req); req->reqType = opcode; req->glxCode = X_GLXQueryVersion; req->majorVersion = GLX_MAJOR_VERSION; req->minorVersion = GLX_MINOR_VERSION; _XReply(dpy, (xReply*) &reply, 0, False); UnlockDisplay(dpy); SyncHandle(); if (reply.majorVersion != GLX_MAJOR_VERSION) { /* ** The server does not support the same major release as this ** client. */ return GL_FALSE; } *major = reply.majorVersion; *minor = min(reply.minorVersion, GLX_MINOR_VERSION); return GL_TRUE;}void __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags ){ int i; if (!tagged_only) { /* Copy in the first set of properties */ config->visualID = *bp++; config->visualType = _gl_convert_from_x_visual_type( *bp++ ); config->rgbMode = *bp++; config->redBits = *bp++; config->greenBits = *bp++; config->blueBits = *bp++; config->alphaBits = *bp++; config->accumRedBits = *bp++; config->accumGreenBits = *bp++; config->accumBlueBits = *bp++; config->accumAlphaBits = *bp++; config->doubleBufferMode = *bp++; config->stereoMode = *bp++; config->rgbBits = *bp++; config->depthBits = *bp++; config->stencilBits = *bp++; config->numAuxBuffers = *bp++; config->level = *bp++; count -= __GLX_MIN_CONFIG_PROPS; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -