From patchwork Tue Nov 26 05:35:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Packard X-Patchwork-Id: 3236511 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B5E029F3AE for ; Tue, 26 Nov 2013 05:36:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DBB65200E7 for ; Tue, 26 Nov 2013 05:36:34 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 0D57D2016D for ; Tue, 26 Nov 2013 05:36:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5568BFB282; Mon, 25 Nov 2013 21:36:31 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from keithp.com (home.keithp.com [63.227.221.253]) by gabe.freedesktop.org (Postfix) with ESMTP id EE701FAF2A; Mon, 25 Nov 2013 21:36:03 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by keithp.com (Postfix) with ESMTP id 92C5A760094; Mon, 25 Nov 2013 21:36:03 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at keithp.com Received: from keithp.com ([127.0.0.1]) by localhost (keithp.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id A-fI65yozTCk; Mon, 25 Nov 2013 21:36:00 -0800 (PST) Received: by keithp.com (Postfix, from userid 1033) id CA3B676009A; Mon, 25 Nov 2013 21:35:59 -0800 (PST) Received: from miki.keithp.com (localhost [127.0.0.1]) by keithp.com (Postfix) with ESMTP id A8017760094; Mon, 25 Nov 2013 21:35:59 -0800 (PST) Received: by miki.keithp.com (Postfix, from userid 1001) id 01285D22; Mon, 25 Nov 2013 21:35:58 -0800 (PST) From: Keith Packard To: mesa-dev@lists.freedesktop.org, Eric Anholt Subject: [PATCH 3/4] dri3: Fix dri3_wait_for_sbc to wait for completion of requested SBC Date: Mon, 25 Nov 2013 21:35:54 -0800 Message-Id: <1385444155-15506-4-git-send-email-keithp@keithp.com> X-Mailer: git-send-email 1.8.4.4 In-Reply-To: <1385444155-15506-1-git-send-email-keithp@keithp.com> References: <86ob5751ju.fsf@miki.keithp.com> <1385444155-15506-1-git-send-email-keithp@keithp.com> Cc: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 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@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Eric figured out that glXWaitForSbcOML wanted to block until the requested SBC had been completed, which means to wait until the PresentCompleteNotify event for that SBC had been received. This replaces the simple sleep(1) loop (which was bogus) with a loop that just checks to see if we've seen the specified SBC value come back in a PresentCompleteNotify event yet. The change is a bit larger than that as I've broken out a piece of common code to wait for and process a single Present event for the target drawable. Signed-off-by: Keith Packard --- src/glx/dri3_glx.c | 55 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index c0915f2..da3f08b 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -397,14 +397,33 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_ free(ge); } +static bool +dri3_wait_for_event(__GLXDRIdrawable *pdraw) +{ + xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy); + struct dri3_drawable *priv = (struct dri3_drawable *) pdraw; + xcb_generic_event_t *ev; + xcb_present_generic_event_t *ge; + + ev = xcb_wait_for_special_event(c, priv->special_event); + if (!ev) + return false; + ge = (void *) ev; + dri3_handle_present_event(priv, ge); + return true; +} + +/** dri3_wait_for_msc + * + * Get the X server to send an event when the target msc/divisor/remainder is + * reached. + */ static int dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) { xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy); struct dri3_drawable *priv = (struct dri3_drawable *) pdraw; - xcb_generic_event_t *ev; - xcb_present_generic_event_t *ge; uint32_t msc_serial; /* Ask for the an event for the target MSC */ @@ -421,11 +440,8 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, /* Wait for the event */ if (priv->special_event) { while ((int32_t) (msc_serial - priv->recv_msc_serial) > 0) { - ev = xcb_wait_for_special_event(c, priv->special_event); - if (!ev) - break; - ge = (void *) ev; - dri3_handle_present_event(priv, ge); + if (!dri3_wait_for_event(pdraw)) + return 0; } } @@ -436,6 +452,11 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, return 1; } +/** dri3_drawable_get_msc + * + * Return the current UST/MSC/SBC triplet by asking the server + * for an event + */ static int dri3_drawable_get_msc(struct glx_screen *psc, __GLXDRIdrawable *pdraw, int64_t *ust, int64_t *msc, int64_t *sbc) @@ -445,12 +466,9 @@ dri3_drawable_get_msc(struct glx_screen *psc, __GLXDRIdrawable *pdraw, /** dri3_wait_for_sbc * - * Wait for the swap buffer count to increase. The only way this - * can happen is if some other thread is doing swap buffers as - * we no longer share swap buffer counts with other processes. - * - * I'm not sure this is actually useful as such, and so this - * implementation is a kludge that just polls once a second + * Wait for the completed swap buffer count to reach the specified + * target. Presumably the application knows that this will be reached with + * outstanding complete events, or we're going to be here awhile. */ static int dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, @@ -458,10 +476,15 @@ dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, { struct dri3_drawable *priv = (struct dri3_drawable *) pdraw; - while (priv->send_sbc < target_sbc) { - sleep(1); + while (priv->recv_sbc < target_sbc) { + if (!dri3_wait_for_event(pdraw)) + return 0; } - return dri3_wait_for_msc(pdraw, 0, 0, 0, ust, msc, sbc); + + *ust = priv->ust; + *msc = priv->msc; + *sbc = priv->recv_sbc; + return 1; } /**