+ extraFramesDropped = 0;
+
+ if (timeToSleepUntil == 0)
+ {
+ // If this is the first frame after the thread is initialized or resumed, we
+ // use the actual time the current frame starts from to calculate the time to
+ // sleep until the next frame.
+ timeToSleepUntil = currentFrameStartTime + mDefaultFrameDurationNanoseconds;
+ }
+ else
+ {
+ // Otherwise, always use the sleep-until time calculated in the last frame to
+ // calculate the time to sleep until the next frame. In this way, if there is
+ // any time gap between the current frame and the next frame, or if update or
+ // rendering in the current frame takes too much time so that the specified
+ // sleep-until time has already passed, it will try to keep the frames syncing
+ // by shortening the duration of the next frame.
+ timeToSleepUntil += mDefaultFrameDurationNanoseconds;
+
+ // Check the current time at the end of the frame
+ uint64_t currentFrameEndTime = 0;
+ TimeService::GetNanoseconds( currentFrameEndTime );
+ while ( currentFrameEndTime > timeToSleepUntil + mDefaultFrameDurationNanoseconds )
+ {
+ // We are more than one frame behind already, so just drop the next frames
+ // until the sleep-until time is later than the current time so that we can
+ // catch up.
+ timeToSleepUntil += mDefaultFrameDurationNanoseconds;
+ extraFramesDropped++;
+ }
+ }
+