X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fglx%2Fdri2.c;h=f00b96525aad1c6942ea8ebbfe768a456694260a;hp=5de55cdbf29505fa97bb9713bf2150f2851b8ea7;hb=84395190ec8cae6158737777c8def7cc3304eb3f;hpb=846cf495226be78b05e74064662eba4e7eb8280e diff --git a/src/glx/dri2.c b/src/glx/dri2.c index 5de55cdbf29..f00b96525aa 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -33,13 +33,11 @@ #ifdef GLX_DIRECT_RENDERING -#define NEED_REPLIES #include #include #include #include #include -#include "xf86drm.h" #include "dri2.h" #include "glxclient.h" #include "GL/glxext.h" @@ -55,13 +53,16 @@ static char dri2ExtensionName[] = DRI2_NAME; -static XExtensionInfo *dri2Info; +static XExtensionInfo _dri2Info_data; +static XExtensionInfo *dri2Info = &_dri2Info_data; static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); static Status DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); +static int +DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_gc */ @@ -73,7 +74,7 @@ static /* const */ XExtensionHooks dri2ExtensionHooks = { DRI2CloseDisplay, /* close_display */ DRI2WireToEvent, /* wire_to_event */ DRI2EventToWire, /* event_to_wire */ - NULL, /* error */ + DRI2Error, /* error */ NULL, /* error_string */ }; @@ -87,20 +88,28 @@ static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); - XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); + struct glx_drawable *glxDraw; XextCheckExtension(dpy, info, dri2ExtensionName, False); switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { -#ifdef X_DRI2SwapBuffers case DRI2_BufferSwapComplete: { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; - xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; + xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire; + __GLXDRIdrawable *pdraw; + + pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable); + if (pdraw == NULL) + return False; + + /* Ignore swap events if we're not looking for them */ + aevent->type = dri2GetSwapEventType(dpy, awire->drawable); + if(!aevent->type) + return False; + aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); - aevent->type = - (glx_info->codes->first_event + GLX_BufferSwapComplete) & 0x75; aevent->send_event = (awire->type & 0x80) != 0; aevent->display = dpy; aevent->drawable = awire->drawable; @@ -109,7 +118,7 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; break; case DRI2_BLIT_COMPLETE: - aevent->event_type = GLX_BLIT_COMPLETE_INTEL; + aevent->event_type = GLX_COPY_COMPLETE_INTEL; break; case DRI2_FLIP_COMPLETE: aevent->event_type = GLX_FLIP_COMPLETE_INTEL; @@ -120,11 +129,19 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) } aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; - aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; + + glxDraw = GetGLXDrawable(dpy, pdraw->drawable); + if (glxDraw != NULL) { + if (awire->sbc < glxDraw->lastEventSbc) + glxDraw->eventSbcWrap += 0x100000000; + glxDraw->lastEventSbc = awire->sbc; + aevent->sbc = awire->sbc + glxDraw->eventSbcWrap; + } else { + aevent->sbc = awire->sbc; + } + return True; } -#endif -#ifdef DRI2_InvalidateBuffers case DRI2_InvalidateBuffers: { xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; @@ -132,7 +149,6 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) dri2InvalidateBuffers(dpy, awire->drawable); return False; } -#endif default: /* client doesn't support server event */ break; @@ -160,6 +176,34 @@ DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) return Success; } +static int +DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) +{ + if (err->majorCode == codes->major_opcode && + err->errorCode == BadDrawable && + err->minorCode == X_DRI2CopyRegion) + return True; + + /* If the X drawable was destroyed before the GLX drawable, the + * DRI2 drawble will be gone by the time we call + * DRI2DestroyDrawable. So just ignore BadDrawable here. */ + if (err->majorCode == codes->major_opcode && + err->errorCode == BadDrawable && + err->minorCode == X_DRI2DestroyDrawable) + return True; + + /* If the server is non-local DRI2Connect will raise BadRequest. + * Swallow this so that DRI2Connect can signal this in its return code */ + if (err->majorCode == codes->major_opcode && + err->minorCode == X_DRI2Connect && + err->errorCode == BadRequest) { + *ret_code = False; + return True; + } + + return False; +} + Bool DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) { @@ -235,7 +279,20 @@ DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2Connect; req->window = window; + req->driverType = DRI2DriverDRI; + { + char *prime = getenv("DRI_PRIME"); + if (prime) { + uint32_t primeid; + errno = 0; + primeid = strtoul(prime, NULL, 0); + if (errno == 0) + req->driverType |= + ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift); + } + } + if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); @@ -248,7 +305,7 @@ DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) return False; } - *driverName = Xmalloc(rep.driverNameLength + 1); + *driverName = malloc(rep.driverNameLength + 1); if (*driverName == NULL) { _XEatData(dpy, ((rep.driverNameLength + 3) & ~3) + @@ -260,9 +317,9 @@ DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) _XReadPad(dpy, *driverName, rep.driverNameLength); (*driverName)[rep.driverNameLength] = '\0'; - *deviceName = Xmalloc(rep.deviceNameLength + 1); + *deviceName = malloc(rep.deviceNameLength + 1); if (*deviceName == NULL) { - Xfree(*driverName); + free(*driverName); _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); UnlockDisplay(dpy); SyncHandle(); @@ -376,7 +433,7 @@ DRI2GetBuffers(Display * dpy, XID drawable, *height = rep.height; *outCount = rep.count; - buffers = Xmalloc(rep.count * sizeof buffers[0]); + buffers = malloc(rep.count * sizeof buffers[0]); if (buffers == NULL) { _XEatData(dpy, rep.count * sizeof repBuffer); UnlockDisplay(dpy); @@ -435,7 +492,7 @@ DRI2GetBuffersWithFormat(Display * dpy, XID drawable, *height = rep.height; *outCount = rep.count; - buffers = Xmalloc(rep.count * sizeof buffers[0]); + buffers = malloc(rep.count * sizeof buffers[0]); if (buffers == NULL) { _XEatData(dpy, rep.count * sizeof repBuffer); UnlockDisplay(dpy); @@ -484,187 +541,4 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, SyncHandle(); } -#ifdef X_DRI2SwapBuffers -static void -load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, - CARD64 remainder) -{ - req->target_msc_hi = target >> 32; - req->target_msc_lo = target & 0xffffffff; - req->divisor_hi = divisor >> 32; - req->divisor_lo = divisor & 0xffffffff; - req->remainder_hi = remainder >> 32; - req->remainder_lo = remainder & 0xffffffff; -} - -static CARD64 -vals_to_card64(CARD32 lo, CARD32 hi) -{ - return (CARD64)hi << 32 | lo; -} - -void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, - CARD64 divisor, CARD64 remainder, CARD64 *count) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2SwapBuffersReq *req; - xDRI2SwapBuffersReply rep; - - XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2SwapBuffers, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2SwapBuffers; - req->drawable = drawable; - load_swap_req(req, target_msc, divisor, remainder); - - _XReply(dpy, (xReply *)&rep, 0, xFalse); - - *count = vals_to_card64(rep.swap_lo, rep.swap_hi); - - UnlockDisplay(dpy); - SyncHandle(); -} -#endif - -#ifdef X_DRI2GetMSC -Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, - CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2GetMSCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2GetMSC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2GetMSC; - req->drawable = drawable; - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = vals_to_card64(rep.ust_lo, rep.ust_hi); - *msc = vals_to_card64(rep.msc_lo, rep.msc_hi); - *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2WaitMSC -static void -load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor, - CARD64 remainder) -{ - req->target_msc_hi = target >> 32; - req->target_msc_lo = target & 0xffffffff; - req->divisor_hi = divisor >> 32; - req->divisor_lo = divisor & 0xffffffff; - req->remainder_hi = remainder >> 32; - req->remainder_lo = remainder & 0xffffffff; -} - -Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, - CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2WaitMSCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2WaitMSC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2WaitMSC; - req->drawable = drawable; - load_msc_req(req, target_msc, divisor, remainder); - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo; - *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo; - *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo; - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2WaitSBC -static void -load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target) -{ - req->target_sbc_hi = target >> 32; - req->target_sbc_lo = target & 0xffffffff; -} - -Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, - CARD64 *msc, CARD64 *sbc) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2WaitSBCReq *req; - xDRI2MSCReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2WaitSBC, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2WaitSBC; - req->drawable = drawable; - load_sbc_req(req, target_sbc); - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo; - *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo; - *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo; - - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} -#endif - -#ifdef X_DRI2SwapInterval -void DRI2SwapInterval(Display *dpy, XID drawable, int interval) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2SwapIntervalReq *req; - - XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - - LockDisplay(dpy); - GetReq(DRI2SwapInterval, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2SwapInterval; - req->drawable = drawable; - req->interval = interval; - UnlockDisplay(dpy); - SyncHandle(); -} -#endif - #endif /* GLX_DIRECT_RENDERING */