From ae05f74e4efc69be05d53b7e419b66c2ff36f4bd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 7 Feb 2015 15:48:50 +0000 Subject: [PATCH] sna/present: Try to use async flips for unflip If possible, we want the restoration of the Screen Pixmap to be fast, and so we want to preferably use the immediate asynchronous flip. Signed-off-by: Chris Wilson --- src/sna/sna_present.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index 96d43c8f..55adca4c 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -283,7 +283,8 @@ static uint64_t gettime_ust64(void) } static Bool -page_flip__async(RRCrtcPtr crtc, +page_flip__async(struct sna *sna, + RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, struct kgem_bo *bo) @@ -294,7 +295,7 @@ page_flip__async(RRCrtcPtr crtc, (long long)event_id, bo->handle)); - if (!sna_page_flip(to_sna_from_screen(crtc->pScreen), bo, NULL, NULL)) { + if (!sna_page_flip(sna, bo, NULL, NULL)) { DBG(("%s: async pageflip failed\n", __FUNCTION__)); present_info.capabilities &= ~PresentCapabilityAsync; return FALSE; @@ -342,12 +343,11 @@ present_flip_handler(struct drm_event_vblank *event, void *data) } static Bool -page_flip(ScreenPtr screen, +page_flip(struct sna *sna, RRCrtcPtr crtc, uint64_t event_id, struct kgem_bo *bo) { - struct sna *sna = to_sna_from_screen(screen); struct sna_present_event *event; DBG(("%s(pipe=%d, event=%lld, handle=%d)\n", @@ -438,9 +438,9 @@ sna_present_flip(RRCrtcPtr crtc, } if (sync_flip) - return page_flip(crtc->pScreen, crtc, event_id, bo); + return page_flip(sna, crtc, event_id, bo); else - return page_flip__async(crtc, event_id, target_msc, bo); + return page_flip__async(sna, crtc, event_id, target_msc, bo); } static void @@ -475,11 +475,21 @@ notify: } bo = get_flip_bo(screen->GetScreenPixmap(screen)); - if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) { + if (bo == NULL) { +reset_mode: DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__)); xf86SetDesiredModes(sna->scrn); goto notify; } + + if (sna->flags & SNA_HAS_ASYNC_FLIP) { + DBG(("%s: trying async flip restore\n", __FUNCTION__)); + if (page_flip__async(sna, NULL, event_id, 0, bo)) + return; + } + + if (!page_flip(sna, NULL, event_id, bo)) + goto reset_mode; } static present_screen_info_rec present_info = {