⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glxcmds.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. *//** * \file glxcmds.c * Client-side GLX interface. */#include "glxclient.h"#include "glapi.h"#include "glxextensions.h"#include "glcontextmodes.h"#include "glheader.h"#ifdef GLX_DIRECT_RENDERING#include <sys/time.h>#include <X11/extensions/xf86vmode.h>#include "xf86dri.h"#endifstatic const char __glXGLXClientVendorName[] = "SGI";static const char __glXGLXClientVersion[] = "1.4";/****************************************************************************/#ifdef GLX_DIRECT_RENDERINGstatic Bool windowExistsFlag;static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr){    if (xerr->error_code == BadWindow) {	windowExistsFlag = GL_FALSE;    }    return 0;}/** * Find drawables in the local hash that have been destroyed on the * server. *  * \param dpy    Display to destroy drawables for * \param screen Screen number to destroy drawables for */static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc){    XID draw;    __GLXDRIdrawable *pdraw;    XWindowAttributes xwa;    int (*oldXErrorHandler)(Display *, XErrorEvent *);    /* Set no-op error handler so Xlib doesn't bail out if the windows     * has alreay been destroyed on the server. */    XSync(dpy, GL_FALSE);    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);    if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {	do {	    windowExistsFlag = GL_TRUE;	    XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */	    if (!windowExistsFlag) {		/* Destroy the local drawable data, if the drawable no		   longer exists in the Xserver */		(*pdraw->destroyDrawable)(pdraw);                __glxHashDelete(sc->drawHash, draw);	    }	} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);    }    XSync(dpy, GL_FALSE);    XSetErrorHandler(oldXErrorHandler);}extern __GLXDRIdrawable *GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);/** * 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. * \param scrn_num  If non-NULL, the drawables screen is stored there * \returns  A pointer to the context's __DRIdrawable on success, or NULL if *           the drawable is not associated with a direct-rendering context. */_X_HIDDEN __GLXDRIdrawable *GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num){    __GLXdisplayPrivate *priv = __glXInitialize(dpy);    __GLXDRIdrawable *pdraw;    const unsigned  screen_count = ScreenCount(dpy);    unsigned   i;    __GLXscreenConfigs *psc;    if (priv == NULL)	return NULL;        for (i = 0; i < screen_count; i++) {	psc = &priv->screenConfigs[i];	if (psc->drawHash == NULL)	    continue;	if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {	    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->pc = gc->buf;    gc->bufEnd = gc->buf + bufSize;    gc->isDirect = GL_FALSE;    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;#ifdef GLX_DIRECT_RENDERING    int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);#endif    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 && psc->driScreen) {	    const __GLcontextModes * mode;	    if (fbconfig == NULL) {		mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);		if (mode == NULL) {		   xError error;		   error.errorCode = BadValue;		   error.resourceID = vis->visualid;		   error.sequenceNumber = dpy->request;		   error.type = X_Error;		   error.majorCode = gc->majorOpcode;		   error.minorCode = X_GLXCreateContext;		   _XError(dpy, &error);		   return None;		}	    }	    else {		mode = fbconfig;	    }	    gc->driContext = psc->driScreen->createContext(psc, mode, gc,							   shareList,							   renderType);	    if (gc->driContext != NULL) {		gc->screen = mode->screen;		gc->psc = psc;		gc->mode = mode;		gc->isDirect = GL_TRUE;	    }	}#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;#ifdef GLX_DIRECT_RENDERING	    req->isDirect = gc->driContext != NULL;#else	    req->isDirect = 0;#endif	}	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;#ifdef GLX_DIRECT_RENDERING	    req->isDirect = gc->driContext != NULL;#else	    req->isDirect = 0;#endif	}	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;#ifdef GLX_DIRECT_RENDERING	    req->isDirect = gc->driContext != NULL;#else	    req->isDirect = 0;#endif	}	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);}_X_HIDDEN 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -