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 <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
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;
}

View File

@ -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,

View File

@ -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

View File

@ -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...