Signed-off-by: Qiang Yu <qiang...@amd.com>
---
 hw/xfree86/drivers/modesetting/dri2.c            | 13 +++++++++++--
 hw/xfree86/drivers/modesetting/drmmode_display.h |  3 +++
 hw/xfree86/drivers/modesetting/present.c         | 15 +++++++++++++++
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/dri2.c 
b/hw/xfree86/drivers/modesetting/dri2.c
index 11e0e6f..1abf98c 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -423,9 +423,14 @@ ms_dri2_flip_abort(void *data)
 {
     struct ms_crtc_pageflip *flip = data;
     struct ms_flipdata *flipdata = flip->flipdata;
+    ScreenPtr screen = flipdata->screen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
 
-    if (flipdata->flip_count == 1)
-        free(flipdata->event);
+    if (flipdata->flip_count == 1) {
+            ms->drmmode.dri2_flipping = FALSE;
+            free(flipdata->event);
+    }
 
     ms_dri2_flip_free(flip);
 }
@@ -469,6 +474,8 @@ ms_dri2_schedule_flip(ms_dri2_frame_event_ptr info)
 {
     DrawablePtr draw = info->drawable;
     ScreenPtr screen = draw->pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
     ms_dri2_buffer_private_ptr back_priv = info->back->driverPrivate;
     struct ms_dri2_vblank_event *event;
     drmmode_crtc_private_ptr drmmode_crtc = info->crtc->driver_private;
@@ -486,6 +493,7 @@ ms_dri2_schedule_flip(ms_dri2_frame_event_ptr info)
                        drmmode_crtc->vblank_pipe, FALSE,
                        ms_dri2_flip_handler,
                        ms_dri2_flip_abort)) {
+        ms->drmmode.dri2_flipping = TRUE;
         return TRUE;
     }
     return FALSE;
@@ -571,6 +579,7 @@ can_flip(ScrnInfoPtr scrn, DrawablePtr draw,
 
     return draw->type == DRAWABLE_WINDOW &&
         ms->drmmode.pageflip &&
+        !ms->drmmode.present_flipping &&
         scrn->vtSema &&
         DRI2CanFlip(draw) && can_exchange(scrn, draw, front, back);
 }
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h 
b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 5499c16..f774250 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -80,6 +80,9 @@ typedef struct {
     Bool is_secondary;
 
     PixmapPtr fbcon_pixmap;
+
+    Bool dri2_flipping;
+    Bool present_flipping;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
diff --git a/hw/xfree86/drivers/modesetting/present.c 
b/hw/xfree86/drivers/modesetting/present.c
index f4318b4..d10c674 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -53,6 +53,7 @@
 
 struct ms_present_vblank_event {
     uint64_t        event_id;
+    Bool            unflip;
 };
 
 static RRCrtcPtr
@@ -221,6 +222,7 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void 
*data)
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     modesettingPtr ms = modesettingPTR(scrn);
     struct ms_flipdata *flipdata = flip->flipdata;
+    struct ms_present_vblank_event *event = flipdata->event;
 
     DebugPresent(("\t\tms:fh %lld c %d msc %llu ust %llu\n",
                   (long long) flipdata->event->event_id,
@@ -238,6 +240,8 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void 
*data)
                       flipdata->flip_count,
                       (long long) flipdata->fe_msc, (long long) 
flipdata->fe_usec));
 
+        if (event->unflip)
+            ms->drmmode.present_flipping = FALSE;
 
         ms_present_vblank_handler(flipdata->fe_msc,
                                   flipdata->fe_usec,
@@ -284,6 +288,9 @@ ms_present_check_flip(RRCrtcPtr crtc,
     if (!ms->drmmode.pageflip)
         return FALSE;
 
+    if (ms->drmmode.dri2_flipping)
+        return FALSE;
+
     if (!scrn->vtSema)
         return FALSE;
 
@@ -330,6 +337,7 @@ ms_present_flip(RRCrtcPtr crtc,
 {
     ScreenPtr screen = crtc->pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
     xf86CrtcPtr xf86_crtc = crtc->devPrivate;
     drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
     Bool ret;
@@ -343,10 +351,14 @@ ms_present_flip(RRCrtcPtr crtc,
         return FALSE;
 
     event->event_id = event_id;
+    event->unflip = FALSE;
+
     ret = ms_do_pageflip(screen, pixmap, event, drmmode_crtc->vblank_pipe, 
!sync_flip,
                          ms_present_flip_handler, ms_present_flip_abort);
     if (!ret)
         xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
+    else
+        ms->drmmode.present_flipping = TRUE;
 
     return ret;
 }
@@ -358,6 +370,7 @@ static void
 ms_present_unflip(ScreenPtr screen, uint64_t event_id)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    modesettingPtr ms = modesettingPTR(scrn);
     PixmapPtr pixmap = screen->GetScreenPixmap(screen);
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
     int i;
@@ -368,6 +381,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
         return;
 
     event->event_id = event_id;
+    event->unflip = TRUE;
 
     if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) &&
         ms_do_pageflip(screen, pixmap, event, -1, FALSE,
@@ -399,6 +413,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
     }
 
     present_event_notify(event_id, 0, 0);
+    ms->drmmode.present_flipping = FALSE;
 }
 #endif
 
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to