[PATCH v2 xserver 5/5] modesetting: exclude DRI2 and prensent page flip

Qiang Yu Qiang.Yu at amd.com
Fri Aug 19 12:50:50 UTC 2016


Signed-off-by: Qiang Yu <Qiang.Yu at amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
---
 hw/xfree86/drivers/modesetting/dri2.c            | 11 +++++++++--
 hw/xfree86/drivers/modesetting/driver.h          |  5 +++--
 hw/xfree86/drivers/modesetting/drmmode_display.h |  3 +++
 hw/xfree86/drivers/modesetting/pageflip.c        |  7 +++++--
 hw/xfree86/drivers/modesetting/present.c         | 20 ++++++++++++++++++--
 5 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index acbb980..125c413 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -408,15 +408,17 @@ struct ms_dri2_vblank_event {
 };
 
 static void
-ms_dri2_flip_abort(void *data)
+ms_dri2_flip_abort(modesettingPtr ms, void *data)
 {
     struct ms_present_vblank_event *event = data;
 
+    ms->drmmode.dri2_flipping = FALSE;
     free(event);
 }
 
 static void
-ms_dri2_flip_handler(uint64_t msc, uint64_t ust, void *data)
+ms_dri2_flip_handler(modesettingPtr ms, uint64_t msc, 
+                     uint64_t ust, void *data)
 {
     struct ms_dri2_vblank_event *event = data;
     uint32_t frame = msc;
@@ -432,6 +434,7 @@ ms_dri2_flip_handler(uint64_t msc, uint64_t ust, void *data)
                          DRI2_FLIP_COMPLETE, event->event_complete,
                          event->event_data);
 
+    ms->drmmode.dri2_flipping = FALSE;
     free(event);
 }
 
@@ -440,6 +443,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;
@@ -457,6 +462,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;
@@ -542,6 +548,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/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 38f0ec0..761490a 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -156,11 +156,12 @@ Bool ms_present_screen_init(ScreenPtr screen);
 
 #ifdef GLAMOR
 
-typedef void (*ms_pageflip_handler_proc)(uint64_t frame,
+typedef void (*ms_pageflip_handler_proc)(modesettingPtr ms,
+                                         uint64_t frame,
                                          uint64_t usec,
                                          void *data);
 
-typedef void (*ms_pageflip_abort_proc)(void *data);
+typedef void (*ms_pageflip_abort_proc)(modesettingPtr ms, void *data);
 
 int ms_flush_drm_events(ScreenPtr screen);
 
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/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c
index 5f35999..a82e0d6 100644
--- a/hw/xfree86/drivers/modesetting/pageflip.c
+++ b/hw/xfree86/drivers/modesetting/pageflip.c
@@ -98,7 +98,7 @@ ms_pageflip_handler(uint64_t msc, uint64_t ust, void *data)
     }
 
     if (flipdata->flip_count == 1) {
-        flipdata->event_handler(flipdata->fe_msc,
+        flipdata->event_handler(ms, flipdata->fe_msc,
                                 flipdata->fe_usec,
                                 flipdata->event);
 
@@ -115,9 +115,12 @@ ms_pageflip_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)
-        flipdata->abort_handler(flipdata->event);
+        flipdata->abort_handler(ms, flipdata->event);
 
     ms_pageflip_free(flip);
 }
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index deee1f1..c0bb221 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
@@ -196,7 +197,8 @@ ms_present_flush(WindowPtr window)
  * extension code telling it when that happened
  */
 static void
-ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
+ms_present_flip_handler(modesettingPtr ms, uint64_t msc, 
+                        uint64_t ust, void *data)
 {
     struct ms_present_vblank_event *event = data;
 
@@ -204,6 +206,9 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
                   (long long) event->event_id,
                   (long long) msc, (long long) ust));
 
+    if (event->unflip)
+        ms->drmmode.present_flipping = FALSE;
+
     ms_present_vblank_handler(msc, ust, event);
 }
 
@@ -211,7 +216,7 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data)
  * Callback for the flip has been aborted.
  */
 static void
-ms_present_flip_abort(void *data)
+ms_present_flip_abort(modesettingPtr ms, void *data)
 {
     struct ms_present_vblank_event *event = data;
 
@@ -237,6 +242,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;
 
@@ -283,6 +291,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;
@@ -298,10 +307,14 @@ ms_present_flip(RRCrtcPtr crtc,
     DebugPresent(("\t\tms:fq %lld\n", event_id));
 
     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;
 }
@@ -313,6 +326,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;
@@ -323,6 +337,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,
@@ -354,6 +369,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



More information about the xorg-devel mailing list