📄 glxext.c
字号:
if (cx == &dummyContext) { return NULL; } else { return cx; }}GLXDrawable glXGetCurrentDrawable(void){ GLXContext gc = __glXGetCurrentContext(); return gc->currentDrawable;}/************************************************************************/#ifdef GLX_DIRECT_RENDERING/* Return the DRI per screen structure */__DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn){ __DRIscreen *pDRIScreen = NULL; XExtDisplayInfo *info = __glXFindDisplay(dpy); XExtData **privList, *found; __GLXdisplayPrivate *dpyPriv; XEDataObject dataObj; __glXLock(); dataObj.display = dpy; privList = XEHeadOfExtensionList(dataObj); found = XFindOnExtensionList(privList, info->codes->extension); __glXUnlock(); if (found) { dpyPriv = (__GLXdisplayPrivate *)found->private_data; pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen; } return pDRIScreen;}#endif/************************************************************************/static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read, xGLXMakeCurrentReply * reply );/** * Sends a GLX protocol message to the specified display to make the context * and the drawables current. * * \param dpy Display to send the message to. * \param opcode Major opcode value for the display. * \param gc_id Context tag for the context to be made current. * \param draw Drawable ID for the "draw" drawable. * \param read Drawable ID for the "read" drawable. * \param reply Space to store the X-server's reply. * * \warning * This function assumes that \c dpy is locked with \c LockDisplay on entry. */static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, GLXContextID gc_id, GLXContextTag gc_tag, GLXDrawable draw, GLXDrawable read, xGLXMakeCurrentReply * reply ){ if ( draw == read ) { xGLXMakeCurrentReq *req; GetReq(GLXMakeCurrent,req); req->reqType = opcode; req->glxCode = X_GLXMakeCurrent; req->drawable = draw; req->context = gc_id; req->oldContextTag = gc_tag; } else { __GLXdisplayPrivate *priv = __glXInitialize(dpy); /* If the server can support the GLX 1.3 version, we should * perfer that. Not only that, some servers support GLX 1.3 but * not the SGI extension. */ if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { xGLXMakeContextCurrentReq *req; GetReq(GLXMakeContextCurrent,req); req->reqType = opcode; req->glxCode = X_GLXMakeContextCurrent; req->drawable = draw; req->readdrawable = read; req->context = gc_id; req->oldContextTag = gc_tag; } else { xGLXVendorPrivateWithReplyReq *vpreq; xGLXMakeCurrentReadSGIReq *req; GetReqExtra(GLXVendorPrivateWithReply, sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); req = (xGLXMakeCurrentReadSGIReq *)vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_MakeCurrentReadSGI; req->drawable = draw; req->readable = read; req->context = gc_id; req->oldContextTag = gc_tag; } } return _XReply(dpy, (xReply*) reply, 0, False);}#ifdef GLX_DIRECT_RENDERINGstatic Bool BindContextWrapper( Display *dpy, GLXContext gc, GLXDrawable draw, GLXDrawable read ){ return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read, & gc->driContext);}static Bool UnbindContextWrapper( GLXContext gc ){ return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, gc->currentDrawable, gc->currentReadable, & gc->driContext );}#endif /* GLX_DIRECT_RENDERING *//*** Make a particular context current.** NOTE: this is in this file so that it can access dummyContext.*/USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc){ xGLXMakeCurrentReply reply; GLXContext oldGC; CARD8 opcode, oldOpcode; Bool sentRequestToOldDpy = False; Bool bindReturnValue = True; opcode = __glXSetupForCommand(dpy); if (!opcode) { return GL_FALSE; } /* ** Make sure that the new context has a nonzero ID. In the request, ** a zero context ID is used only to mean that we bind to no current ** context. */ if ((gc != NULL) && (gc->xid == None)) { return GL_FALSE; } oldGC = __glXGetCurrentContext(); oldOpcode = (gc == oldGC) ? opcode : __glXSetupForCommand(dpy); if (!oldOpcode) { return GL_FALSE; } if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && !oldGC->isDirect && oldGC != &dummyContext) { /* ** We are either switching from one dpy to another and have to ** send a request to the previous dpy to unbind the previous ** context, or we are switching away from a indirect context to ** a direct context and have to send a request to the dpy to ** unbind the previous context. */ sentRequestToOldDpy = True; LockDisplay(oldGC->currentDpy); if ( ! SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, None, oldGC->currentContextTag, None, None, &reply ) ) { /* The make current failed. Just return GL_FALSE. */ UnlockDisplay(oldGC->currentDpy); SyncHandle(); return GL_FALSE; } oldGC->currentContextTag = 0; } _glapi_check_multithread();#ifdef GLX_DIRECT_RENDERING /* Unbind the old direct rendering context */ if (oldGC->isDirect) { if (oldGC->driContext.private) { if (! UnbindContextWrapper( oldGC )) { /* The make current failed. Just return GL_FALSE. */ return GL_FALSE; } } oldGC->currentContextTag = 0; } /* Bind the direct rendering context to the drawable */ if (gc && gc->isDirect) { if (gc->driContext.private) { bindReturnValue = BindContextWrapper( dpy, gc, draw, read ); } } else {#endif /* Send a glXMakeCurrent request to bind the new context. */ LockDisplay(dpy); bindReturnValue = SendMakeCurrentRequest( dpy, opcode, gc ? gc->xid : None, oldGC->currentContextTag, draw, read, &reply ); UnlockDisplay(dpy);#ifdef GLX_DIRECT_RENDERING }#endif if (!bindReturnValue) { /* The make current failed. */ if (gc && !gc->isDirect) { SyncHandle(); }#ifdef GLX_DIRECT_RENDERING /* If the old context was direct rendering, then re-bind to it. */ if (oldGC->isDirect) { if (oldGC->driContext.private) { if (! BindContextWrapper( oldGC->currentDpy, oldGC, oldGC->currentDrawable, oldGC->currentReadable )) { /* ** The request failed; this cannot happen with the ** current API. If in the future the API is ** extended to allow context sharing between ** clients, then this may fail (because another ** client may have grabbed the context); in that ** case, we cannot undo the previous request, and ** cannot adhere to the "no-op" behavior. */ } } } else#endif /* ** If we had just sent a request to a previous dpy, we have to ** undo that request (because if a command fails, it should act ** like a no-op) by making current to the previous context and ** drawable. */ if (sentRequestToOldDpy) { if ( !SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, oldGC->xid, 0, oldGC->currentDrawable, oldGC->currentReadable, &reply ) ) { UnlockDisplay(oldGC->currentDpy); SyncHandle(); /* ** The request failed; this cannot happen with the ** current API. If in the future the API is extended to ** allow context sharing between clients, then this may ** fail (because another client may have grabbed the ** context); in that case, we cannot undo the previous ** request, and cannot adhere to the "no-op" behavior. */ } else { UnlockDisplay(oldGC->currentDpy); } oldGC->currentContextTag = reply.contextTag; } return GL_FALSE; } /* Update our notion of what is current */ __glXLock(); if (gc == oldGC) { /* ** Even though the contexts are the same the drawable might have ** changed. Note that gc cannot be the dummy, and that oldGC ** cannot be NULL, therefore if they are the same, gc is not ** NULL and not the dummy. */ gc->currentDrawable = draw; gc->currentReadable = read; } else { if (oldGC != &dummyContext) { /* Old current context is no longer current to anybody */ oldGC->currentDpy = 0; oldGC->currentDrawable = None; oldGC->currentReadable = None; oldGC->currentContextTag = 0; if (oldGC->xid == None) { /* ** We are switching away from a context that was ** previously destroyed, so we need to free the memory ** for the old handle. */#ifdef GLX_DIRECT_RENDERING /* Destroy the old direct rendering context */ if (oldGC->isDirect) { if (oldGC->driContext.private) { (*oldGC->driContext.destroyContext) (dpy, oldGC->screen, oldGC->driContext.private); oldGC->driContext.private = NULL; } }#endif __glXFreeContext(oldGC); } } if (gc) { __glXSetCurrentContext(gc);#ifdef GLX_DIRECT_RENDERING if (!gc->isDirect) { if (!IndirectAPI) IndirectAPI = __glXNewIndirectAPI(); _glapi_set_dispatch(IndirectAPI);# ifdef GLX_USE_APPLEGL do { extern void XAppleDRIUseIndirectDispatch(void); XAppleDRIUseIndirectDispatch(); } while (0);# endif }#else /* if not direct rendering, always need indirect dispatch */ if (!IndirectAPI) IndirectAPI = __glXNewIndirectAPI(); _glapi_set_dispatch(IndirectAPI);#endif gc->currentDpy = dpy; gc->currentDrawable = draw; gc->currentReadable = read; if ( ! gc->isDirect ) { __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); gc->currentContextTag = reply.contextTag; if ( state->array_state == NULL ) { (void) glGetString( GL_EXTENSIONS ); (void) glGetString( GL_VERSION ); __glXInitVertexArrayState(gc); } } else { gc->currentContextTag = -1; } } else { __glXSetCurrentContext(&dummyContext);#ifdef GLX_DIRECT_RENDERING _glapi_set_dispatch(NULL); /* no-op functions */#endif } } __glXUnlock(); return GL_TRUE;}PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc){ return MakeContextCurrent( dpy, draw, draw, gc );}PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent)PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent)#ifdef DEBUGvoid __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/* * Used only when we are sparc, using sparc assembler. * */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 + -