[PATCH 06/11] DRI2: adjust MSC by the number of interpolated vblanks

Ilija Hadzic ilijahadzic at gmail.com
Sun Apr 28 13:07:51 PDT 2013


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>
---
 src/radeon_dri2.c  | 17 ++++++++++++++---
 src/radeon_video.c |  6 ++++++
 src/radeon_video.h |  1 +
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 78d069b..8247e37 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -902,7 +902,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;
 }
@@ -964,7 +965,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,
@@ -983,6 +985,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) {
@@ -992,6 +995,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;
     }
@@ -1014,6 +1018,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);
@@ -1024,6 +1029,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;
@@ -1199,7 +1205,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)) {
@@ -1239,6 +1246,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) {
@@ -1252,6 +1260,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;
@@ -1283,6 +1292,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;
@@ -1301,6 +1311,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
-- 
1.8.1.5



More information about the xorg-driver-ati mailing list