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

📄 glxext.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
 out:    UnlockDisplay(dpy);    return psc->visuals != NULL;}static GLbooleangetFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen){    xGLXGetFBConfigsReq *fb_req;    xGLXGetFBConfigsSGIXReq *sgi_req;    xGLXVendorPrivateWithReplyReq *vpreq;    xGLXGetFBConfigsReply reply;    __GLXscreenConfigs *psc;    psc = priv->screenConfigs + screen;    psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,						  X_GLXQueryServerString,						  screen, GLX_EXTENSIONS);    LockDisplay(dpy);    psc->configs = NULL;    if (atof(priv->serverGLXversion) >= 1.3) {	GetReq(GLXGetFBConfigs, fb_req);	fb_req->reqType = priv->majorOpcode;	fb_req->glxCode = X_GLXGetFBConfigs;	fb_req->screen = screen;    } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {	GetReqExtra(GLXVendorPrivateWithReply,		    sz_xGLXGetFBConfigsSGIXReq +		    sz_xGLXVendorPrivateWithReplyReq, vpreq);	sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;	sgi_req->reqType = priv->majorOpcode;	sgi_req->glxCode = X_GLXVendorPrivateWithReply;	sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;	sgi_req->screen = screen;    } else	goto out;    if (!_XReply(dpy, (xReply*) &reply, 0, False))	goto out;    psc->configs = createConfigsFromProperties(dpy,					       reply.numFBConfigs,					       reply.numAttribs * 2,					       screen, GL_TRUE); out:    UnlockDisplay(dpy);    return psc->configs != NULL;}/*** Allocate the memory for the per screen configs for each screen.** If that works then fetch the per screen configs data.*/static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv){    __GLXscreenConfigs *psc;    GLint i, screens;    /*    ** First allocate memory for the array of per screen configs.    */    screens = ScreenCount(dpy);    psc = (__GLXscreenConfigs*) Xmalloc(screens * sizeof(__GLXscreenConfigs));    if (!psc) {	return GL_FALSE;    }    memset(psc, 0, screens * sizeof(__GLXscreenConfigs));    priv->screenConfigs = psc;        priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,						      X_GLXQueryServerString,						      0, GLX_VERSION);    if ( priv->serverGLXversion == NULL ) {	FreeScreenConfigs(priv);	return GL_FALSE;    }    for (i = 0; i < screens; i++, psc++) {	getVisualConfigs(dpy, priv, i);	getFBConfigs(dpy, priv, i);#ifdef GLX_DIRECT_RENDERING	psc->scr = i;	psc->dpy = dpy;	psc->drawHash = __glxHashCreate();	if (psc->drawHash == NULL)	    continue;	if (psc->driScreen == NULL && priv->driDisplay)	    psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv);	if (psc->driScreen == NULL && priv->driswDisplay)	    psc->driScreen = (*priv->driswDisplay->createScreen)(psc, i, priv);	if (psc->driScreen == NULL) {	    __glxHashDestroy(psc->drawHash);	    psc->drawHash = NULL;	}#endif    }    SyncHandle();    return GL_TRUE;}/*** Initialize the client side extension code.*/_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy){    XExtDisplayInfo *info = __glXFindDisplay(dpy);    XExtData **privList, *private, *found;    __GLXdisplayPrivate *dpyPriv;    XEDataObject dataObj;    int major, minor;#ifdef GLX_DIRECT_RENDERING    Bool glx_direct, glx_accel;#endif#if defined(USE_XTHREADS)    {        static int firstCall = 1;        if (firstCall) {            /* initialize the GLX mutexes */            xmutex_init(&__glXmutex);            firstCall = 0;        }    }#endif    INIT_MESA_SPARC    /* The one and only long long lock */    __glXLock();    if (!XextHasExtension(info)) {	/* No GLX extension supported by this server. Oh well. */	__glXUnlock();	XMissingExtension(dpy, __glXExtensionName);	return 0;    }    /* See if a display private already exists.  If so, return it */    dataObj.display = dpy;    privList = XEHeadOfExtensionList(dataObj);    found = XFindOnExtensionList(privList, info->codes->extension);    if (found) {	__glXUnlock();	return (__GLXdisplayPrivate *) found->private_data;    }    /* See if the versions are compatible */    if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) {	/* The client and server do not agree on versions.  Punt. */	__glXUnlock();	return 0;    }    /*    ** Allocate memory for all the pieces needed for this buffer.    */    private = (XExtData *) Xmalloc(sizeof(XExtData));    if (!private) {	__glXUnlock();	return 0;    }    dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));    if (!dpyPriv) {	__glXUnlock();	Xfree((char*) private);	return 0;    }    /*    ** Init the display private and then read in the screen config    ** structures from the server.    */    dpyPriv->majorOpcode = info->codes->major_opcode;    dpyPriv->majorVersion = major;    dpyPriv->minorVersion = minor;    dpyPriv->dpy = dpy;    dpyPriv->serverGLXvendor = 0x0;     dpyPriv->serverGLXversion = 0x0;#ifdef GLX_DIRECT_RENDERING    glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);    glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);    /*    ** Initialize the direct rendering per display data and functions.    ** Note: This _must_ be done before calling any other DRI routines    ** (e.g., those called in AllocAndFetchScreenConfigs).    */    if (glx_direct && glx_accel) {	dpyPriv->driDisplay = driCreateDisplay(dpy);    }    if (glx_direct)	dpyPriv->driswDisplay = driswCreateDisplay(dpy);#endif    if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {	__glXUnlock();	Xfree((char*) dpyPriv);	Xfree((char*) private);	return 0;    }    /*    ** Fill in the private structure.  This is the actual structure that    ** hangs off of the Display structure.  Our private structure is    ** referred to by this structure.  Got that?    */    private->number = info->codes->extension;    private->next = 0;    private->free_private = __glXFreeDisplayPrivate;    private->private_data = (char *) dpyPriv;    XAddToExtensionList(privList, private);    if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) {        __glXClientInfo(dpy, dpyPriv->majorOpcode);    }    __glXUnlock();    return dpyPriv;}/*** Setup for sending a GLX command on dpy.  Make sure the extension is** initialized.  Try to avoid calling __glXInitialize as its kinda slow.*/_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy){    GLXContext gc;    __GLXdisplayPrivate *priv;    /* If this thread has a current context, flush its rendering commands */    gc = __glXGetCurrentContext();    if (gc->currentDpy) {	/* Flush rendering buffer of the current context, if any */	(void) __glXFlushRenderBuffer(gc, gc->pc);	if (gc->currentDpy == dpy) {	    /* Use opcode from gc because its right */	    INIT_MESA_SPARC	    return gc->majorOpcode;	} else {	    /*	    ** Have to get info about argument dpy because it might be to	    ** a different server	    */	}    }    /* Forced to lookup extension via the slow initialize route */    priv = __glXInitialize(dpy);    if (!priv) {	return 0;    }    return priv->majorOpcode;}/** * Flush the drawing command transport buffer. *  * \param ctx  Context whose transport buffer is to be flushed. * \param pc   Pointer to first unused buffer location. *  * \todo * Modify this function to use \c ctx->pc instead of the explicit * \c pc parameter. */_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc){    Display * const dpy = ctx->currentDpy;#ifdef USE_XCB    xcb_connection_t *c = XGetXCBConnection(dpy);#else    xGLXRenderReq *req;#endif /* USE_XCB */    const GLint size = pc - ctx->buf;    if ( (dpy != NULL) && (size > 0) ) {#ifdef USE_XCB	xcb_glx_render(c, ctx->currentContextTag, size,		       (const uint8_t *)ctx->buf);#else	/* Send the entire buffer as an X request */	LockDisplay(dpy);	GetReq(GLXRender,req); 	req->reqType = ctx->majorOpcode;	req->glxCode = X_GLXRender; 	req->contextTag = ctx->currentContextTag;	req->length += (size + 3) >> 2;	_XSend(dpy, (char *)ctx->buf, size);	UnlockDisplay(dpy);	SyncHandle();#endif    }    /* Reset pointer and return it */    ctx->pc = ctx->buf;    return ctx->pc;}/** * Send a portion of a GLXRenderLarge command to the server.  The advantage of * this function over \c __glXSendLargeCommand is that callers can use the * data buffer in the GLX context and may be able to avoid allocating an * extra buffer.  The disadvantage is the clients will have to do more * GLX protocol work (i.e., calculating \c totalRequests, etc.). * * \sa __glXSendLargeCommand * * \param gc             GLX context * \param requestNumber  Which part of the whole command is this?  The first *                       request is 1. * \param totalRequests  How many requests will there be? * \param data           Command data. * \param dataLen        Size, in bytes, of the command data. */_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, 				   GLint totalRequests,				   const GLvoid * data, GLint dataLen){    Display *dpy = gc->currentDpy;#ifdef USE_XCB    xcb_connection_t *c = XGetXCBConnection(dpy);    xcb_glx_render_large(c, gc->currentContextTag, requestNumber, totalRequests, dataLen, data);#else    xGLXRenderLargeReq *req;        if ( requestNumber == 1 ) {	LockDisplay(dpy);    }    GetReq(GLXRenderLarge,req);     req->reqType = gc->majorOpcode;    req->glxCode = X_GLXRenderLarge;     req->contextTag = gc->currentContextTag;    req->length += (dataLen + 3) >> 2;    req->requestNumber = requestNumber;    req->requestTotal = totalRequests;    req->dataBytes = dataLen;    Data(dpy, data, dataLen);    if ( requestNumber == totalRequests ) {	UnlockDisplay(dpy);	SyncHandle();    }#endif /* USE_XCB */}/** * Send a command that is too large for the GLXRender protocol request. *  * Send a large command, one that is too large for some reason to * send using the GLXRender protocol request.  One reason to send * a large command is to avoid copying the data. *  * \param ctx        GLX context * \param header     Header data. * \param headerLen  Size, in bytes, of the header data.  It is assumed that *                   the header data will always be small enough to fit in *                   a single X protocol packet. * \param data       Command data. * \param dataLen    Size, in bytes, of the command data. */_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx,				     const GLvoid *header, GLint headerLen,				     const GLvoid *data, GLint dataLen){    GLint maxSize;    GLint totalRequests, requestNumber;    /*    ** Calculate the maximum amount of data can be stuffed into a single    ** packet.  sz_xGLXRenderReq is added because bufSize is the maximum    ** packet size minus sz_xGLXRenderReq.    */    maxSize = (ctx->bufSize + sz_xGLXRenderReq) - sz_xGLXRenderLargeReq;    totalRequests = 1 + (dataLen / maxSize);    if (dataLen % maxSize) totalRequests++;    /*    ** Send all of the command, except the large array, as one request.    */    assert( headerLen <= maxSize );    __glXSendLargeChunk(ctx, 1, totalRequests, header, headerLen);    /*    ** Send enough requests until the whole array is sent.    */    for ( requestNumber = 2 ; requestNumber <= (totalRequests - 1) ; requestNumber++ ) {	__glXSendLargeChunk(ctx, requestNumber, totalRequests, data, maxSize);	data = (const GLvoid *) (((const GLubyte *) data) + maxSize);	dataLen -= maxSize;	assert( dataLen > 0 );    }    assert( dataLen <= maxSize );    __glXSendLargeChunk(ctx, requestNumber, totalRequests, data, dataLen);}/************************************************************************/#ifdef DEBUG_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx){    GLubyte *p = ctx->buf;    GLubyte *end = ctx->pc;    GLushort opcode, length;    while (p < end) {	/* Fetch opcode */	opcode = *((GLushort*) p);	length = *((GLushort*) (p + 2));	printf("%2x: %5d: ", opcode, length);	length -= 4;	p += 4;	while (length > 0) {	    printf("%08x ", *((unsigned *) p));	    p += 4;	    length -= 4;	}	printf("\n");    }	    }#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){	unsigned int *insn_ptr, *end_ptr;	unsigned long disp_addr;	insn_ptr = &_mesa_sparc_glapi_begin;	end_ptr = &_mesa_sparc_glapi_end;	disp_addr = (unsigned long) &_glapi_Dispatch;	/*         * Verbatim from Mesa sparc.c.  It's needed because there doesn't         * seem to be a better way to do this:         *         * UNCONDITIONAL_JUMP ( (*_glapi_Dispatch) + entry_offset )         *         * This code is patching in the ADDRESS of the pointer to the         * dispatch table.  Hence, it must be called exactly once, because         * that address is not going to change.         *         * What it points to can change, but Mesa (and hence, we) assume         * that there is only one pointer.         *	 */	while (insn_ptr < end_ptr) {#if ( defined(__sparc_v9__) && ( !defined(__linux__) || defined(__linux_64__) ) )	/*	This code patches for 64-bit addresses.  This had better	not happen for Sparc/Linux, no matter what architecture we	are building for.  So, don't do this.        The 'defined(__linux_64__)' is used here as a placeholder for        when we do do 64-bit usermode on sparc linux.	*/		insn_ptr[0] |= (disp_addr >> (32 + 10));		insn_ptr[1] |= ((disp_addr & 0xffffffff) >> 10);		__glapi_sparc_icache_flush(&insn_ptr[0]);		insn_ptr[2] |= ((disp_addr >> 32) & ((1 << 10) - 1));		insn_ptr[3] |= (disp_addr & ((1 << 10) - 1));		__glapi_sparc_icache_flush(&insn_ptr[2]);		insn_ptr += 11;#else		insn_ptr[0] |= (disp_addr >> 10);		insn_ptr[1] |= (disp_addr & ((1 << 10) - 1));		__glapi_sparc_icache_flush(&insn_ptr[0]);		insn_ptr += 5;#endif	}}#endif  /* sparc ASM in use */

⌨️ 快捷键说明

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