glxcmds.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 2,495 行 · 第 1/5 页
C
2,495 行
/* $XFree86: xc/lib/GL/glx/glxcmds.c,v 1.30 2004/01/30 20:33:06 alanh 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 glxcmds.c * Client-side GLX interface. */#include <inttypes.h>#include "glxclient.h"#include <X11/extensions/extutil.h>#include <X11/extensions/Xext.h>#include <assert.h>#include <string.h>#include "glapi.h"#ifdef GLX_DIRECT_RENDERING#include "indirect_init.h"#include <X11/extensions/xf86vmode.h>#include "xf86dri.h"#endif#include "glxextensions.h"#include "glcontextmodes.h"#include "glheader.h"#include <sys/time.h>static const char __glXGLXClientVendorName[] = "SGI";static const char __glXGLXClientVersion[] = "1.4";/****************************************************************************//** * Get the __DRIdrawable for the drawable associated with a GLXContext * * \param dpy The display associated with \c drawable. * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved. * \returns A pointer to the context's __DRIdrawable on success, or NULL if * the drawable is not associated with a direct-rendering context. */#ifdef GLX_DIRECT_RENDERINGstatic __DRIdrawable *GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ){ __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) { const unsigned screen_count = ScreenCount(dpy); unsigned i; for ( i = 0 ; i < screen_count ; i++ ) { __DRIscreen * const psc = &priv->screenConfigs[i].driScreen; __DRIdrawable * const pdraw = (psc->private != NULL) ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL; if ( pdraw != NULL ) { if ( scrn_num != NULL ) { *scrn_num = i; } return pdraw; } } } return NULL;}#endif/** * Get the GLX per-screen data structure associated with a GLX context. * * \param dpy Display for which the GLX per-screen information is to be * retrieved. * \param scrn Screen on \c dpy for which the GLX per-screen information is * to be retrieved. * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn * specify a valid GLX screen, or NULL otherwise. * * \todo Should this function validate that \c scrn is within the screen * number range for \c dpy? */static __GLXscreenConfigs *GetGLXScreenConfigs(Display *dpy, int scrn){ __GLXdisplayPrivate * const priv = __glXInitialize(dpy); return (priv->screenConfigs != NULL) ? &priv->screenConfigs[scrn] : NULL;}static intGetGLXPrivScreenConfig( Display *dpy, int scrn, __GLXdisplayPrivate ** ppriv, __GLXscreenConfigs ** ppsc ){ /* Initialize the extension, if needed . This has the added value * of initializing/allocating the display private */ if ( dpy == NULL ) { return GLX_NO_EXTENSION; } *ppriv = __glXInitialize(dpy); if ( *ppriv == NULL ) { return GLX_NO_EXTENSION; } /* Check screen number to see if its valid */ if ((scrn < 0) || (scrn >= ScreenCount(dpy))) { return GLX_BAD_SCREEN; } /* Check to see if the GL is supported on this screen */ *ppsc = &((*ppriv)->screenConfigs[scrn]); if ( (*ppsc)->configs == NULL ) { /* No support for GL on this screen regardless of visual */ return GLX_BAD_VISUAL; } return Success;}/** * Determine if a \c GLXFBConfig supplied by the application is valid. * * \param dpy Application supplied \c Display pointer. * \param config Application supplied \c GLXFBConfig. * * \returns If the \c GLXFBConfig is valid, the a pointer to the matching * \c __GLcontextModes structure is returned. Otherwise, \c NULL * is returned. */static __GLcontextModes *ValidateGLXFBConfig( Display * dpy, GLXFBConfig config ){ __GLXdisplayPrivate * const priv = __glXInitialize(dpy); const unsigned num_screens = ScreenCount(dpy); unsigned i; const __GLcontextModes * modes; if ( priv != NULL ) { for ( i = 0 ; i < num_screens ; i++ ) { for ( modes = priv->screenConfigs[i].configs ; modes != NULL ; modes = modes->next ) { if ( modes == (__GLcontextModes *) config ) { return (__GLcontextModes *) config; } } } } return NULL;}/** * \todo It should be possible to move the allocate of \c client_state_private * later in the function for direct-rendering contexts. Direct-rendering * contexts don't need to track client state, so they don't need that memory * at all. * * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new * function called \c __glXAllocateClientState that allocates the memory and * does all the initialization (including the pixel pack / unpack). */staticGLXContext AllocateGLXContext( Display *dpy ){ GLXContext gc; int bufSize; CARD8 opcode; __GLXattribute *state; if (!dpy) return NULL; opcode = __glXSetupForCommand(dpy); if (!opcode) { return NULL; } /* Allocate our context record */ gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec)); if (!gc) { /* Out of memory */ return NULL; } memset(gc, 0, sizeof(struct __GLXcontextRec)); state = Xmalloc(sizeof(struct __GLXattributeRec)); if (state == NULL) { /* Out of memory */ Xfree(gc); return NULL; } gc->client_state_private = state; memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec)); state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL); /* ** Create a temporary buffer to hold GLX rendering commands. The size ** of the buffer is selected so that the maximum number of GLX rendering ** commands can fit in a single X packet and still have room in the X ** packet for the GLXRenderReq header. */ bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq; gc->buf = (GLubyte *) Xmalloc(bufSize); if (!gc->buf) { Xfree(gc->client_state_private); Xfree(gc); return NULL; } gc->bufSize = bufSize; /* Fill in the new context */ gc->renderMode = GL_RENDER; state->storePack.alignment = 4; state->storeUnpack.alignment = 4; gc->attributes.stackPointer = &gc->attributes.stack[0]; /* ** PERFORMANCE NOTE: A mode dependent fill image can speed things up. ** Other code uses the fastImageUnpack bit, but it is never set ** to GL_TRUE. */ gc->fastImageUnpack = GL_FALSE; gc->fillImage = __glFillImage; gc->isDirect = GL_FALSE; gc->pc = gc->buf; gc->bufEnd = gc->buf + bufSize; if (__glXDebug) { /* ** Set limit register so that there will be one command per packet */ gc->limit = gc->buf; } else { gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; } gc->createDpy = dpy; gc->majorOpcode = opcode; /* ** Constrain the maximum drawing command size allowed to be ** transfered using the X_GLXRender protocol request. First ** constrain by a software limit, then constrain by the protocl ** limit. */ if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) { bufSize = __GLX_RENDER_CMD_SIZE_LIMIT; } if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) { bufSize = __GLX_MAX_RENDER_CMD_SIZE; } gc->maxSmallRenderCommandSize = bufSize; return gc;}/** * Create a new context. Exactly one of \c vis and \c fbconfig should be * non-NULL. * * \param use_glx_1_3 For FBConfigs, should GLX 1.3 protocol or * SGIX_fbconfig protocol be used? * \param renderType For FBConfigs, what is the rendering type? */static GLXContextCreateContext(Display *dpy, XVisualInfo *vis, const __GLcontextModes * const fbconfig, GLXContext shareList, Bool allowDirect, GLXContextID contextID, Bool use_glx_1_3, int renderType){ GLXContext gc; if ( dpy == NULL ) return NULL; gc = AllocateGLXContext(dpy); if (!gc) return NULL; if (None == contextID) { if ( (vis == NULL) && (fbconfig == NULL) ) return NULL;#ifdef GLX_DIRECT_RENDERING if (allowDirect) { int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); const __GLcontextModes * mode; /* The value of fbconfig cannot change because it is tested * later in the function. */ if ( fbconfig == NULL ) { /* FIXME: Is it possible for the __GLcontextModes structure * FIXME: to not be found? */ mode = _gl_context_modes_find_visual( psc->configs, vis->visualid ); assert( mode != NULL ); assert( mode->screen == screen ); } else { mode = fbconfig; } if (psc && psc->driScreen.private) { void * const shared = (shareList != NULL) ? shareList->driContext.private : NULL; gc->driContext.private = (*psc->driScreen.createNewContext)( dpy, mode, renderType, shared, &gc->driContext ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; gc->screen = mode->screen; gc->vid = mode->visualID; gc->fbconfigID = mode->fbconfigID; gc->driContext.mode = mode; } } }#endif LockDisplay(dpy); if ( fbconfig == NULL ) { xGLXCreateContextReq *req; /* Send the glXCreateContext request */ GetReq(GLXCreateContext,req); req->reqType = gc->majorOpcode; req->glxCode = X_GLXCreateContext; req->context = gc->xid = XAllocID(dpy); req->visual = vis->visualid; req->screen = vis->screen; req->shareList = shareList ? shareList->xid : None; req->isDirect = gc->isDirect; } else if ( use_glx_1_3 ) { xGLXCreateNewContextReq *req; /* Send the glXCreateNewContext request */ GetReq(GLXCreateNewContext,req); req->reqType = gc->majorOpcode; req->glxCode = X_GLXCreateNewContext; req->context = gc->xid = XAllocID(dpy); req->fbconfig = fbconfig->fbconfigID; req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; req->isDirect = gc->isDirect; } else { xGLXVendorPrivateWithReplyReq *vpreq; xGLXCreateContextWithConfigSGIXReq *req; /* Send the glXCreateNewContext request */ GetReqExtra(GLXVendorPrivateWithReply, sz_xGLXCreateContextWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; req->reqType = gc->majorOpcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; req->context = gc->xid = XAllocID(dpy); req->fbconfig = fbconfig->fbconfigID; req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; req->isDirect = gc->isDirect; } UnlockDisplay(dpy); SyncHandle(); gc->imported = GL_FALSE; } else { gc->xid = contextID; gc->imported = GL_TRUE; } return gc;}PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool allowDirect){ return CreateContext(dpy, vis, NULL, shareList, allowDirect, None, False, 0);}void __glXFreeContext(__GLXcontext *gc){ if (gc->vendor) XFree((char *) gc->vendor); if (gc->renderer) XFree((char *) gc->renderer); if (gc->version) XFree((char *) gc->version); if (gc->extensions) XFree((char *) gc->extensions); __glFreeAttributeState(gc); XFree((char *) gc->buf); Xfree((char *) gc->client_state_private); XFree((char *) gc); }/*** Destroy the named context*/static void DestroyContext(Display *dpy, GLXContext gc){ xGLXDestroyContextReq *req; GLXContextID xid; CARD8 opcode; GLboolean imported; opcode = __glXSetupForCommand(dpy); if (!opcode || !gc) { return; } __glXLock(); xid = gc->xid; imported = gc->imported; gc->xid = None;#ifdef GLX_DIRECT_RENDERING /* Destroy the direct rendering context */ if (gc->isDirect) { if (gc->driContext.private) { (*gc->driContext.destroyContext)(dpy, gc->screen, gc->driContext.private); gc->driContext.private = NULL; } }#endif if (gc->currentDpy) { /* Have to free later cuz it's in use now */ __glXUnlock(); } else { /* Destroy the handle if not current to anybody */ __glXUnlock(); __glXFreeContext(gc); } if (!imported) { /* ** This dpy also created the server side part of the context. ** Send the glXDestroyContext request. */ LockDisplay(dpy); GetReq(GLXDestroyContext,req); req->reqType = opcode; req->glxCode = X_GLXDestroyContext; req->context = xid; UnlockDisplay(dpy); SyncHandle();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?