From patchwork Mon Jan 19 11:00:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 5657441 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A50249F333 for ; Mon, 19 Jan 2015 11:17:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 68BF820351 for ; Mon, 19 Jan 2015 11:17:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 83D842011D for ; Mon, 19 Jan 2015 11:17:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7DB966E554; Mon, 19 Jan 2015 03:17:17 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay.fireflyinternet.com (hostedrelay.fireflyinternet.com [109.228.30.76]) by gabe.freedesktop.org (Postfix) with ESMTP id 08CFA6E538; Mon, 19 Jan 2015 03:17:15 -0800 (PST) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by relay.fireflyinternet.com (FireflyRelay1) with ESMTP id 12848043-1305619 for multiple; Mon, 19 Jan 2015 11:00:54 +0000 From: Chris Wilson To: xorg-devel@lists.x.org, dri-devel@lists.freedesktop.org, mesa-dev@lists.freedesktop.org Subject: [mesa 8/9] glx/dri2: Move the wait after SwapBuffers into the next GetBuffers Date: Mon, 19 Jan 2015 11:00:44 +0000 Message-Id: <1421665245-5994-9-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1421665245-5994-1-git-send-email-chris@chris-wilson.co.uk> References: <1421665245-5994-1-git-send-email-chris@chris-wilson.co.uk> X-Authenticated-User: chris.alporthouse@surfanytime.net X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As the SBC from the reply from SwapBuffers is not used immediately and can be easily determined by counting the new of SwapBuffers requests made by the client, we can defer the synchronisation point to the pending GetBuffers round trip. (We force the invalidation event in order to require the GetBuffers round trip - we know that all X servers will send the invalidation after SwapBuffers and that invalidation will arrive before the SwapBuffers reply, so no extra roundtrips are forced.) An important side-effect is demonstrated in the next patch where we can detect when the buffers are stale before querying properties. Signed-off-by: Chris Wilson --- src/glx/dri2_glx.c | 73 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 462d560..0577804 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -93,6 +93,10 @@ struct dri2_drawable int have_back; int have_fake_front; int swap_interval; + int swap_pending; + + xcb_dri2_swap_buffers_cookie_t swap_buffers_cookie; + int64_t last_swap_sbc; uint64_t previous_time; unsigned frames; @@ -778,50 +782,51 @@ static void show_fps(struct dri2_drawable *draw) } } -static int64_t -dri2XcbSwapBuffers(Display *dpy, - __GLXDRIdrawable *pdraw, +static void +dri2XcbSwapBuffers(struct dri2_drawable *priv, int64_t target_msc, int64_t divisor, int64_t remainder) { - xcb_dri2_swap_buffers_cookie_t swap_buffers_cookie; - xcb_dri2_swap_buffers_reply_t *swap_buffers_reply; + xcb_connection_t *c = XGetXCBConnection(priv->base.psc->dpy); uint32_t target_msc_hi, target_msc_lo; uint32_t divisor_hi, divisor_lo; uint32_t remainder_hi, remainder_lo; - int64_t ret = 0; - xcb_connection_t *c = XGetXCBConnection(dpy); split_counter(target_msc, &target_msc_hi, &target_msc_lo); split_counter(divisor, &divisor_hi, &divisor_lo); split_counter(remainder, &remainder_hi, &remainder_lo); - swap_buffers_cookie = - xcb_dri2_swap_buffers_unchecked(c, pdraw->xDrawable, + priv->swap_buffers_cookie = + xcb_dri2_swap_buffers_unchecked(c, priv->base.xDrawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo); + xcb_flush(c); + priv->swap_pending++; - /* Immediately wait on the swapbuffers reply. If we didn't, we'd have - * to do so some time before reusing a (non-pageflipped) backbuffer. - * Otherwise, the new rendering could get ahead of the X Server's - * dispatch of the swapbuffer and you'd display garbage. - * - * We use XSync() first to reap the invalidate events through the event - * filter, to ensure that the next drawing doesn't use an invalidated - * buffer. - */ - XSync(dpy, False); + /* Force a synchronous completion prior to the next rendering */ + dri2InvalidateBuffers(priv->base.psc->dpy, priv->base.xDrawable); +} + +static void dri2XcbSwapBuffersComplete(struct dri2_drawable *priv) +{ + xcb_dri2_swap_buffers_reply_t *swap_buffers_reply; + + if (!priv->swap_pending) + return; + + priv->swap_pending = 0; swap_buffers_reply = - xcb_dri2_swap_buffers_reply(c, swap_buffers_cookie, NULL); - if (swap_buffers_reply) { - ret = merge_counter(swap_buffers_reply->swap_hi, - swap_buffers_reply->swap_lo); - free(swap_buffers_reply); - } - return ret; + xcb_dri2_swap_buffers_reply(XGetXCBConnection(priv->base.psc->dpy), + priv->swap_buffers_cookie, NULL); + if (swap_buffers_reply == NULL) + return; + + priv->last_swap_sbc = merge_counter(swap_buffers_reply->swap_hi, + swap_buffers_reply->swap_lo); + free(swap_buffers_reply); } static int64_t @@ -833,11 +838,10 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc; struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display; - int64_t ret = 0; /* Check we have the right attachments */ if (!priv->have_back) - return ret; + return 0; /* Old servers can't handle swapbuffers */ if (!pdp->swapAvailable) { @@ -850,19 +854,14 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, flags |= __DRI2_FLUSH_CONTEXT; dri2Flush(psc, ctx, priv, flags, __DRI2_THROTTLE_SWAPBUFFER); - ret = dri2XcbSwapBuffers(pdraw->psc->dpy, pdraw, - target_msc, divisor, remainder); + dri2XcbSwapBuffers(priv, target_msc, divisor, remainder); } if (psc->show_fps_interval) { show_fps(priv); } - /* Old servers don't send invalidate events */ - if (!pdp->invalidateAvailable) - dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable); - - return ret; + return priv->last_swap_sbc + priv->swap_pending; } static __DRIbuffer * @@ -885,6 +884,8 @@ dri2GetBuffers(__DRIdrawable * driDrawable, free(buffers); + dri2XcbSwapBuffersComplete(pdraw); + return pdraw->buffers; } @@ -910,6 +911,8 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, free(buffers); + dri2XcbSwapBuffersComplete(pdraw); + return pdraw->buffers; }