xf86-video-ati: Branch 'master' - 2 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Tue Mar 1 01:28:04 UTC 2016


 src/drmmode_display.c  |   92 ++++++++++++++++++++++---------------------------
 src/drmmode_display.h  |   13 +++---
 src/radeon.h           |    2 -
 src/radeon_dri2.c      |   42 ++++++++++------------
 src/radeon_drm_queue.c |   14 +++----
 src/radeon_drm_queue.h |    6 +--
 src/radeon_kms.c       |   23 ++++++------
 src/radeon_present.c   |   18 ++++-----
 8 files changed, 101 insertions(+), 109 deletions(-)

New commits:
commit a88985f5d1e39caca49ceb65678aaa9cb622a0d2
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Mon Feb 29 18:12:43 2016 +0900

    Deal with modesets and page flips crossing on a CRTC
    
    If we set a mode while a flip is pending, the kernel driver may program
    the flip to the hardware after the modeset. If that happens, the hardware
    will display the BO from the flip, whereas we will assume it displays the
    BO from the modeset. In other words, the display will most likely freeze,
    at least until another modeset.
    
    Prevent this condition by waiting for a pending flip to finish before
    setting a mode.
    
    Fixes display freezing when setting rotation or a transform with
    TearFree enabled.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 24430a2..f1ca02c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -760,6 +760,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 				radeon_bo_wait(drmmode_crtc->scanout[0].bo);
 			}
 		}
+
+		/* Wait for any pending flip to finish */
+		do {} while (drmmode_crtc->flip_pending &&
+			     drmHandleEvent(drmmode->fd,
+					    &drmmode->event_context) > 0);
+
 		if (drmModeSetCrtc(drmmode->fd,
 				   drmmode_crtc->mode_crtc->crtc_id,
 				   fb_id, x, y, output_ids,
@@ -2024,6 +2030,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 static void
 drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data)
 {
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_flipdata_ptr flipdata = event_data;
 
 	if (--flipdata->flip_count == 0) {
@@ -2032,11 +2039,14 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data)
 		flipdata->abort(crtc, flipdata->event_data);
 		free(flipdata);
 	}
+
+	drmmode_crtc->flip_pending = FALSE;
 }
 
 static void
 drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data)
 {
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 	drmmode_flipdata_ptr flipdata = event_data;
 
@@ -2059,6 +2069,8 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even
 
 		free(flipdata);
 	}
+
+	drmmode_crtc->flip_pending = FALSE;
 }
 
 
@@ -2582,6 +2594,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 				   "flip queue failed: %s\n", strerror(errno));
 			goto error;
 		}
+		drmmode_crtc->flip_pending = TRUE;
 		drm_queue = NULL;
 	}
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 99c6c91..c295735 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -95,8 +95,12 @@ typedef struct {
     uint16_t lut_r[256], lut_g[256], lut_b[256];
     int prime_pixmap_x;
 
-    /* Modeset needed for DPMS on */
+    /* Modeset needed (for DPMS on or after a page flip crossing with a
+     * modeset)
+     */
     Bool need_modeset;
+    /* A flip is pending for this CRTC */
+    Bool flip_pending;
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
 typedef struct {
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 3768983..44fe71e 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -483,6 +483,7 @@ radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
     drmmode_crtc_private_ptr drmmode_crtc = event_data;
 
     drmmode_crtc->scanout_update_pending = FALSE;
+    drmmode_crtc->flip_pending = FALSE;
 }
 
 static void
@@ -523,6 +524,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
 
     drmmode_crtc->scanout_id = scanout_id;
     drmmode_crtc->scanout_update_pending = TRUE;
+    drmmode_crtc->flip_pending = TRUE;
 }
 
 static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
commit f5d968cbba3c9b7ec202161f2157d8d64778c817
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu May 21 12:54:31 2015 +0900

    Make DRM event queue xf86CrtcPtr based instead of ScrnInfoPtr based
    
    This allows for a minor simplification of the code.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4063743..24430a2 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -756,7 +756,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 				fb_id = drmmode_crtc->scanout[0].fb_id;
 				x = y = 0;
 
-				radeon_scanout_update_handler(pScrn, 0, 0, crtc);
+				radeon_scanout_update_handler(crtc, 0, 0, drmmode_crtc);
 				radeon_bo_wait(drmmode_crtc->scanout[0].bo);
 			}
 		}
@@ -2022,55 +2022,43 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 };
 
 static void
-drmmode_flip_free(drmmode_flipevtcarrier_ptr flipcarrier)
+drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data)
 {
-	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+	drmmode_flipdata_ptr flipdata = event_data;
 
-	free(flipcarrier);
-
-	if (--flipdata->flip_count > 0)
-		return;
-
-	free(flipdata);
-}
-
-static void
-drmmode_flip_abort(ScrnInfoPtr scrn, void *event_data)
-{
-	drmmode_flipevtcarrier_ptr flipcarrier = event_data;
-	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
-
-	if (flipdata->flip_count == 1)
-		flipdata->abort(scrn, flipdata->event_data);
-
-	drmmode_flip_free(flipcarrier);
+	if (--flipdata->flip_count == 0) {
+		if (flipdata->fe_crtc)
+			crtc = flipdata->fe_crtc;
+		flipdata->abort(crtc, flipdata->event_data);
+		free(flipdata);
+	}
 }
 
 static void
-drmmode_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *event_data)
+drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data)
 {
-	drmmode_flipevtcarrier_ptr flipcarrier = event_data;
-	drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
+	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+	drmmode_flipdata_ptr flipdata = event_data;
 
 	/* Is this the event whose info shall be delivered to higher level? */
-	if (flipcarrier->dispatch_me) {
+	if (crtc == flipdata->fe_crtc) {
 		/* Yes: Cache msc, ust for later delivery. */
 		flipdata->fe_frame = frame;
 		flipdata->fe_usec = usec;
 	}
 
-	if (flipdata->flip_count == 1) {
+	if (--flipdata->flip_count == 0) {
 		/* Deliver cached msc, ust from reference crtc to flip event handler */
-		if (flipdata->event_data)
-			flipdata->handler(scrn, flipdata->fe_frame,
-					  flipdata->fe_usec,
-					  flipdata->event_data);
+		if (flipdata->fe_crtc)
+			crtc = flipdata->fe_crtc;
+		flipdata->handler(crtc, flipdata->fe_frame, flipdata->fe_usec,
+				  flipdata->event_data);
 
 		/* Release framebuffer */
-		drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id);
-	}
+		drmModeRmFB(info->drmmode.fd, flipdata->old_fb_id);
 
-	drmmode_flip_free(flipcarrier);
+		free(flipdata);
+	}
 }
 
 
@@ -2510,13 +2498,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 {
 	RADEONInfoPtr info = RADEONPTR(scrn);
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	xf86CrtcPtr crtc = NULL;
 	drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	unsigned int pitch;
 	int i;
 	uint32_t tiling_flags = 0;
 	drmmode_flipdata_ptr flipdata;
-	drmmode_flipevtcarrier_ptr flipcarrier = NULL;
 	struct radeon_drm_queue_entry *drm_queue = NULL;
 
 	if (info->allowColorTiling) {
@@ -2559,32 +2547,26 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 	 */
 
         flipdata->event_data = data;
-        flipdata->drmmode = drmmode;
         flipdata->handler = handler;
         flipdata->abort = abort;
 
 	for (i = 0; i < config->num_crtc; i++) {
-		if (!config->crtc[i]->enabled)
+		crtc = config->crtc[i];
+
+		if (!crtc->enabled)
 			continue;
 
 		flipdata->flip_count++;
-		drmmode_crtc = config->crtc[i]->driver_private;
-
-		flipcarrier = calloc(1, sizeof(drmmode_flipevtcarrier_rec));
-		if (!flipcarrier) {
-			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-				   "flip queue: carrier alloc failed.\n");
-			goto error;
-		}
+		drmmode_crtc = crtc->driver_private;
 
 		/* Only the reference crtc will finally deliver its page flip
 		 * completion event. All other crtc's events will be discarded.
 		 */
-		flipcarrier->dispatch_me = (drmmode_crtc->hw_id == ref_crtc_hw_id);
-		flipcarrier->flipdata = flipdata;
+		if (drmmode_crtc->hw_id == ref_crtc_hw_id)
+			flipdata->fe_crtc = crtc;
 
-		drm_queue = radeon_drm_queue_alloc(scrn, client, id,
-						   flipcarrier,
+		drm_queue = radeon_drm_queue_alloc(crtc, client, id,
+						   flipdata,
 						   drmmode_flip_handler,
 						   drmmode_flip_abort);
 		if (!drm_queue) {
@@ -2600,7 +2582,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 				   "flip queue failed: %s\n", strerror(errno));
 			goto error;
 		}
-		flipcarrier = NULL;
 		drm_queue = NULL;
 	}
 
@@ -2615,8 +2596,8 @@ error:
 
 	if (drm_queue)
 		radeon_drm_abort_entry(drm_queue);
-	else if (flipcarrier)
-		drmmode_flip_abort(scrn, flipcarrier);
+	else if (crtc)
+		drmmode_flip_abort(crtc, flipdata);
 	else if (flipdata && flipdata->flip_count <= 1)
 		free(flipdata);
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index ab6c590..99c6c91 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -60,21 +60,16 @@ typedef struct {
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
-  drmmode_ptr drmmode;
   unsigned old_fb_id;
   int flip_count;
   void *event_data;
   unsigned int fe_frame;
   uint64_t fe_usec;
+  xf86CrtcPtr fe_crtc;
   radeon_drm_handler_proc handler;
   radeon_drm_abort_proc abort;
 } drmmode_flipdata_rec, *drmmode_flipdata_ptr;
 
-typedef struct {
-  drmmode_flipdata_ptr flipdata;
-  Bool dispatch_me;
-} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr;
-
 struct drmmode_scanout {
     struct radeon_bo *bo;
     PixmapPtr pixmap;
diff --git a/src/radeon.h b/src/radeon.h
index 5cec12b..fe26df4 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -608,7 +608,7 @@ extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
 Bool radeon_dri3_screen_init(ScreenPtr screen);
 
 /* radeon_kms.c */
-void radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame,
+void radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
 				   uint64_t usec, void *event_data);
 
 /* radeon_present.c */
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 740a9d3..657e6a6 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -645,19 +645,20 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
 }
 
 static void
-radeon_dri2_flip_event_abort(ScrnInfoPtr scrn, void *event_data)
+radeon_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data)
 {
-    RADEONInfoPtr info = RADEONPTR(scrn);
+    RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 
     info->drmmode.dri2_flipping = FALSE;
     free(event_data);
 }
 
 static void
-radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
+radeon_dri2_flip_event_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
 			       void *event_data)
 {
     DRI2FrameEventPtr flip = event_data;
+    ScrnInfoPtr scrn = crtc->scrn;
     unsigned tv_sec, tv_usec;
     DrawablePtr drawable;
     ScreenPtr screen;
@@ -669,9 +670,7 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
     if (status != Success)
 	goto abort;
 
-    if (!flip->crtc)
-	goto abort;
-    frame += radeon_get_msc_delta(drawable, flip->crtc);
+    frame += radeon_get_msc_delta(drawable, crtc);
 
     screen = scrn->pScreen;
     pixmap = screen->GetScreenPixmap(screen);
@@ -708,22 +707,21 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
     }
 
 abort:
-    radeon_dri2_flip_event_abort(scrn, event_data);
+    radeon_dri2_flip_event_abort(crtc, event_data);
 }
 
 static Bool
-radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
+radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client,
 			  DrawablePtr draw, DRI2BufferPtr front,
 			  DRI2BufferPtr back, DRI2SwapEventPtr func,
 			  void *data, unsigned int target_msc)
 {
+    ScrnInfoPtr scrn = crtc->scrn;
     RADEONInfoPtr info = RADEONPTR(scrn);
     struct dri2_buffer_priv *back_priv;
     struct radeon_bo *bo;
     DRI2FrameEventPtr flip_info;
-    /* Main crtc for this drawable shall finally deliver pageflip event. */
-    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
-    int ref_crtc_hw_id = crtc ? drmmode_get_crtc_id(crtc) : -1;
+    int ref_crtc_hw_id = drmmode_get_crtc_id(crtc);
 
     flip_info = calloc(1, sizeof(DRI2FrameEventRec));
     if (!flip_info)
@@ -874,7 +872,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt
     DamageRegionProcessPending(&front_priv->pixmap->drawable);
 }
 
-static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
+static void radeon_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data)
 {
     DRI2FrameEventPtr event = event_data;
 
@@ -885,30 +883,28 @@ static void radeon_dri2_frame_event_abort(ScrnInfoPtr scrn, void *event_data)
     free(event);
 }
 
-static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
+static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq,
 					    uint64_t usec, void *event_data)
 {
     DRI2FrameEventPtr event = event_data;
+    ScrnInfoPtr scrn = crtc->scrn;
     DrawablePtr drawable;
     int status;
     int swap_type;
     BoxRec box;
     RegionRec region;
 
-    if (!event->crtc)
-	goto cleanup;
-
     status = dixLookupDrawable(&drawable, event->drawable_id, serverClient,
                                M_ANY, DixWriteAccess);
     if (status != Success)
         goto cleanup;
 
-    seq += radeon_get_msc_delta(drawable, event->crtc);
+    seq += radeon_get_msc_delta(drawable, crtc);
 
     switch (event->type) {
     case DRI2_FLIP:
 	if (can_flip(scrn, drawable, event->front, event->back) &&
-	    radeon_dri2_schedule_flip(scrn,
+	    radeon_dri2_schedule_flip(crtc,
 				      event->client,
 				      drawable,
 				      event->front,
@@ -952,7 +948,7 @@ static void radeon_dri2_frame_event_handler(ScrnInfoPtr scrn, uint32_t seq,
     }
 
 cleanup:
-    radeon_dri2_frame_event_abort(scrn, event_data);
+    radeon_dri2_frame_event_abort(crtc, event_data);
 }
 
 drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc)
@@ -1108,7 +1104,7 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
 	    radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0,
 				     event_info->drm_queue);
 	else
-	    radeon_dri2_frame_event_handler(scrn, 0, 0, data);
+	    radeon_dri2_frame_event_handler(crtc, 0, 0, data);
 	return 0;
     }
     /*
@@ -1124,7 +1120,7 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
 	radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000,
 				 drm_now % 1000000, event_info->drm_queue);
     else
-	radeon_dri2_frame_event_handler(scrn, frame, drm_now, data);
+	radeon_dri2_frame_event_handler(crtc, frame, drm_now, data);
     return 0;
 }
 
@@ -1209,7 +1205,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     current_msc = vbl.reply.sequence + msc_delta;
     current_msc &= 0xffffffff;
 
-    wait = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+    wait = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
 				  wait_info, radeon_dri2_frame_event_handler,
 				  radeon_dri2_frame_event_abort);
     if (!wait) {
@@ -1356,7 +1352,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     swap_info->back = back;
     swap_info->crtc = crtc;
 
-    swap = radeon_drm_queue_alloc(scrn, client, RADEON_DRM_QUEUE_ID_DEFAULT,
+    swap = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT,
 				  swap_info, radeon_dri2_frame_event_handler,
 				  radeon_dri2_frame_event_abort);
     if (!swap) {
diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c
index a50a1fd..25fb183 100644
--- a/src/radeon_drm_queue.c
+++ b/src/radeon_drm_queue.c
@@ -42,7 +42,7 @@ struct radeon_drm_queue_entry {
     uint64_t id;
     void *data;
     ClientPtr client;
-    ScrnInfoPtr scrn;
+    xf86CrtcPtr crtc;
     radeon_drm_handler_proc handler;
     radeon_drm_abort_proc abort;
 };
@@ -65,11 +65,11 @@ radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
 		if (e == user_data) {
 			xorg_list_del(&e->list);
 			if (e->handler)
-				e->handler(e->scrn, frame,
+				e->handler(e->crtc, frame,
 					   (uint64_t)sec * 1000000 + usec,
 					   e->data);
 			else
-				e->abort(e->scrn, e->data);
+				e->abort(e->crtc, e->data);
 			free(e);
 			break;
 		}
@@ -81,7 +81,7 @@ radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
  * appears, we've got data to pass to the handler from here
  */
 struct radeon_drm_queue_entry *
-radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
+radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client,
 		       uint64_t id, void *data,
 		       radeon_drm_handler_proc handler,
 		       radeon_drm_abort_proc abort)
@@ -93,7 +93,7 @@ radeon_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
 	return NULL;
 
     e->client = client;
-    e->scrn = scrn;
+    e->crtc = crtc;
     e->id = id;
     e->data = data;
     e->handler = handler;
@@ -113,7 +113,7 @@ static void
 radeon_drm_abort_one(struct radeon_drm_queue_entry *e)
 {
     xorg_list_del(&e->list);
-    e->abort(e->scrn, e->data);
+    e->abort(e->crtc, e->data);
     free(e);
 }
 
@@ -181,7 +181,7 @@ radeon_drm_queue_close(ScrnInfoPtr scrn)
     struct radeon_drm_queue_entry *e, *tmp;
 
     xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) {
-	if (e->scrn == scrn)
+	if (e->crtc->scrn == scrn)
 	    radeon_drm_abort_one(e);
     }
 
diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h
index 8fc1c42..5d8dedf 100644
--- a/src/radeon_drm_queue.h
+++ b/src/radeon_drm_queue.h
@@ -34,14 +34,14 @@
 
 struct radeon_drm_queue_entry;
 
-typedef void (*radeon_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq,
+typedef void (*radeon_drm_handler_proc)(xf86CrtcPtr crtc, uint32_t seq,
 					uint64_t usec, void *data);
-typedef void (*radeon_drm_abort_proc)(ScrnInfoPtr scrn, void *data);
+typedef void (*radeon_drm_abort_proc)(xf86CrtcPtr crtc, void *data);
 
 void radeon_drm_queue_handler(int fd, unsigned int frame,
 			      unsigned int tv_sec, unsigned int tv_usec,
 			      void *user_ptr);
-struct radeon_drm_queue_entry *radeon_drm_queue_alloc(ScrnInfoPtr scrn,
+struct radeon_drm_queue_entry *radeon_drm_queue_alloc(xf86CrtcPtr crtc,
 						      ClientPtr client,
 						      uint64_t id,
 						      void *data,
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index d93a4ce..3768983 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -401,21 +401,20 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 }
 
 static void
-radeon_scanout_update_abort(ScrnInfoPtr scrn, void *event_data)
+radeon_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
 {
-    xf86CrtcPtr xf86_crtc = event_data;
-    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+    drmmode_crtc_private_ptr drmmode_crtc = event_data;
 
     drmmode_crtc->scanout_update_pending = FALSE;
 }
 
 void
-radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
+radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
 			      void *event_data)
 {
-    radeon_scanout_do_update(event_data, 0);
+    radeon_scanout_do_update(crtc, 0);
 
-    radeon_scanout_update_abort(scrn, event_data);
+    radeon_scanout_update_abort(crtc, event_data);
 }
 
 static void
@@ -451,9 +450,10 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
 	return;
 
     scrn = xf86_crtc->scrn;
-    drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
+    drm_queue_entry = radeon_drm_queue_alloc(xf86_crtc,
+					     RADEON_DRM_QUEUE_CLIENT_DEFAULT,
 					     RADEON_DRM_QUEUE_ID_DEFAULT,
-					     xf86_crtc,
+					     drmmode_crtc,
 					     radeon_scanout_update_handler,
 					     radeon_scanout_update_abort);
     if (!drm_queue_entry) {
@@ -478,7 +478,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
 }
 
 static void
-radeon_scanout_flip_abort(ScrnInfoPtr scrn, void *event_data)
+radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
 {
     drmmode_crtc_private_ptr drmmode_crtc = event_data;
 
@@ -502,7 +502,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
 	return;
 
     scrn = xf86_crtc->scrn;
-    drm_queue_entry = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
+    drm_queue_entry = radeon_drm_queue_alloc(xf86_crtc,
+					     RADEON_DRM_QUEUE_CLIENT_DEFAULT,
 					     RADEON_DRM_QUEUE_ID_DEFAULT,
 					     drmmode_crtc, NULL,
 					     radeon_scanout_flip_abort);
diff --git a/src/radeon_present.c b/src/radeon_present.c
index bd4d8f2..68be1c7 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -50,7 +50,7 @@
 
 struct radeon_present_vblank_event {
     uint64_t event_id;
-    xf86CrtcPtr crtc;
+    Bool unflip;
 };
 
 static uint32_t crtc_select(int crtc_id)
@@ -124,7 +124,7 @@ radeon_present_flush_drm_events(ScreenPtr screen)
  * Called when the queued vblank event has occurred
  */
 static void
-radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc,
+radeon_present_vblank_handler(xf86CrtcPtr crtc, unsigned int msc,
 			      uint64_t usec, void *data)
 {
     struct radeon_present_vblank_event *event = data;
@@ -137,7 +137,7 @@ radeon_present_vblank_handler(ScrnInfoPtr scrn, unsigned int msc,
  * Called when the queued vblank is aborted
  */
 static void
-radeon_present_vblank_abort(ScrnInfoPtr scrn, void *data)
+radeon_present_vblank_abort(xf86CrtcPtr crtc, void *data)
 {
     struct radeon_present_vblank_event *event = data;
 
@@ -165,7 +165,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
     if (!event)
 	return BadAlloc;
     event->event_id = event_id;
-    queue = radeon_drm_queue_alloc(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
+    queue = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT,
 				   event_id, event,
 				   radeon_present_vblank_handler,
 				   radeon_present_vblank_abort);
@@ -280,12 +280,12 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
  * extension code telling it when that happened
  */
 static void
-radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pageflip_data)
+radeon_present_flip_event(xf86CrtcPtr crtc, uint32_t msc, uint64_t ust, void *pageflip_data)
 {
-    RADEONInfoPtr info = RADEONPTR(scrn);
+    RADEONInfoPtr info = RADEONPTR(crtc->scrn);
     struct radeon_present_vblank_event *event = pageflip_data;
 
-    if (!event->crtc)
+    if (event->unflip)
 	info->drmmode.present_flipping = FALSE;
 
     present_event_notify(event->event_id, ust, msc);
@@ -296,7 +296,7 @@ radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void *pa
  * The flip has been aborted, free the structure
  */
 static void
-radeon_present_flip_abort(ScrnInfoPtr scrn, void *pageflip_data)
+radeon_present_flip_abort(xf86CrtcPtr crtc, void *pageflip_data)
 {
     struct radeon_present_vblank_event *event = pageflip_data;
 
@@ -331,7 +331,6 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
 	return FALSE;
 
     event->event_id = event_id;
-    event->crtc = xf86_crtc;
 
     ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
 			     event_id, event, crtc_id,
@@ -375,6 +374,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
     }
 
     event->event_id = event_id;
+    event->unflip = TRUE;
 
     if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
 			   event_id, event, -1, radeon_present_flip_event,


More information about the xorg-commit mailing list