fix the wrong operation of SW timer 22/89522/1
authorBoram Park <boram1288.park@samsung.com>
Mon, 26 Sep 2016 02:13:13 +0000 (11:13 +0900)
committerBoram Park <boram1288.park@samsung.com>
Mon, 26 Sep 2016 02:13:17 +0000 (11:13 +0900)
skip variable should be unsigned int to correct the prev time

Change-Id: Iea57ca5fbe7783c2b50cad6435d35f1fee0ba9f5

src/tdm_vblank.c

index 6696d78..8dc85e5 100644 (file)
@@ -575,15 +575,26 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence,
                VWR("couldn't update sw timer");
        }
 
-       if (tdm_debug_module & TDM_DEBUG_VBLANK)
-               VIN("wait(%p) sequence(%u) done", wait_info, wait_info->target_seq);
-
        if (private_vblank->last_seq >= wait_info->target_seq)
                TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, wait_info->target_seq);
 
+       /* tv_sec & tv_usec shouldn't be zero. But sometimes they are zero in some hardware.
+        * We need to prohibit that last_time becomes zero because "last_time == 0" means
+        * that a tdm_vblank object is just created and doesn't have the first vblank event.
+        * If last_time becomes 0, it would make issue.
+        */
+       if (tv_sec == 0 && tv_usec == 0) {
+               double curr = tdm_helper_get_time();
+               tv_sec = TDM_TIME_SEC(curr);
+               tv_usec = TDM_TIME_USEC(curr);
+       }
+
        private_vblank->last_seq = wait_info->target_seq;
        private_vblank->last_time = TDM_TIME(tv_sec, tv_usec);
 
+       if (tdm_debug_module & TDM_DEBUG_VBLANK)
+               VIN("wait(%p) last(%.6f) sequence(%u) done", wait_info, private_vblank->last_time, wait_info->target_seq);
+
        if (wait_info->func)
                wait_info->func(private_vblank, TDM_ERROR_NONE, wait_info->target_seq,
                                                tv_sec, tv_usec, wait_info->user_data);
@@ -612,15 +623,16 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info)
                /* +1 ms to call the handler ASAP at the first. no matter for SW timer. */
                wait_info->target_seq = 1;
                if (tdm_debug_module & TDM_DEBUG_VBLANK)
-                       VIN("wait(%p) last(%.6f) hw_interval(%d) target sequence(%u)",
+                       VIN("wait(%p) last(%.6f) hw_itvl(%d) targ_seq(%u)",
                                wait_info, private_vblank->last_time, hw_interval, wait_info->target_seq);
        } else {
-               double last, prev, req, curr, target, skip;
+               double last, prev, req, curr, target;
+               unsigned int skip;
 
                last = private_vblank->last_time;
                req = wait_info->req_time;
 
-               skip = (req - last) / private_vblank->vblank_gap;
+               skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
                prev = last + private_vblank->vblank_gap * skip;
 
                curr = tdm_helper_get_time();
@@ -634,12 +646,12 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info)
                wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
 
                if (hw_interval > 300)
-                       VER("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)",
-                               wait_info, last, req - last, prev - last, curr - last, target - last,
+                       VER("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) hw_itvl(%d) targ_seq(%u)",
+                               wait_info, last, req - last, prev - last, curr - last, target, target - last,
                                skip, hw_interval, wait_info->target_seq);
                else if (tdm_debug_module & TDM_DEBUG_VBLANK)
-                       VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f) skip(%.0f) hw_interval(%d) target_seq(%u)",
-                               wait_info, last, req - last, prev - last, curr - last, target - last,
+                       VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) hw_itvl(%d) targ_seq(%u)",
+                               wait_info, last, req - last, prev - last, curr - last, target, target - last,
                                skip, hw_interval, wait_info->target_seq);
        }
 
@@ -708,15 +720,15 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp)
        first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link);
        TDM_RETURN_VAL_IF_FAIL(first_wait_info != NULL, TDM_ERROR_OPERATION_FAILED);
 
-       if (tdm_debug_module & TDM_DEBUG_VBLANK)
-               VIN("wait(%p) sequence(%u) done", first_wait_info, first_wait_info->target_seq);
-
        if (private_vblank->last_seq >= first_wait_info->target_seq)
                TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, first_wait_info->target_seq);
 
        private_vblank->last_seq = first_wait_info->target_seq;
        private_vblank->last_time = first_wait_info->target_time;
 
+       if (tdm_debug_module & TDM_DEBUG_VBLANK)
+               VIN("wait(%p) last(%.6f) sequence(%u) done", first_wait_info, private_vblank->last_time, first_wait_info->target_seq);
+
        LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) {
                if (w->target_time != first_wait_info->target_time)
                        break;
@@ -757,12 +769,13 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info)
                        VIN("wait(%p) last(%.6f) target(%.6f) target sequence(%u)",
                                wait_info, private_vblank->last_time, wait_info->target_time, wait_info->target_seq);
        } else {
-               double last, prev, req, curr, target, skip;
+               double last, prev, req, curr, target;
+               unsigned int skip;
 
                last = private_vblank->last_time;
                req = wait_info->req_time;
 
-               skip = (req - last) / private_vblank->vblank_gap;
+               skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
                prev = last + private_vblank->vblank_gap * skip;
 
                curr = tdm_helper_get_time();
@@ -777,9 +790,9 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info)
                wait_info->target_time = target;
 
                if (tdm_debug_module & TDM_DEBUG_VBLANK)
-                       VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) target(%.6f,%.6f) target sequence(%u)",
+                       VIN("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) targ_seq(%u)",
                                wait_info, last, req - last, prev - last, curr - last,
-                               target, target - last, wait_info->target_seq);
+                               target, target - last, skip, wait_info->target_seq);
        }
 
        _tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list);