From patchwork Tue May 3 17:59:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 750972 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p43I1xlJ027058 for ; Tue, 3 May 2011 18:02:20 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4BB0A9EDA2 for ; Tue, 3 May 2011 11:01:59 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from oproxy8-pub.bluehost.com (oproxy8-pub.bluehost.com [69.89.22.20]) by gabe.freedesktop.org (Postfix) with SMTP id 458169EC2F for ; Tue, 3 May 2011 10:59:31 -0700 (PDT) Received: (qmail 14239 invoked by uid 0); 3 May 2011 17:59:30 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by oproxy2.bluehost.com with SMTP; 3 May 2011 17:59:30 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References:X-Identified-User; b=QE275qIbrH26ZLelsWOTCkpTXnxTal6qooH9R+ohvU8OiV2ni71hXbBEd8LJ8AZUjUXTmC+WBjr9uJ2j6jkLLN8kDYGb2Cls6ixOtToyYNjtBzhng/8EQT9V3mbNsRX5; Received: from c-67-161-37-189.hsd1.ca.comcast.net ([67.161.37.189] helo=localhost.localdomain) by box514.bluehost.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1QHJse-0004gv-Po; Tue, 03 May 2011 11:59:28 -0600 From: Jesse Barnes To: dri-devel@lists.freedesktop.org, xorg-devel@lists.freedesktop.org, mesa-dev@lists.freedesktop.org Subject: [PATCH 4/5] DRI2: support generic swap event handling Date: Tue, 3 May 2011 10:59:17 -0700 Message-Id: <1304445561-9910-5-git-send-email-jbarnes@virtuousgeek.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1304445561-9910-1-git-send-email-jbarnes@virtuousgeek.org> References: <1304445561-9910-1-git-send-email-jbarnes@virtuousgeek.org> X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 67.161.37.189 authed with jbarnes@virtuousgeek.org} X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 03 May 2011 18:02:20 +0000 (UTC) The existing swap event structure is too large to fit in an XEvent, so new servers will send a generic event if the client supports it. This allows a valid swap count value to be sent along with the event type, timestamp, and media stamp. Check for server support based on the advertised DRI2 version and look for generic events in the event stream with DRI2 in the extension field. Signed-off-by: Jesse Barnes --- configure.ac | 2 +- src/glx/dri2.c | 105 ++++++++++++++++++++++++++++++++++++-------------- src/glx/dri2.h | 3 +- src/glx/dri2_glx.c | 31 +++++++++++++- src/glx/glxclient.h | 2 + 5 files changed, 108 insertions(+), 35 deletions(-) diff --git a/configure.ac b/configure.ac index 3b05ca3..92d11af 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl Versions for external dependencies LIBDRM_REQUIRED=2.4.24 LIBDRM_RADEON_REQUIRED=2.4.24 LIBDRM_INTEL_REQUIRED=2.4.24 -DRI2PROTO_REQUIRED=2.1 +DRI2PROTO_REQUIRED=2.4 GLPROTO_REQUIRED=1.4.11 LIBDRM_XORG_REQUIRED=2.4.24 LIBKMS_XORG_REQUIRED=1.0.0 diff --git a/src/glx/dri2.c b/src/glx/dri2.c index adfd3d1..9cab639 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -48,7 +48,7 @@ */ #if DRI2_MINOR < 1 #undef DRI2_MINOR -#define DRI2_MINOR 1 +#define DRI2_MINOR 4 #define X_DRI2GetBuffersWithFormat 7 #endif @@ -88,43 +88,85 @@ static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); + int type; XextCheckExtension(dpy, info, dri2ExtensionName, False); - switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { + if (wire->u.u.type == GenericEvent && + dri2ServerSupportsSBC(dpy)) { + xGenericEvent *wire2 = (xGenericEvent *)wire; + if (!dri2Event(dpy, wire2->extension)) + return False; + type = wire2->evtype; + } else { + type = (wire->u.u.type & 0x7f) - info->codes->first_event; + } + + switch (type) { #ifdef X_DRI2SwapBuffers case DRI2_BufferSwapComplete: { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; - xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; - - /* 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->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_COPY_COMPLETE_INTEL; - break; - case DRI2_FLIP_COMPLETE: - aevent->event_type = GLX_FLIP_COMPLETE_INTEL; - break; - default: - /* unknown swap completion type */ - return False; + + if (dri2ServerSupportsSBC(dpy)) { + xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire; + + /* 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->send_event = (awire->type & 0x80) != 0; + aevent->display = dpy; + aevent->drawable = awire->drawable; + switch (awire->swap_event_type) { + case DRI2_EXCHANGE_COMPLETE: + aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; + break; + case DRI2_BLIT_COMPLETE: + aevent->event_type = GLX_COPY_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; + } else { + xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; + /* 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->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_COPY_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 = 0; } - 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 @@ -184,11 +226,12 @@ DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) } Bool -DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) +DRI2QueryExtension(Display * dpy, int *extBase, int *eventBase, int *errorBase) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); if (XextHasExtension(info)) { + *extBase = info->codes->major_opcode; *eventBase = info->codes->first_event; *errorBase = info->codes->first_error; return True; @@ -241,6 +284,8 @@ DRI2QueryVersion(Display * dpy, int *major, int *minor) XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); } + XESetWireToEvent(dpy, GenericEvent, DRI2WireToEvent); + return True; } diff --git a/src/glx/dri2.h b/src/glx/dri2.h index 114e9f8..b3a9918 100644 --- a/src/glx/dri2.h +++ b/src/glx/dri2.h @@ -46,7 +46,8 @@ typedef struct } DRI2Buffer; extern Bool -DRI2QueryExtension(Display * display, int *eventBase, int *errorBase); +DRI2QueryExtension(Display * display, int *extBase, int *eventBase, + int *errorBase); extern Bool DRI2QueryVersion(Display * display, int *major, int *minor); diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index fc0237a..19be513 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -55,12 +55,14 @@ #define DRI_CONF_VBLANK_ALWAYS_SYNC 3 #undef DRI2_MINOR -#define DRI2_MINOR 1 +#define DRI2_MINOR 4 struct dri2_display { __GLXDRIdisplay base; + int majorOpcode; + /* ** XFree86-DRI version information */ @@ -791,6 +793,28 @@ static const struct glx_screen_vtable dri2_screen_vtable = { dri2_create_context }; +int +dri2ServerSupportsSBC(Display *dpy) +{ + struct glx_display *dpyPriv = __glXInitialize(dpy); + struct dri2_display *pdp = + (struct dri2_display *) dpyPriv->dri2Display; + + if (pdp->driMajor > 1 || (pdp->driMajor == 1 && pdp->driMinor > 3)) + return 1; + + return 0; +} + +int dri2Event(Display *dpy, int extension) +{ + struct glx_display *dpyPriv = __glXInitialize(dpy); + struct dri2_display *pdp = + (struct dri2_display *) dpyPriv->dri2Display; + + return pdp->majorOpcode == extension; +} + static struct glx_screen * dri2CreateScreen(int screen, struct glx_display * priv) { @@ -973,9 +997,9 @@ _X_HIDDEN __GLXDRIdisplay * dri2CreateDisplay(Display * dpy) { struct dri2_display *pdp; - int eventBase, errorBase, i; + int extBase, eventBase, errorBase, i; - if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) + if (!DRI2QueryExtension(dpy, &extBase, &eventBase, &errorBase)) return NULL; pdp = Xmalloc(sizeof *pdp); @@ -987,6 +1011,7 @@ dri2CreateDisplay(Display * dpy) return NULL; } + pdp->majorOpcode = extBase; pdp->driPatch = 0; pdp->swapAvailable = (pdp->driMinor >= 2); pdp->invalidateAvailable = (pdp->driMinor >= 3); diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 2b6966f..755a66d 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -149,6 +149,8 @@ extern __GLXDRIdisplay *driCreateDisplay(Display * dpy); extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy); extern void dri2InvalidateBuffers(Display *dpy, XID drawable); extern unsigned dri2GetSwapEventType(Display *dpy, XID drawable); +extern int dri2ServerSupportsSBC(Display *dpy); +extern int dri2Event(Display *dpy, int extension); /*