From patchwork Sat Dec 14 01:25:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Packard X-Patchwork-Id: 3344051 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 98E7E9F2A9 for ; Sat, 14 Dec 2013 01:28:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BA98E20707 for ; Sat, 14 Dec 2013 01:28:54 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D724220702 for ; Sat, 14 Dec 2013 01:28:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 850D1FBC78; Fri, 13 Dec 2013 17:28:48 -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 D588CFB342; Fri, 13 Dec 2013 17:25:50 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by keithp.com (Postfix) with ESMTP id 36A811488008; Fri, 13 Dec 2013 17:25:50 -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 5pY9WSo8BaNP; Fri, 13 Dec 2013 17:25:46 -0800 (PST) Received: by keithp.com (Postfix, from userid 1033) id BEE7F148800D; Fri, 13 Dec 2013 17:25:34 -0800 (PST) Received: from miki.keithp.com (localhost [127.0.0.1]) by keithp.com (Postfix) with ESMTP id 0BDE3149800C; Fri, 13 Dec 2013 17:25:34 -0800 (PST) Received: by miki.keithp.com (Postfix, from userid 1001) id B78B8DDB; Fri, 13 Dec 2013 17:25:31 -0800 (PST) From: Keith Packard To: mesa-dev@lists.freedesktop.org Subject: [PATCH 08/18] dri3: Fix dri3_wait_for_sbc to wait for completion of requested SBC Date: Fri, 13 Dec 2013 17:25:20 -0800 Message-Id: <1386984330-26074-9-git-send-email-keithp@keithp.com> X-Mailer: git-send-email 1.8.4.4 In-Reply-To: <1386984330-26074-1-git-send-email-keithp@keithp.com> References: <1386984330-26074-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 b9a786f..d2b9d0e 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; } /**