present: Unfold and annotate the target-msc getter

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 <subdiff@gmail.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Roman Gilg 2019-05-27 22:42:34 +02:00
parent 99e55f1b95
commit 4d89ba0058
4 changed files with 69 additions and 39 deletions

View File

@ -27,17 +27,6 @@
#include "present_priv.h" #include "present_priv.h"
#include <gcstruct.h> #include <gcstruct.h>
/*
* 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 uint32_t
present_query_capabilities(RRCrtcPtr crtc) present_query_capabilities(RRCrtcPtr crtc)
{ {
@ -158,30 +147,71 @@ present_can_window_flip(WindowPtr window)
} }
uint64_t uint64_t
present_get_target_msc(uint32_t options, present_get_target_msc(uint64_t target_msc_arg,
uint64_t crtc_msc, uint64_t crtc_msc,
uint64_t target_msc,
uint64_t divisor, 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 (msc_is_after(target_msc_arg, crtc_msc))
if (divisor != 0) { return target_msc_arg;
target_msc = crtc_msc - (crtc_msc % divisor) + remainder;
if (options & PresentOptionAsync) { /* If no divisor is specified, the modulo is undefined
if (msc_is_after(crtc_msc, target_msc)) * and we do present instead asap.
target_msc += divisor; */
} else { if (divisor == 0) {
if (msc_is_equal_or_after(crtc_msc, target_msc)) target_msc = crtc_msc;
target_msc += divisor;
} /* When no async presentation is forced, by default we sync the
} else { * presentation with vblank. But in this case we can't target
target_msc = crtc_msc; * the current crtc-msc, which already has begun, but must aim
if (!(options & PresentOptionAsync)) * for the upcoming one.
(target_msc)++; */
} 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; return target_msc;
} }

View File

@ -280,11 +280,11 @@ present_set_tree_pixmap(WindowPtr window,
PixmapPtr pixmap); PixmapPtr pixmap);
uint64_t uint64_t
present_get_target_msc(uint32_t options, present_get_target_msc(uint64_t target_msc_arg,
uint64_t crtc_msc, uint64_t crtc_msc,
uint64_t target_msc,
uint64_t divisor, uint64_t divisor,
uint64_t remainder); uint64_t remainder,
uint32_t options);
int int
present_pixmap(WindowPtr window, present_pixmap(WindowPtr window,

View File

@ -690,11 +690,11 @@ present_scmd_pixmap(WindowPtr window,
window_priv->msc = crtc_msc; window_priv->msc = crtc_msc;
} }
target_msc = present_get_target_msc(options, target_msc = present_get_target_msc(target_msc,
crtc_msc, crtc_msc,
target_msc,
divisor, divisor,
remainder); remainder,
options);
/* /*
* Look for a matching presentation already on the list and * Look for a matching presentation already on the list and

View File

@ -582,11 +582,11 @@ present_wnmd_pixmap(WindowPtr window,
window_priv->msc = crtc_msc; window_priv->msc = crtc_msc;
} }
target_msc = present_get_target_msc(options, target_msc = present_get_target_msc(target_msc,
crtc_msc, crtc_msc,
target_msc,
divisor, divisor,
remainder); remainder,
options);
/* /*
* Look for a matching presentation already on the list... * Look for a matching presentation already on the list...