_X_HIDDEN void dri2InvalidateBuffers(Display *dpy, XID drawable) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); #if __DRI2_FLUSH_VERSION >= 3 if (pdraw && pdraw->psc->f) pdraw->psc->f->invalidate(pdraw->driDrawable); #endif }
static void DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) { struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); XID xid; if (pdraw != NULL) { xid = pdraw->xDrawable; (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(priv->drawHash, drawable); if (destroy_xdrawable) XFreePixmap(priv->dpy, xid); } }
/** * Destroy a non-pbuffer GLX drawable. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static void DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) { xGLXDestroyPbufferReq *req; CARD8 opcode; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); GetReqExtra(GLXDestroyPbuffer, 4, req); req->reqType = opcode; req->glxCode = glxCode; req->pbuffer = (GLXPbuffer) drawable; UnlockDisplay(dpy); SyncHandle(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) { int screen; __GLXdisplayPrivate *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; if (pdraw != NULL) { (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(psc->drawHash, drawable); } } #endif return; }
/** * Get a drawable's attribute. * * This function is used to implement \c glXGetSelectedEvent and * \c glXGetSelectedEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. * * \todo * This function needs to be modified to work with direct-rendering drivers. */ static int GetDrawableAttribute(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { __GLXdisplayPrivate *priv; xGLXGetDrawableAttributesReply reply; CARD32 *data; CARD8 opcode; unsigned int length; unsigned int i; unsigned int num_attributes; GLboolean use_glx_1_3; if ((dpy == NULL) || (drawable == 0)) { return 0; } priv = __glXInitialize(dpy); use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); *value = 0; opcode = __glXSetupForCommand(dpy); if (!opcode) return 0; LockDisplay(dpy); if (use_glx_1_3) { xGLXGetDrawableAttributesReq *req; GetReqExtra(GLXGetDrawableAttributes, 4, req); req->reqType = opcode; req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; } _XReply(dpy, (xReply *) & reply, 0, False); if (reply.type == X_Error) { UnlockDisplay(dpy); SyncHandle(); return 0; } length = reply.length; if (length) { num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; data = (CARD32 *) Xmalloc(length * sizeof(CARD32)); if (data == NULL) { /* Throw data on the floor */ _XEatData(dpy, length); } else { _XRead(dpy, (char *) data, length * sizeof(CARD32)); /* Search the set of returned attributes for the attribute requested by * the caller. */ for (i = 0; i < num_attributes; i++) { if (data[i * 2] == attribute) { *value = data[(i * 2) + 1]; break; } } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); if (pdraw != NULL && !pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); if (pdraw != NULL && !pdraw->textureFormat) pdraw->textureFormat = determineTextureFormat((const int *) data, num_attributes); } #endif Xfree(data); } } UnlockDisplay(dpy); SyncHandle(); return 0; }
/** * Change a drawable's attribute. * * This function is used to implement \c glXSelectEvent and * \c glXSelectEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. */ static void ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { struct glx_display *priv = __glXInitialize(dpy); #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; #endif CARD32 *output; CARD8 opcode; int i; if ((dpy == NULL) || (drawable == 0)) { return; } opcode = __glXSetupForCommand(dpy); if (!opcode) return; LockDisplay(dpy); if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXChangeDrawableAttributesReq *req; GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req); output = (CARD32 *) (req + 1); req->reqType = opcode; req->glxCode = X_GLXChangeDrawableAttributes; req->drawable = drawable; req->numAttribs = (CARD32) num_attribs; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq); output = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX; output[0] = (CARD32) drawable; output[1] = num_attribs; output += 2; } (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs); UnlockDisplay(dpy); SyncHandle(); #ifdef GLX_DIRECT_RENDERING pdraw = GetGLXDRIDrawable(dpy, drawable); if (!pdraw) return; for (i = 0; i < num_attribs; i++) { switch(attribs[i * 2]) { case GLX_EVENT_MASK: /* Keep a local copy for masking out DRI2 proto events as needed */ pdraw->eventMask = attribs[i * 2 + 1]; break; } } #endif return; }
/** * Get a drawable's attribute. * * This function is used to implement \c glXGetSelectedEvent and * \c glXGetSelectedEventSGIX. * * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. * * \todo * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. */ static int GetDrawableAttribute(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { struct glx_display *priv; xGLXGetDrawableAttributesReply reply; CARD32 *data; CARD8 opcode; unsigned int length; unsigned int i; unsigned int num_attributes; GLboolean use_glx_1_3; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) __GLXDRIdrawable *pdraw; #endif if (dpy == NULL) return 0; /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says: * * "If drawable is not a valid GLX drawable, a GLXBadDrawable error is * generated." */ if (drawable == 0) { __glXSendError(dpy, GLXBadDrawable, 0, X_GLXGetDrawableAttributes, false); return 0; } priv = __glXInitialize(dpy); if (priv == NULL) return 0; use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); *value = 0; opcode = __glXSetupForCommand(dpy); if (!opcode) return 0; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) pdraw = GetGLXDRIDrawable(dpy, drawable); if (attribute == GLX_BACK_BUFFER_AGE_EXT) { struct glx_context *gc = __glXGetCurrentContext(); struct glx_screen *psc; /* The GLX_EXT_buffer_age spec says: * * "If querying GLX_BACK_BUFFER_AGE_EXT and <draw> is not bound to * the calling thread's current context a GLXBadDrawable error is * generated." */ if (pdraw == NULL || gc == &dummyContext || gc->currentDpy != dpy || (gc->currentDrawable != drawable && gc->currentReadable != drawable)) { __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, false); return 0; } psc = pdraw->psc; if (psc->driScreen->getBufferAge != NULL) *value = psc->driScreen->getBufferAge(pdraw); return 0; } #endif LockDisplay(dpy); if (use_glx_1_3) { xGLXGetDrawableAttributesReq *req; GetReq(GLXGetDrawableAttributes, req); req->reqType = opcode; req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; } else { xGLXVendorPrivateWithReplyReq *vpreq; GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); data = (CARD32 *) (vpreq + 1); data[0] = (CARD32) drawable; vpreq->reqType = opcode; vpreq->glxCode = X_GLXVendorPrivateWithReply; vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; } _XReply(dpy, (xReply *) & reply, 0, False); if (reply.type == X_Error) { UnlockDisplay(dpy); SyncHandle(); return 0; } length = reply.length; if (length) { num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; data = malloc(length * sizeof(CARD32)); if (data == NULL) { /* Throw data on the floor */ _XEatData(dpy, length); } else { _XRead(dpy, (char *) data, length * sizeof(CARD32)); /* Search the set of returned attributes for the attribute requested by * the caller. */ for (i = 0; i < num_attributes; i++) { if (data[i * 2] == attribute) { *value = data[(i * 2) + 1]; break; } } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) if (pdraw != NULL) { if (!pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); if (!pdraw->textureFormat) pdraw->textureFormat = determineTextureFormat((const int *) data, num_attributes); } #endif free(data); } } UnlockDisplay(dpy); SyncHandle(); return 0; }