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

Michel Dänzer daenzer at kemper.freedesktop.org
Wed May 29 06:28:12 PDT 2013


 src/drmmode_display.c |   88 +++++++++++++--
 src/drmmode_display.h |    9 +
 src/radeon.h          |    2 
 src/radeon_dri2.c     |  286 ++++++++++++++++++++++++++++++++++++++++++--------
 src/radeon_video.c    |    6 +
 src/radeon_video.h    |    1 
 6 files changed, 342 insertions(+), 50 deletions(-)

New commits:
commit bd2557ea5ef84b975060e929d5ece53ec464336f
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:48 2013 -0400

    DRI2: add interpolated blanks to frame number in event handlers
    
    The 'frame' argument passed to event handlers is the plain
    CRTC vblank counter that stops progressing when the
    associated display is in DPMS-off mode. If we have a
    DPMS-off period the frame counter and MSC will
    diverge, which can cause some higher-level functions
    to return incorrect values.
    
    This patch fixes the problem by adding interpolated
    vblanks to the frame counter before using it in handler
    functions.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 10a614b..fa3719d 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -799,6 +799,9 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec,
                                M_ANY, DixWriteAccess);
     if (status != Success)
         goto cleanup;
+    if (!event->crtc)
+	goto cleanup;
+    frame += radeon_get_interpolated_vblanks(event->crtc);
 
     screen = drawable->pScreen;
     scrn = xf86ScreenToScrn(screen);
@@ -1254,6 +1257,11 @@ void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
 	free(flip);
 	return;
     }
+    if (!flip->crtc) {
+	free(flip);
+	return;
+    }
+    frame += radeon_get_interpolated_vblanks(flip->crtc);
 
     screen = drawable->pScreen;
     scrn = xf86ScreenToScrn(screen);
commit 385a92b4fbe8f53b359ef6c463704414d00476fa
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:47 2013 -0400

    DRI2: support scheduling emulated events with zero delay
    
    Now that we fully emulating a running CRTC through DPMS-off state
    it is possible to come up with a zero delay when scheduling
    a swap or MSC-wait (e.g., if a call into respective wait function
    was entered very late). This patch wraps the TimerSet function
    into our own radeon_dri2_schedule_event such that the latter
    calls the event right away if zero delay is specified.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 9a58219..10a614b 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -1076,6 +1076,18 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
     return 0;
 }
 
+static
+void radeon_dri2_schedule_event(CARD32 delay, pointer arg)
+{
+    OsTimerPtr timer;
+
+    timer = TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, arg);
+    if (delay == 0) {
+	CARD32 now = GetTimeInMillis();
+	radeon_dri2_deferred_event(timer, now, arg);
+    }
+}
+
 /*
  * Request a DRM event when the requested conditions will be satisfied.
  *
@@ -1132,7 +1144,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 	delay = radeon_dri2_extrapolate_msc_delay(crtc, &target_msc,
 						  divisor, remainder);
 	wait_info->frame = target_msc;
-	TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, wait_info);
+	radeon_dri2_schedule_event(delay, wait_info);
 	DRI2BlockClient(client, draw);
 	return TRUE;
     }
@@ -1364,7 +1376,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc,
 						  divisor, remainder);
 	swap_info->frame = *target_msc;
-	TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, swap_info);
+	radeon_dri2_schedule_event(delay, swap_info);
 	return TRUE;
     }
 
@@ -1377,9 +1389,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "first get vblank counter failed: %s\n",
                 strerror(errno));
-	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
-		 swap_info);
 	*target_msc = 0;
+	radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
 	return TRUE;
     }
 
@@ -1431,9 +1442,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
             xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                     "divisor 0 get vblank counter failed: %s\n",
                     strerror(errno));
-	    TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
-		     swap_info);
 	    *target_msc = 0;
+	    radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
             return TRUE;
         }
 
@@ -1481,9 +1491,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "final get vblank counter failed: %s\n",
                 strerror(errno));
-	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
-		 swap_info);
 	*target_msc = 0;
+	radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info);
 	return TRUE;
     }
 
commit e87b52e6ad41ad7a87e43b818d80e7d522d9c68d
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:46 2013 -0400

    DRI2: make wait_msc and get_msc work on disabled CRTCs
    
    Now that the running CRTC is emulated through DPMS-off
    states, wait_msc and get_msc must also work on disabled
    CRTCs. When CRTC is disabled, we must extrapolate the
    MSC count from present time and last MSC when CRTC was
    running and also use timers facility in wait_msc.
    
    v2: CRTC-private now stores frame rate instead of nominal
        vblank period.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 2620171..9a58219 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -963,7 +963,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
     RADEONInfoPtr info = RADEONPTR(scrn);
     drmVBlank vbl;
     int ret;
-    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
 
     /* Drawable not displayed, make up a value */
     if (crtc == NULL) {
@@ -971,21 +971,47 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
         *msc = 0;
         return TRUE;
     }
-    vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
-    vbl.request.sequence = 0;
+    if (radeon_crtc_is_enabled(crtc)) {
+	/* CRTC is running, read vblank counter and timestamp */
+	vbl.request.type = DRM_VBLANK_RELATIVE;
+	vbl.request.type |= radeon_populate_vbl_request_type(crtc);
+	vbl.request.sequence = 0;
 
-    ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
-    if (ret) {
-        xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-                "get vblank counter failed: %s\n", strerror(errno));
-        return FALSE;
-    }
+	ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
+	if (ret) {
+	    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+		       "get vblank counter failed: %s\n", strerror(errno));
+	    return FALSE;
+	}
 
-    *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
-    *msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
-    *msc &= 0xffffffff;
+	*ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
+	*msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
+	*msc &= 0xffffffff;
+    } else {
+	/* CRTC is not running, extrapolate MSC and timestamp */
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	CARD64 now, delta_t, delta_seq;
 
+	if (!drmmode_crtc->dpms_last_ust)
+	    return FALSE;
+	ret = drmmode_get_current_ust(info->dri2.drm_fd, &now);
+	if (ret) {
+	    xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+		       "%s cannot get current time\n", __func__);
+	    return FALSE;
+	}
+	delta_t = now - drmmode_crtc->dpms_last_ust;
+	delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
+	delta_seq /= 1000000;
+	*ust = drmmode_crtc->dpms_last_ust;
+	delta_t = delta_seq * 1000000;
+	delta_t /= drmmode_crtc->dpms_last_fps;
+	*ust += delta_t;
+	*msc = drmmode_crtc->dpms_last_seq;
+	*msc += drmmode_crtc->interpolated_vblanks;
+	*msc += delta_seq;
+	*msc &= 0xffffffff;
+    }
     return TRUE;
 }
 
@@ -1064,7 +1090,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     RADEONInfoPtr info = RADEONPTR(scrn);
     DRI2FrameEventPtr wait_info = NULL;
-    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
     drmVBlank vbl;
     int ret;
     CARD64 current_msc;
@@ -1097,6 +1123,20 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         goto out_complete;
     }
 
+    /*
+     * CRTC is in DPMS off state, calculate wait time from current time,
+     * target_msc and last vblank time/sequence when CRTC was turned off
+     */
+    if (!radeon_crtc_is_enabled(crtc)) {
+	CARD32 delay;
+	delay = radeon_dri2_extrapolate_msc_delay(crtc, &target_msc,
+						  divisor, remainder);
+	wait_info->frame = target_msc;
+	TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, wait_info);
+	DRI2BlockClient(client, draw);
+	return TRUE;
+    }
+
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
     vbl.request.type |= radeon_populate_vbl_request_type(crtc);
commit f1584152bbeda98cc1907359f1c7954a84c8837d
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:45 2013 -0400

    DRI2: move rename and rework radeon_dri2_deferred_swap
    
    radeon_dri2_deferred_swap will be used to generate
    real events (not just fallbacks) so now it needs to
    generate real timestamp and frame counter. Also
    this function will be used both by schedule_swap
    and wait_msc, so give it a more generic name:
    radeon_dri2_deferred_event
    
    v2: - Extrapolate the frame number from the time
          of actual execution of the function instead
          of using the MSC calculated (extrapolated)
          at event scheduling time.
        - CRTC-private now stores frame rate instead of
          nominal vblank period.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 7d3b16a..2620171 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -989,6 +989,67 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
     return TRUE;
 }
 
+static
+CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
+{
+    DRI2FrameEventPtr event_info = (DRI2FrameEventPtr)data;
+    DrawablePtr drawable;
+    ScreenPtr screen;
+    ScrnInfoPtr scrn;
+    RADEONInfoPtr info;
+    int status;
+    CARD64 drm_now;
+    int ret;
+    unsigned int tv_sec, tv_usec;
+    CARD64 delta_t, delta_seq, frame;
+    drmmode_crtc_private_ptr drmmode_crtc;
+    TimerFree(timer);
+
+    /*
+     * This is emulated event, so its time is current time, which we
+     * have to get in DRM-compatible form (which is a bit messy given
+     * the information that we have at this point). Can't use now argument
+     * because DRM event time may come from monotonic clock, while
+     * DIX timer facility uses real-time clock.
+     */
+    if (!event_info->crtc) {
+	ErrorF("%s no crtc\n", __func__);
+	radeon_dri2_frame_event_handler(0, 0, 0, data);
+	return 0;
+    }
+    status = dixLookupDrawable(&drawable, event_info->drawable_id, serverClient,
+			       M_ANY, DixWriteAccess);
+    if (status != Success) {
+	ErrorF("%s cannot lookup drawable\n", __func__);
+	radeon_dri2_frame_event_handler(0, 0, 0, data);
+	return 0;
+    }
+    screen = drawable->pScreen;
+    scrn = xf86ScreenToScrn(screen);
+    info = RADEONPTR(scrn);
+    ret = drmmode_get_current_ust(info->dri2.drm_fd, &drm_now);
+    if (ret) {
+	xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+		   "%s cannot get current time\n", __func__);
+	radeon_dri2_frame_event_handler(0, 0, 0, data);
+	return 0;
+    }
+    tv_sec = (unsigned int)(drm_now / 1000000);
+    tv_usec = (unsigned int)(drm_now - (CARD64)tv_sec * 1000000);
+    /*
+     * calculate the frame number from current time
+     * that would come from CRTC if it were running
+     */
+    drmmode_crtc = event_info->crtc->driver_private;
+    delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust;
+    delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
+    delta_seq /= 1000000;
+    frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq;
+    frame &= 0xffffffff;
+    radeon_dri2_frame_event_handler((unsigned int)frame, tv_sec, tv_usec, data);
+    return 0;
+}
+
 /*
  * Request a DRM event when the requested conditions will be satisfied.
  *
@@ -1178,14 +1239,6 @@ void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
     free(flip);
 }
 
-static
-CARD32 radeon_dri2_deferred_swap(OsTimerPtr timer, CARD32 now, pointer data)
-{
-    TimerFree(timer);
-    radeon_dri2_frame_event_handler(0, 0, 0, data);
-    return 0;
-}
-
 /*
  * ScheduleSwap is responsible for requesting a DRM vblank event for the
  * appropriate frame.
@@ -1271,7 +1324,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc,
 						  divisor, remainder);
 	swap_info->frame = *target_msc;
-	TimerSet(NULL, 0, delay, radeon_dri2_deferred_swap, swap_info);
+	TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, swap_info);
 	return TRUE;
     }
 
@@ -1284,7 +1337,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "first get vblank counter failed: %s\n",
                 strerror(errno));
-	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
 		 swap_info);
 	*target_msc = 0;
 	return TRUE;
@@ -1338,7 +1391,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
             xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                     "divisor 0 get vblank counter failed: %s\n",
                     strerror(errno));
-	    TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+	    TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
 		     swap_info);
 	    *target_msc = 0;
             return TRUE;
@@ -1388,7 +1441,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "final get vblank counter failed: %s\n",
                 strerror(errno));
-	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
 		 swap_info);
 	*target_msc = 0;
 	return TRUE;
commit 84bce7943b735aee19e26be4d47fdf140564f3f5
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:44 2013 -0400

    DRI2: track CRTC in event record
    
    Tracking the CRTC associated with an event will save us
    some lookups later in event handlers.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index c6f271e..7d3b16a 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -501,6 +501,7 @@ typedef struct _DRI2FrameEvent {
     ClientPtr client;
     enum DRI2FrameEventType type;
     int frame;
+    xf86CrtcPtr crtc;
 
     /* for swaps & flips only */
     DRI2SwapEventPtr event_complete;
@@ -648,6 +649,7 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
     flip_info->event_complete = func;
     flip_info->event_data = data;
     flip_info->frame = target_msc;
+    flip_info->crtc = crtc;
 
     xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info);
@@ -1024,6 +1026,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     wait_info->client = client;
     wait_info->type = DRI2_WAITMSC;
     wait_info->valid = TRUE;
+    wait_info->crtc = crtc;
 
     if (ListAddDRI2ClientEvents(client, &wait_info->link)) {
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1249,6 +1252,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     swap_info->front = front;
     swap_info->back = back;
     swap_info->valid = TRUE;
+    swap_info->crtc = crtc;
     if (ListAddDRI2ClientEvents(client, &swap_info->link)) {
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "add events to client private failed.\n");
commit e40d5390b3efdea3e02267413350410d8e6a2970
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:43 2013 -0400

    DRI2: hook up vblank extrapolation to schedule_swap
    
    This patch hooks up swap-scheduling function with
    vblank-extrapolation function. Rather than waiting for
    fixed time, we calculate exactly how much we should wait
    and what we should update target_msc to using
    radeon_dri2_extrapolate_msc_delay helper function
    and schedule the swap completion using DIX's timer facility.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index d113486..c6f271e 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -1258,14 +1258,16 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     }
 
     /*
-     * CRTC is in DPMS off state, fallback to blit, but pace the
-     * application at the rate that roughly approximates the
-     * nominal frame rate of the relevant CRTC
+     * CRTC is in DPMS off state, fallback to blit, but calculate
+     * wait time from current time, target_msc and last vblank
+     * time/sequence when CRTC was turned off
      */
     if (!radeon_crtc_is_enabled(crtc)) {
-	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
-		 swap_info);
-	*target_msc = 0;
+	CARD32 delay;
+	delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc,
+						  divisor, remainder);
+	swap_info->frame = *target_msc;
+	TimerSet(NULL, 0, delay, radeon_dri2_deferred_swap, swap_info);
 	return TRUE;
     }
 
commit ffaa5abf207415159cdb28e90da49b95f497ef61
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:42 2013 -0400

    DRI2: add vblank extrapolation function
    
    Implement a helper function that will be called when emulating
    the running CRTC. The function should be called only when CRTC
    is in DPMS-off state. It will look at the vblank count and the
    time that was recorded last time the CRTC was running and
    calculate how long one must wait (from present time) until
    the target_msc is reached if the CRTC were running.
    
    v2: - CRTC-private now stores frame rate instead of nominal
          vblank period.
        - DIX's timer facility can sometimes wake up the scheduled
          functions more than a millisecond earlier. To avoid
          generating an old MSC, we have to add more margin when
          converting the delay in microseconds to milliseconds.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index cd2be2b..d113486 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -875,6 +875,82 @@ drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc)
 }
 
 /*
+ * This function should be called on a disabled CRTC only (i.e., CRTC
+ * in DPMS-off state). It will calculate the delay necessary to reach
+ * target_msc from present time if the CRTC were running.
+ */
+static
+CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc,
+					 CARD64 divisor, CARD64 remainder)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    int nominal_frame_rate = drmmode_crtc->dpms_last_fps;
+    CARD64 last_vblank_ust = drmmode_crtc->dpms_last_ust;
+    int last_vblank_seq = drmmode_crtc->dpms_last_seq;
+    int interpolated_vblanks = drmmode_crtc->interpolated_vblanks;
+    int target_seq;
+    CARD64 now, target_time, delta_t;
+    int64_t d, delta_seq;
+    int ret;
+    CARD32 d_ms;
+
+    if (!last_vblank_ust) {
+	*target_msc = 0;
+	return FALLBACK_SWAP_DELAY;
+    }
+    ret = drmmode_get_current_ust(info->dri2.drm_fd, &now);
+    if (ret) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "%s cannot get current time\n", __func__);
+	*target_msc = 0;
+	return FALLBACK_SWAP_DELAY;
+    }
+    target_seq = (int)*target_msc - interpolated_vblanks;
+    delta_seq = (int64_t)target_seq - (int64_t)last_vblank_seq;
+    delta_seq *= 1000000;
+    target_time = last_vblank_ust;
+    target_time += delta_seq / nominal_frame_rate;
+    d = target_time - now;
+    if (d < 0) {
+	/* we missed the event, adjust target_msc, do the divisor magic */
+	CARD64 current_msc;
+	current_msc = last_vblank_seq + interpolated_vblanks;
+	delta_t = now - last_vblank_ust;
+	delta_seq = delta_t * nominal_frame_rate;
+	current_msc += delta_seq / 1000000;
+	current_msc &= 0xffffffff;
+	if (divisor == 0) {
+	    *target_msc = current_msc;
+	    d = 0;
+	} else {
+	    *target_msc = current_msc - (current_msc % divisor) + remainder;
+	    if ((current_msc % divisor) >= remainder)
+		*target_msc += divisor;
+	    *target_msc &= 0xffffffff;
+	    target_seq = (int)*target_msc - interpolated_vblanks;
+	    delta_seq = (int64_t)target_seq - (int64_t)last_vblank_seq;
+	    delta_seq *= 1000000;
+	    target_time = last_vblank_ust;
+	    target_time += delta_seq / nominal_frame_rate;
+	    d = target_time - now;
+	}
+    }
+    /*
+     * convert delay to milliseconds and add margin to prevent the client
+     * from coming back early (due to timer granularity and rounding
+     * errors) and getting the same MSC it just got
+     */
+    d_ms = (CARD32)d / 1000;
+    if ((CARD32)d - d_ms * 1000 > 0)
+	d_ms += 2;
+    else
+	d_ms++;
+    return d_ms;
+}
+
+/*
  * Get current frame count and frame count timestamp, based on drawable's
  * crtc.
  */
commit 80ae2291d082b57c70d27a80182f00d760fb3d3a
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:41 2013 -0400

    DRI2: adjust MSC by the number of interpolated vblanks
    
    Normally, MSC value equals the vblank count of the CRTC
    on which the drawable resides. However, we are now interpolating
    vblanks through DPMS-off state, so if the CRTC is turned
    off at some point, the vlbank count does not change, but
    MSC does change by the amount that equals the cumulative
    number of interpolated vblanks.
    
    So each time we interact with the CRTC's vblank facility,
    we have to adjust the vblank counter: in the request, we
    have to subtract the number of interpolated vblanks from
    MSC and in the reply we have to add the number of interpolated
    vblanks to the MSC.
    
    This patch only makes the MSC correct when CRTC is on.
    The subsequent patch will construct the MSC when CRTC is not
    running.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 10ea0f7..cd2be2b 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -905,7 +905,8 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
     }
 
     *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
-    *msc = vbl.reply.sequence;
+    *msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
+    *msc &= 0xffffffff;
 
     return TRUE;
 }
@@ -967,7 +968,8 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         goto out_complete;
     }
 
-    current_msc = vbl.reply.sequence;
+    current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
+    current_msc &= 0xffffffff;
 
     /*
      * If divisor is zero, or current_msc is smaller than target_msc,
@@ -986,6 +988,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
 	vbl.request.type |= radeon_populate_vbl_request_type(crtc);
         vbl.request.sequence = target_msc;
+	vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc);
         vbl.request.signal = (unsigned long)wait_info;
         ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
         if (ret) {
@@ -995,6 +998,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         }
 
         wait_info->frame = vbl.reply.sequence;
+	wait_info->frame += radeon_get_interpolated_vblanks(crtc);
         DRI2BlockClient(client, draw);
         return TRUE;
     }
@@ -1017,6 +1021,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
      */
     if ((current_msc % divisor) >= remainder)
         vbl.request.sequence += divisor;
+    vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc);
 
     vbl.request.signal = (unsigned long)wait_info;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -1027,6 +1032,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     }
 
     wait_info->frame = vbl.reply.sequence;
+    wait_info->frame += radeon_get_interpolated_vblanks(crtc);
     DRI2BlockClient(client, draw);
 
     return TRUE;
@@ -1202,7 +1208,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 	return TRUE;
     }
 
-    current_msc = vbl.reply.sequence;
+    current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc);
+    current_msc &= 0xffffffff;
 
     /* Flips need to be submitted one frame before */
     if (can_flip(scrn, draw, front, back)) {
@@ -1242,6 +1249,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
             *target_msc = current_msc;
 
         vbl.request.sequence = *target_msc;
+	vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc);
         vbl.request.signal = (unsigned long)swap_info;
         ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
         if (ret) {
@@ -1255,6 +1263,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         }
 
         *target_msc = vbl.reply.sequence + flip;
+	*target_msc += radeon_get_interpolated_vblanks(crtc);
         swap_info->frame = *target_msc;
 
         return TRUE;
@@ -1286,6 +1295,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
      */
     if (vbl.request.sequence <= current_msc)
         vbl.request.sequence += divisor;
+    vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc);
 
     /* Account for 1 frame extra pageflip delay if flip > 0 */
     vbl.request.sequence -= flip;
@@ -1304,6 +1314,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 
     /* Adjust returned value for 1 fame pageflip offset of flip > 0 */
     *target_msc = vbl.reply.sequence + flip;
+    *target_msc += radeon_get_interpolated_vblanks(crtc);
     swap_info->frame = *target_msc;
 
     return TRUE;
diff --git a/src/radeon_video.c b/src/radeon_video.c
index c050528..56cd9ab 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -73,6 +73,12 @@ Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc)
     return drmmode_crtc->dpms_mode == DPMSModeOn;
 }
 
+uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+    return drmmode_crtc->interpolated_vblanks;
+}
+
 xf86CrtcPtr
 radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
 		      int x1, int x2, int y1, int y2)
diff --git a/src/radeon_video.h b/src/radeon_video.h
index e6068e8..2a09295 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -101,5 +101,6 @@ RADEONCopyMungedData(ScrnInfoPtr pScrn,
 		     unsigned int dstPitch, unsigned int h, unsigned int w);
 
 Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc);
+uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc);
 
 #endif
commit 5fd2eb5d12cea32927a9e6c6ce4afd18aa7d046a
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:40 2013 -0400

    drmmode: calculate interpolated vblanks while in dpms-off state
    
    This adds provisions for interpolating vblanks while the CRTC
    is in DPMS-off state. When entering DPMS-off state, we
    record the last vblank time, sequence number and frame rate
    in CRTC-private structure.
    
    When going back to DPMS-on state we read the current
    time and calculate how long we have been off. Then we derive
    how many vblanks that would have been had the CRTC remained
    running. These are the interpolated vblanks.
    
    Finally, we accumulate the number of interpolated vblanks
    in CRTC-private structure to get the number of interpolated
    vblanks over the system lifetime.
    
    v2: Track frame rate instead of vblank period. The former
        eliminates some roundoff errors.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 658747c..cd276f3 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -49,6 +49,8 @@
 #include <X11/extensions/dpms.h>
 #endif
 
+#define DEFAULT_NOMINAL_FRAME_RATE 60
+
 static Bool
 RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name)
 {
@@ -245,7 +247,61 @@ static void
 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	ScrnInfoPtr scrn = crtc->scrn;
+	RADEONInfoPtr info = RADEONPTR(scrn);
+	CARD64 ust;
+	int ret;
+
+	if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) {
+		drmVBlank vbl;
+
+		/*
+		 * On->Off transition: record the last vblank time,
+		 * sequence number and frame period.
+		 */
+		vbl.request.type = DRM_VBLANK_RELATIVE;
+		vbl.request.type |= radeon_populate_vbl_request_type(crtc);
+		vbl.request.sequence = 0;
+		ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
+		if (ret)
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				   "%s cannot get last vblank counter\n",
+				   __func__);
+		else {
+			CARD64 seq = (CARD64)vbl.reply.sequence;
+			CARD64 nominal_frame_rate, pix_in_frame;
+
+			ust = ((CARD64)vbl.reply.tval_sec * 1000000) +
+				vbl.reply.tval_usec;
+			drmmode_crtc->dpms_last_ust = ust;
+			drmmode_crtc->dpms_last_seq = seq;
+			nominal_frame_rate = crtc->mode.Clock;
+			nominal_frame_rate *= 1000;
+			pix_in_frame = crtc->mode.HTotal * crtc->mode.VTotal;
+			if (nominal_frame_rate == 0 || pix_in_frame == 0)
+				nominal_frame_rate = DEFAULT_NOMINAL_FRAME_RATE;
+			else
+				nominal_frame_rate /= pix_in_frame;
+			drmmode_crtc->dpms_last_fps = nominal_frame_rate;
+		}
+	} else if (drmmode_crtc->dpms_mode != DPMSModeOn && mode == DPMSModeOn) {
+		/*
+		 * Off->On transition: calculate and accumulate the
+		 * number of interpolated vblanks while we were in Off state
+		 */
+		ret = drmmode_get_current_ust(info->dri2.drm_fd, &ust);
+		if (ret)
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				   "%s cannot get current time\n", __func__);
+		else if (drmmode_crtc->dpms_last_ust) {
+			CARD64 time_elapsed, delta_seq;
+			time_elapsed = ust - drmmode_crtc->dpms_last_ust;
+			delta_seq = time_elapsed * drmmode_crtc->dpms_last_fps;
+			delta_seq /= 1000000;
+			drmmode_crtc->interpolated_vblanks += delta_seq;
 
+		}
+	}
 	drmmode_crtc->dpms_mode = mode;
 }
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index add2ee4..2fccfda 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -76,6 +76,10 @@ typedef struct {
     struct radeon_bo *rotate_bo;
     unsigned rotate_fb_id;
     int dpms_mode;
+    CARD64 dpms_last_ust;
+    uint32_t dpms_last_seq;
+    int dpms_last_fps;
+    uint32_t interpolated_vblanks;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
commit e41ad30d09be4962cfb1942b0b9f63875dbb2d2a
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:39 2013 -0400

    drmmode: remove dead code from drmmode_crtc_dpms
    
    We are about to modify this function, so let's clean it
    up first.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 5db58da..658747c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -245,17 +245,8 @@ static void
 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-//	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
 	drmmode_crtc->dpms_mode = mode;
-
-#if 0
-	/* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
-	if (mode == DPMSModeOff) {
-//		drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-//			       0, 0, 0, NULL, 0, NULL);
-	}
-#endif
 }
 
 static PixmapPtr
commit 373671d2eed30e30b3bdee7e40426cf58c127234
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:38 2013 -0400

    drmmode: add drmmode_get_current_ust function
    
    The new helper function retrieves current time in the format
    that is compatible with vblank timestamps.
    
    v2: - fix an incorrect statement in a comment
        - add a #define so that don't depend on libdrm patches that
          have not yet been accepted upstream
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 13e65fa..5db58da 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -31,6 +31,7 @@
 
 #include <errno.h>
 #include <sys/ioctl.h>
+#include <time.h>
 #include "micmap.h"
 #include "xf86cmap.h"
 #include "radeon.h"
@@ -216,6 +217,30 @@ drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
 
 }
 
+/*
+ * Retrieves present time in microseconds that is compatible
+ * with units used by vblank timestamps. Depending on the kernel
+ * version and DRM kernel module configuration, the vblank
+ * timestamp can either be in real time or monotonic time
+ */
+int drmmode_get_current_ust(int drm_fd, CARD64 *ust)
+{
+	uint64_t cap_value;
+	int ret;
+	struct timespec now;
+
+	ret = drmGetCap(drm_fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap_value);
+	if (ret || !cap_value)
+		/* old kernel or drm_timestamp_monotonic turned off */
+		ret = clock_gettime(CLOCK_REALTIME, &now);
+	else
+		ret = clock_gettime(CLOCK_MONOTONIC, &now);
+	if (ret)
+		return ret;
+	*ust = ((CARD64)now.tv_sec * 1000000) + ((CARD64)now.tv_nsec / 1000);
+	return 0;
+}
+
 static void
 drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index b63ec8e..add2ee4 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -34,6 +34,10 @@
 
 #include "radeon_probe.h"
 
+#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
+#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
+#endif
+
 typedef struct {
   int fd;
   unsigned fb_id;
@@ -115,6 +119,7 @@ extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
 extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
 
 Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id);
+int drmmode_get_current_ust(int drm_fd, CARD64 *ust);
 
 #endif
 
commit 006fbbd1d38a089b50ab3197d32815689ed249fa
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:37 2013 -0400

    DRI2: make populate_vbl_request_type external
    
    We'll need to use this function in other .c files so
    remove static annotation from it. Also, add radeon_
    prefix because this function is now part of global namespace,
    so it would be nice to know where it is coming from.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon.h b/src/radeon.h
index 8dc3d12..77fdd6e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -518,6 +518,8 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
 				const char *func, int line);
 void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size);
 
+drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc);
+
 #if XF86_CRTC_VERSION >= 5
 #define RADEON_PIXMAP_SHARING 1
 #endif
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 8c4be4c..10ea0f7 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -854,7 +854,7 @@ cleanup:
     free(event);
 }
 
-static drmVBlankSeqType populate_vbl_request_type(xf86CrtcPtr crtc)
+drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc)
 {
     drmVBlankSeqType type = 0;
     int crtc_id = drmmode_get_crtc_id(crtc);
@@ -894,7 +894,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
         return TRUE;
     }
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(crtc);
+    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
 
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -958,7 +958,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(crtc);
+    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -984,7 +984,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         if (current_msc >= target_msc)
             target_msc = current_msc;
         vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-	vbl.request.type |= populate_vbl_request_type(crtc);
+	vbl.request.type |= radeon_populate_vbl_request_type(crtc);
         vbl.request.sequence = target_msc;
         vbl.request.signal = (unsigned long)wait_info;
         ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -1004,7 +1004,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
      * so we queue an event that will satisfy the divisor/remainder equation.
      */
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-    vbl.request.type |= populate_vbl_request_type(crtc);
+    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
 
     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;
@@ -1189,7 +1189,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(crtc);
+    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -1232,7 +1232,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
          */
         if (flip == 0)
             vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-	vbl.request.type |= populate_vbl_request_type(crtc);
+	vbl.request.type |= radeon_populate_vbl_request_type(crtc);
 
         /* If target_msc already reached or passed, set it to
          * current_msc to ensure we return a reasonable value back
@@ -1268,7 +1268,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
     if (flip == 0)
         vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-    vbl.request.type |= populate_vbl_request_type(crtc);
+    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
 
     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;
commit 34660d8757ff16acd1686ff2872f4600d92a68bf
Author: Ilija Hadzic <ilijahadzic at gmail.com>
Date:   Wed May 8 22:39:36 2013 -0400

    DRI2: change signature of populate_vbl_request_type
    
    This function no longer uses info argument, so nuke it.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 443d908..8c4be4c 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -854,8 +854,7 @@ cleanup:
     free(event);
 }
 
-static
-drmVBlankSeqType populate_vbl_request_type(RADEONInfoPtr info, xf86CrtcPtr crtc)
+static drmVBlankSeqType populate_vbl_request_type(xf86CrtcPtr crtc)
 {
     drmVBlankSeqType type = 0;
     int crtc_id = drmmode_get_crtc_id(crtc);
@@ -895,7 +894,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
         return TRUE;
     }
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(info, crtc);
+    vbl.request.type |= populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
 
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -959,7 +958,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
 
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(info, crtc);
+    vbl.request.type |= populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -985,7 +984,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         if (current_msc >= target_msc)
             target_msc = current_msc;
         vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-	vbl.request.type |= populate_vbl_request_type(info, crtc);
+	vbl.request.type |= populate_vbl_request_type(crtc);
         vbl.request.sequence = target_msc;
         vbl.request.signal = (unsigned long)wait_info;
         ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -1005,7 +1004,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
      * so we queue an event that will satisfy the divisor/remainder equation.
      */
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-    vbl.request.type |= populate_vbl_request_type(info, crtc);
+    vbl.request.type |= populate_vbl_request_type(crtc);
 
     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;
@@ -1190,7 +1189,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    vbl.request.type |= populate_vbl_request_type(info, crtc);
+    vbl.request.type |= populate_vbl_request_type(crtc);
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -1233,7 +1232,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
          */
         if (flip == 0)
             vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-	vbl.request.type |= populate_vbl_request_type(info, crtc);
+	vbl.request.type |= populate_vbl_request_type(crtc);
 
         /* If target_msc already reached or passed, set it to
          * current_msc to ensure we return a reasonable value back
@@ -1269,7 +1268,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
     if (flip == 0)
         vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-    vbl.request.type |= populate_vbl_request_type(info, crtc);
+    vbl.request.type |= populate_vbl_request_type(crtc);
 
     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;


More information about the xorg-commit mailing list