X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fx11%2Fdri2.c;h=91053d3fb61d539a49556e3f8c99842ec86b09b9;hb=538539d8791e5b3b1ea2e95473b589934d94497e;hp=e144ed3e1f91aaa4df601cf5f115fd3624dd335f;hpb=1d4dbd8d9b00cdba8c4aef4a3994d8763fea0dff;p=mesa.git diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index e144ed3e1f9..91053d3fb61 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -31,13 +31,18 @@ */ +#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" /* Allow the build to work with an older versions of dri2proto.h and * dri2tokens.h. @@ -53,6 +58,11 @@ static char dri2ExtensionName[] = DRI2_NAME; static XExtensionInfo *dri2Info; 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 /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_gc */ NULL, /* copy_gc */ @@ -61,8 +71,8 @@ static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_font */ NULL, /* free_font */ DRI2CloseDisplay, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ + DRI2WireToEvent, /* wire_to_event */ + DRI2EventToWire, /* event_to_wire */ NULL, /* error */ NULL, /* error_string */ }; @@ -71,7 +81,78 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, - 0, NULL) + 1, NULL) + +static Bool +DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); + static int glx_event_base; + static Bool found_glx_info = False; + + 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; + 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; + switch (awire->event_type) { + case DRI2_EXCHANGE_COMPLETE: + aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; + break; + case DRI2_BLIT_COMPLETE: + aevent->event_type = GLX_BLIT_COMPLETE_INTEL; + break; + case DRI2_FLIP_COMPLETE: + aevent->event_type = GLX_FLIP_COMPLETE_INTEL; + break; + default: + /* unknown swap completion type */ + return False; + } + 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; + return True; + } +#endif + + default: + /* client doesn't support server event */ + break; + } + + return False; +} + +/* We don't actually support this. It doesn't make sense for clients to + * send each other DRI2 events. + */ +static Status +DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + + XextCheckExtension(dpy, info, dri2ExtensionName, False); + + switch (event->type) { + default: + /* client doesn't support server event */ + break; + } + + return Success; +} Bool DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) @@ -377,3 +458,188 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, UnlockDisplay(dpy); 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 */