By default Xlib isn't thread safe so we better avoid it when gl thread is enabled.
It will help applications that use XCB. But it will still crash if applications are still relying on Xlib (without XInitThread). Note: those dri2* functions are typically called by gallium/mesa state tracker to handle new backbuffer allocation. When the old backbuffer was previously invalidated due to vsync. Signed-off-by: Gregory Hainaut <gregory.hain...@gmail.com> --- src/glx/dri2.c | 118 ----------------------------------------------------- src/glx/dri2.h | 25 ------------ src/glx/dri2_glx.c | 64 +++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 160 deletions(-) diff --git a/src/glx/dri2.c b/src/glx/dri2.c index f00b96525a..eed899e237 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -391,138 +391,20 @@ DRI2DestroyDrawable(Display * dpy, XID drawable) LockDisplay(dpy); GetReq(DRI2DestroyDrawable, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2DestroyDrawable; req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); } -DRI2Buffer * -DRI2GetBuffers(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, int *outCount) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetBuffersReply rep; - xDRI2GetBuffersReq *req; - DRI2Buffer *buffers; - xDRI2Buffer repBuffer; - CARD32 *p; - int i; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReqExtra(DRI2GetBuffers, count * 4, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetBuffers; - req->drawable = drawable; - req->count = count; - p = (CARD32 *) & req[1]; - for (i = 0; i < count; i++) - p[i] = attachments[i]; - - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - *width = rep.width; - *height = rep.height; - *outCount = rep.count; - - buffers = malloc(rep.count * sizeof buffers[0]); - if (buffers == NULL) { - _XEatData(dpy, rep.count * sizeof repBuffer); - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - for (i = 0; i < rep.count; i++) { - _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); - buffers[i].attachment = repBuffer.attachment; - buffers[i].name = repBuffer.name; - buffers[i].pitch = repBuffer.pitch; - buffers[i].cpp = repBuffer.cpp; - buffers[i].flags = repBuffer.flags; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return buffers; -} - - -DRI2Buffer * -DRI2GetBuffersWithFormat(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, int *outCount) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetBuffersReply rep; - xDRI2GetBuffersReq *req; - DRI2Buffer *buffers; - xDRI2Buffer repBuffer; - CARD32 *p; - int i; - - XextCheckExtension(dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetBuffersWithFormat; - req->drawable = drawable; - req->count = count; - p = (CARD32 *) & req[1]; - for (i = 0; i < (count * 2); i++) - p[i] = attachments[i]; - - if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - *width = rep.width; - *height = rep.height; - *outCount = rep.count; - - buffers = malloc(rep.count * sizeof buffers[0]); - if (buffers == NULL) { - _XEatData(dpy, rep.count * sizeof repBuffer); - UnlockDisplay(dpy); - SyncHandle(); - return NULL; - } - - for (i = 0; i < rep.count; i++) { - _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); - buffers[i].attachment = repBuffer.attachment; - buffers[i].name = repBuffer.name; - buffers[i].pitch = repBuffer.pitch; - buffers[i].cpp = repBuffer.cpp; - buffers[i].flags = repBuffer.flags; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return buffers; -} - - void DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2CopyRegionReq *req; xDRI2CopyRegionReply rep; XextSimpleCheckExtension(dpy, info, dri2ExtensionName); diff --git a/src/glx/dri2.h b/src/glx/dri2.h index 4be5bf8eb8..c383e27123 100644 --- a/src/glx/dri2.h +++ b/src/glx/dri2.h @@ -30,29 +30,20 @@ * Kristian Høgsberg (k...@redhat.com) */ #ifndef _DRI2_H_ #define _DRI2_H_ #include <xf86drm.h> #include <X11/extensions/Xfixes.h> #include <X11/extensions/dri2tokens.h> -typedef struct -{ - unsigned int attachment; - unsigned int name; - unsigned int pitch; - unsigned int cpp; - unsigned int flags; -} DRI2Buffer; - struct glx_screen; extern Bool DRI2QueryExtension(Display * display, int *eventBase, int *errorBase); extern Bool DRI2QueryVersion(Display * display, int *major, int *minor); extern Bool DRI2Connect(Display * display, XID window, @@ -60,32 +51,16 @@ DRI2Connect(Display * display, XID window, extern Bool DRI2Authenticate(Display * display, XID window, drm_magic_t magic); extern void DRI2CreateDrawable(Display * display, XID drawable); extern void DRI2DestroyDrawable(Display * display, XID handle); -extern DRI2Buffer* -DRI2GetBuffers(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, int count, - int *outCount); - -/** - * \note - * This function is only supported with DRI2 version 1.1 or later. - */ -extern DRI2Buffer* -DRI2GetBuffersWithFormat(Display * dpy, XID drawable, - int *width, int *height, - unsigned int *attachments, - int count, int *outCount); - extern void DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src); #endif diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 145f44d6e8..bb61985592 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -707,21 +707,21 @@ dri2DestroyScreen(struct glx_screen *base) free(psc); } /** * Process list of buffer received from the server * * Processes the list of buffers received in a reply from the server to either * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat. */ static void -process_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers, +process_buffers(struct dri2_drawable * pdraw, xcb_dri2_dri2_buffer_t * buffers, unsigned count) { int i; pdraw->bufferCount = count; pdraw->have_fake_front = 0; pdraw->have_back = 0; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ @@ -859,57 +859,87 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, return ret; } static __DRIbuffer * dri2GetBuffers(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) { struct dri2_drawable *pdraw = loaderPrivate; - DRI2Buffer *buffers; + xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy); + xcb_dri2_dri2_buffer_t *buffers; + xcb_dri2_get_buffers_reply_t *reply; + xcb_dri2_get_buffers_cookie_t cookie; - buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, - width, height, attachments, count, out_count); - if (buffers == NULL) + (void) driDrawable; + + cookie = xcb_dri2_get_buffers_unchecked(c, pdraw->base.xDrawable, + count, count, attachments); + + reply = xcb_dri2_get_buffers_reply(c, cookie, NULL); + if (reply == NULL) return NULL; - pdraw->width = *width; - pdraw->height = *height; + buffers = xcb_dri2_get_buffers_buffers(reply); + if (buffers == NULL) { + free(reply); + return NULL; + } + + *out_count = reply->count; + pdraw->width = *width = reply->width; + pdraw->height = *height = reply->height; process_buffers(pdraw, buffers, *out_count); - free(buffers); + free(reply); return pdraw->buffers; } static __DRIbuffer * dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) { struct dri2_drawable *pdraw = loaderPrivate; - DRI2Buffer *buffers; + xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy); + xcb_dri2_dri2_buffer_t *buffers; + xcb_dri2_get_buffers_with_format_reply_t *reply; + xcb_dri2_get_buffers_with_format_cookie_t cookie; + xcb_dri2_attach_format_t *format_attachments; + + (void) driDrawable; + + format_attachments = (xcb_dri2_attach_format_t *)attachments; + cookie = xcb_dri2_get_buffers_with_format_unchecked(c, + pdraw->base.xDrawable, + count, count, + format_attachments); + + reply = xcb_dri2_get_buffers_with_format_reply(c, cookie, NULL); + if (reply == NULL) + return NULL; - buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy, - pdraw->base.xDrawable, - width, height, attachments, - count, out_count); - if (buffers == NULL) + buffers = xcb_dri2_get_buffers_with_format_buffers(reply); + if (buffers == NULL) { + free(reply); return NULL; + } - pdraw->width = *width; - pdraw->height = *height; + *out_count = reply->count; + pdraw->width = *width = reply->width; + pdraw->height = *height = reply->height; process_buffers(pdraw, buffers, *out_count); - free(buffers); + free(reply); return pdraw->buffers; } static int dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval) { xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy); struct dri2_drawable *priv = (struct dri2_drawable *) pdraw; GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev