namespace
{
constexpr auto LOOP_FOREVER = -1;
-constexpr auto NANOSECONDS_PER_SECOND(1e+9);
+constexpr auto MICROSECONDS_PER_SECOND(1e+6);
#if defined(DEBUG_ENABLED)
Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_VECTOR_ANIMATION");
mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
mLoopingMode(DevelImageVisual::LoopingMode::RESTART),
mNextFrameStartTime(),
- mFrameDurationNanoSeconds(0),
+ mFrameDurationMicroSeconds(MICROSECONDS_PER_SECOND / 60.0f),
mFrameRate(60.0f),
mCurrentFrame(0),
mTotalFrame(0),
mStartFrame(0),
mEndFrame(0),
+ mDroppedFrames(0),
mWidth(0),
mHeight(0),
mAnimationDataIndex(0),
mEndFrame = mTotalFrame - 1;
- mFrameRate = mVectorRenderer.GetFrameRate();
- mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate;
+ mFrameRate = mVectorRenderer.GetFrameRate();
+ mFrameDurationMicroSeconds = MICROSECONDS_PER_SECOND / mFrameRate;
uint32_t width, height;
mVectorRenderer.GetDefaultSize(width, height);
std::string marker;
if(playRange.GetElementAt(0).Get(marker))
{
- if(mVectorRenderer)
+ if(mVectorRenderer && mVectorRenderer.GetMarkerInfo(marker, startFrame, endFrame))
{
- mVectorRenderer.GetMarkerInfo(marker, startFrame, endFrame);
valid = true;
}
}
if(mPlayState == PlayState::PLAYING && mUpdateFrameNumber)
{
- mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1;
+ mCurrentFrame = mForward ? mCurrentFrame + mDroppedFrames + 1 : mCurrentFrame - mDroppedFrames - 1;
Dali::ClampInPlace(mCurrentFrame, mStartFrame, mEndFrame);
}
return frame;
}
-std::chrono::time_point<std::chrono::system_clock> VectorAnimationTask::CalculateNextFrameTime(bool renderNow)
+VectorAnimationTask::TimePoint VectorAnimationTask::CalculateNextFrameTime(bool renderNow)
{
- // std::chrono::time_point template has second parameter duration which defaults to the std::chrono::system_clock supported
+ // std::chrono::time_point template has second parameter duration which defaults to the std::chrono::steady_clock supported
// duration. In some C++11 implementations it is a milliseconds duration, so it fails to compile unless mNextFrameStartTime
// is casted to use the default duration.
- mNextFrameStartTime = std::chrono::time_point_cast<std::chrono::time_point<std::chrono::system_clock>::duration>(
- mNextFrameStartTime + std::chrono::nanoseconds(mFrameDurationNanoSeconds));
- auto current = std::chrono::system_clock::now();
- if(renderNow || mNextFrameStartTime < current)
+ mNextFrameStartTime = std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds));
+ auto current = std::chrono::steady_clock::now();
+ mDroppedFrames = 0;
+
+ if(renderNow)
{
mNextFrameStartTime = current;
}
+ else if(mNextFrameStartTime < current)
+ {
+ uint32_t droppedFrames = 0;
+
+ while(current > std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds)) && droppedFrames < mTotalFrame)
+ {
+ droppedFrames++;
+ mNextFrameStartTime = std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds));
+ }
+
+ mNextFrameStartTime = current;
+ mDroppedFrames = droppedFrames;
+ }
+
return mNextFrameStartTime;
}
-std::chrono::time_point<std::chrono::system_clock> VectorAnimationTask::GetNextFrameTime()
+VectorAnimationTask::TimePoint VectorAnimationTask::GetNextFrameTime()
{
return mNextFrameStartTime;
}