The problem was found in hwcomposer HAL. A nanosleep in vsync thread was too long, causing ioctl MXCFB_WAIT_FOR_VSYNC to sometimes miss first vsync (NF-ACK from IPU), and instead wait for second vsync, causing time to wait for vsync to double.
diff --git a/mx6/hwcomposer/hwc_vsync.cpp b/mx6/hwcomposer/hwc_vsync.cpp
index fc6b9bf..8fec0a6 100644
--- a/mx6/hwcomposer/hwc_vsync.cpp
+++ b/mx6/hwcomposer/hwc_vsync.cpp
@@ -125,7 +125,7 @@ void VSyncThread::performVSync()
struct timespec tm;
struct timespec ts;
- const nsecs_t wake_up = 400000;
+ const nsecs_t wake_up = 800000; // Allow for some time to reschedule this thread and start wait on next VSYNC ioctl
double m_frame_period_ns = mCtx->mDispInfo[HWC_DISPLAY_PRIMARY].vsync_period;