sna/present: Fixup msc when reporting a fake vblank with 0 delay

If we have to fake a vblank because the CRTC is off and we compute the
delay as being 0, then we would report the event immediately - but with
the earlier msc. Instead, we want to report the completion.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2016-04-08 20:49:13 +01:00
parent e783ffa497
commit e5bbf519bd
1 changed files with 21 additions and 8 deletions

View File

@ -145,6 +145,10 @@ static uint32_t msc_to_delay(xf86CrtcPtr crtc, uint64_t target)
const struct ust_msc *swap = sna_crtc_last_swap(crtc);
int64_t delay, subframe;
/* XXX How to handle CRTC being off? */
if (mode->Clock == 0)
return 0;
delay = target - swap->msc;
assert(delay >= 0);
if (delay > 1) { /* try to use the hw vblank for the last frame */
@ -241,21 +245,30 @@ fixup:
static bool sna_fake_vblank(struct sna_present_event *info)
{
uint64_t msc = sna_crtc_last_swap(info->crtc)->msc;
const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
uint32_t delay;
if (msc < info->target_msc)
if (swap->msc < info->target_msc)
delay = msc_to_delay(info->crtc, info->target_msc);
else
delay = 0;
DBG(("%s(event=%lld, target_msc=%lld, msc=%lld, delay=%ums)\n",
__FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc, delay));
DBG(("%s(event=%lldx%d, target_msc=%lld, msc=%lld, delay=%ums)\n",
__FUNCTION__, (long long)info->event_id[0], info->n_event_id,
(long long)info->target_msc, (long long)swap->msc, delay));
if (delay == 0) {
const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
present_event_notify(info->event_id[0], swap_ust(swap), swap->msc);
list_del(&info->link);
free(info);
uint64_t ust, msc;
if (swap->msc < info->target_msc) {
/* Fixup and pretend it completed immediately */
msc = info->target_msc;
ust = gettime_ust64();
} else {
msc = swap->msc;
ust = swap_ust(swap);
}
vblank_complete(info, ust, msc);
return true;
}