sna/present: Queue the unflip if we have flips outstanding
Rather than synchronously wait in the unflip for the pageflips to complete by forcing the modeset, try to queue the unflip to happen after the pending flip completes. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
6ba3bd9dfd
commit
f93aab9bbc
|
|
@ -354,6 +354,7 @@ struct sna {
|
|||
bool available;
|
||||
bool open;
|
||||
#if HAVE_PRESENT
|
||||
uint64_t unflip;
|
||||
#endif
|
||||
} present;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ struct sna_present_event {
|
|||
xf86CrtcPtr crtc;
|
||||
};
|
||||
|
||||
static void sna_present_unflip(ScreenPtr screen, uint64_t event_id);
|
||||
|
||||
static inline struct sna_present_event *
|
||||
to_present_event(uintptr_t data)
|
||||
{
|
||||
|
|
@ -201,11 +203,21 @@ check_flip__crtc(struct sna *sna,
|
|||
|
||||
assert(sna->scrn->vtSema);
|
||||
|
||||
if (!sna->mode.front_active) {
|
||||
DBG(("%s: DPMS off, no flips\n", __FUNCTION__));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (sna->mode.shadow_active) {
|
||||
DBG(("%s: shadow buffer active\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sna->mode.flip_active) {
|
||||
DBG(("%s: flips still pending\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -229,11 +241,6 @@ sna_present_check_flip(RRCrtcPtr crtc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!sna->mode.front_active) {
|
||||
DBG(("%s: DPMS off, no flips\n", __FUNCTION__));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (sna->flags & SNA_NO_FLIP) {
|
||||
DBG(("%s: flips not suported\n", __FUNCTION__));
|
||||
return FALSE;
|
||||
|
|
@ -312,6 +319,7 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
|
|||
{
|
||||
struct sna_present_event *info = data;
|
||||
struct ust_msc swap;
|
||||
struct sna *sna;
|
||||
|
||||
DBG(("%s(sequence=%d)\n", __FUNCTION__, event->sequence));
|
||||
|
||||
|
|
@ -327,6 +335,14 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
|
|||
swap.tv_sec, swap.tv_usec, (long long)swap.msc,
|
||||
(long long)info->event_id));
|
||||
present_event_notify(info->event_id, ust64(swap.tv_sec, swap.tv_usec), swap.msc);
|
||||
|
||||
sna = info->crtc ? to_sna(info->crtc->scrn) : NULL;
|
||||
if (sna && sna->present.unflip) {
|
||||
DBG(("%s: executing queued unflip\n", __FUNCTION__));
|
||||
sna_present_unflip(xf86ScrnToScreen(sna->scrn),
|
||||
sna->present.unflip);
|
||||
sna->present.unflip = 0;
|
||||
}
|
||||
free(info);
|
||||
}
|
||||
|
||||
|
|
@ -412,6 +428,8 @@ sna_present_flip(RRCrtcPtr crtc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
assert(to_sna_from_pixmap(pixmap)->present.unflip == 0);
|
||||
|
||||
bo = get_flip_bo(pixmap);
|
||||
if (bo == NULL) {
|
||||
DBG(("%s: flip invalid bo\n", __FUNCTION__));
|
||||
|
|
@ -448,6 +466,13 @@ notify:
|
|||
return;
|
||||
}
|
||||
|
||||
if (sna->mode.flip_active) {
|
||||
DBG(("%s: outstanding flips, queueing unflip\n", __FUNCTION__));
|
||||
assert(sna->present.unflip == 0);
|
||||
sna->present.unflip = event_id;
|
||||
return;
|
||||
}
|
||||
|
||||
bo = get_flip_bo(screen->GetScreenPixmap(screen));
|
||||
if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) {
|
||||
DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__));
|
||||
|
|
|
|||
Loading…
Reference in New Issue