From 4d89ba0058457d51f2e1a132c0b7fc8a3ec5c76d Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Mon, 27 May 2019 22:42:34 +0200 Subject: [PATCH] present: Unfold and annotate the target-msc getter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfold and extensively annotate the target-msc adjustment function, to make it easier to understand what's happening and why. Signed-off-by: Roman Gilg Reviewed-by: Michel Dänzer --- present/present.c | 90 ++++++++++++++++++++++++++++-------------- present/present_priv.h | 6 +-- present/present_scmd.c | 6 +-- present/present_wnmd.c | 6 +-- 4 files changed, 69 insertions(+), 39 deletions(-) diff --git a/present/present.c b/present/present.c index 1a2163cdc..43581e378 100644 --- a/present/present.c +++ b/present/present.c @@ -27,17 +27,6 @@ #include "present_priv.h" #include -/* - * Returns: - * TRUE if the first MSC value is equal to or after the second one - * FALSE if the first MSC value is before the second one - */ -static Bool -msc_is_equal_or_after(uint64_t test, uint64_t reference) -{ - return (int64_t)(test - reference) >= 0; -} - uint32_t present_query_capabilities(RRCrtcPtr crtc) { @@ -158,30 +147,71 @@ present_can_window_flip(WindowPtr window) } uint64_t -present_get_target_msc(uint32_t options, +present_get_target_msc(uint64_t target_msc_arg, uint64_t crtc_msc, - uint64_t target_msc, uint64_t divisor, - uint64_t remainder) + uint64_t remainder, + uint32_t options) { - /* Adjust target_msc to match modulus + const Bool synced_flip = !(options & PresentOptionAsync); + uint64_t target_msc; + + /* If the specified target-msc lies in the future, then this + * defines the target-msc according to Present protocol. */ - if (msc_is_equal_or_after(crtc_msc, target_msc)) { - if (divisor != 0) { - target_msc = crtc_msc - (crtc_msc % divisor) + remainder; - if (options & PresentOptionAsync) { - if (msc_is_after(crtc_msc, target_msc)) - target_msc += divisor; - } else { - if (msc_is_equal_or_after(crtc_msc, target_msc)) - target_msc += divisor; - } - } else { - target_msc = crtc_msc; - if (!(options & PresentOptionAsync)) - (target_msc)++; - } + if (msc_is_after(target_msc_arg, crtc_msc)) + return target_msc_arg; + + /* If no divisor is specified, the modulo is undefined + * and we do present instead asap. + */ + if (divisor == 0) { + target_msc = crtc_msc; + + /* When no async presentation is forced, by default we sync the + * presentation with vblank. But in this case we can't target + * the current crtc-msc, which already has begun, but must aim + * for the upcoming one. + */ + if (synced_flip) + target_msc++; + + return target_msc; } + + /* Calculate target-msc by the specified modulo parameters. According + * to Present protocol this is after the next field with: + * + * field-msc % divisor == remainder. + * + * The following formula calculates a target_msc solving above equation + * and with |target_msc - crtc_msc| < divisor. + * + * Example with crtc_msc = 10, divisor = 4 and remainder = 3, 2, 1, 0: + * 11 = 10 - 2 + 3 = 10 - (10 % 4) + 3, + * 10 = 10 - 2 + 2 = 10 - (10 % 4) + 2, + * 9 = 10 - 2 + 1 = 10 - (10 % 4) + 1, + * 8 = 10 - 2 + 0 = 10 - (10 % 4) + 0. + */ + target_msc = crtc_msc - (crtc_msc % divisor) + remainder; + + /* Here we already found the correct field-msc. */ + if (msc_is_after(target_msc, crtc_msc)) + return target_msc; + /* + * Here either: + * a) target_msc == crtc_msc, i.e. crtc_msc actually solved + * above equation with crtc_msc % divisor == remainder. + * + * => This means we want to present at target_msc + divisor for a synced + * flip or directly now for an async flip. + * + * b) target_msc < crtc_msc with target_msc + divisor > crtc_msc. + * + * => This means in any case we want to present at target_msc + divisor. + */ + if (synced_flip || msc_is_after(crtc_msc, target_msc)) + target_msc += divisor; return target_msc; } diff --git a/present/present_priv.h b/present/present_priv.h index 3205d033d..2bd6b4062 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -280,11 +280,11 @@ present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap); uint64_t -present_get_target_msc(uint32_t options, +present_get_target_msc(uint64_t target_msc_arg, uint64_t crtc_msc, - uint64_t target_msc, uint64_t divisor, - uint64_t remainder); + uint64_t remainder, + uint32_t options); int present_pixmap(WindowPtr window, diff --git a/present/present_scmd.c b/present/present_scmd.c index 88c6ebbf7..8bf8fc1d5 100644 --- a/present/present_scmd.c +++ b/present/present_scmd.c @@ -690,11 +690,11 @@ present_scmd_pixmap(WindowPtr window, window_priv->msc = crtc_msc; } - target_msc = present_get_target_msc(options, + target_msc = present_get_target_msc(target_msc, crtc_msc, - target_msc, divisor, - remainder); + remainder, + options); /* * Look for a matching presentation already on the list and diff --git a/present/present_wnmd.c b/present/present_wnmd.c index f09e320aa..91aab985c 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -582,11 +582,11 @@ present_wnmd_pixmap(WindowPtr window, window_priv->msc = crtc_msc; } - target_msc = present_get_target_msc(options, + target_msc = present_get_target_msc(target_msc, crtc_msc, - target_msc, divisor, - remainder); + remainder, + options); /* * Look for a matching presentation already on the list...