[PATCH xf86-video-intel 1/2] Fix I830DRI2ScheduleWaitMSC() to correctly handle target_msc, divisor and remainder.

Mario Kleiner mario.kleiner at tuebingen.mpg.de
Sun Feb 21 09:45:47 PST 2010


Previous code only handled divisor == 0 case correctly. This should
honor a given target_msc for the divisor > 0 case and handle the
(msc % divisor) == remainder constraint correctly.

Signed-off-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
---
 src/i830_dri.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/i830_dri.c b/src/i830_dri.c
index e1c1470..d5e085a 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -756,6 +756,7 @@ I830DRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
     DRI2FrameEventPtr wait_info;
     drmVBlank vbl;
     int ret, pipe = I830DRI2DrawablePipe(draw);
+    CARD64 current_msc;
 
     /* Drawable not visible, return immediately */
     if (pipe == -1) {
@@ -785,11 +786,13 @@ I830DRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
 	return FALSE;
     }
 
+    current_msc = vbl.reply.sequence;
+
     /*
-     * If divisor is zero, we just need to make sure target_msc passes
-     * before waking up the client.
+     * If divisor is zero, or current_msc is smaller than target_msc,
+     * we just need to make sure target_msc passes before waking up the client.
      */
-    if (divisor == 0) {
+    if (divisor == 0 || current_msc < target_msc) {
 	vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
 	if (pipe > 0)
 	    vbl.request.type |= DRM_VBLANK_SECONDARY;
@@ -815,16 +818,16 @@ I830DRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
     if (pipe > 0)
 	vbl.request.type |= DRM_VBLANK_SECONDARY;
 
+    vbl.request.sequence = current_msc - (current_msc % divisor) + remainder;
+
     /*
-     * If we have no remainder and the condition isn't satisified, it means
+     * If calculated remainder is larger than requested remainder, it means
      * we've passed the last point where seq % divisor == remainder, so we need
      * to wait for the next time that will happen.
      */
-    if (((vbl.reply.sequence % divisor) != remainder) && !remainder)
-	vbl.request.sequence += divisor;
+    if ((current_msc % divisor) > remainder)
+       vbl.request.sequence += divisor;
 
-    vbl.request.sequence = vbl.reply.sequence - (vbl.reply.sequence % divisor) +
-	remainder;
     vbl.request.signal = (unsigned long)wait_info;
     ret = drmWaitVBlank(intel->drmSubFD, &vbl);
     if (ret) {
-- 
1.6.6



More information about the xorg-devel mailing list