X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fanimated-vector-image%2Fvector-rasterize-thread.cpp;h=a640b19cccb819063e6c3c40879294a4beca9313;hp=2c393335a7716e34464e6b61144b8cefa9412b72;hb=313392fb575a7b9bf3657d2091adc77adc7eb3ca;hpb=c4473b138fec8355d4b4583a48528f816a8cb42a diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp index 2c39333..a640b19 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp @@ -37,55 +37,20 @@ namespace Internal namespace { -constexpr auto LOOP_FOREVER = -1; -constexpr auto NANOSECONDS_PER_SECOND( 1e+9 ); - #if defined(DEBUG_ENABLED) Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" ); #endif -template< typename T > -inline void ResetValue( bool& updated, T& value, T newValue, ConditionalWait& conditionalWait ) -{ - ConditionalWait::ScopedLock lock( conditionalWait ); - if( !updated ) - { - value = newValue; - updated = true; - } -} - } // unnamed namespace -VectorRasterizeThread::VectorRasterizeThread( const std::string& url ) -: mUrl( url ), - mVectorRenderer(), +VectorRasterizeThread::VectorRasterizeThread() +: mRasterizeTasks(), mConditionalWait(), - mAnimationFinishedTrigger(), - mPlayState( PlayState::STOPPED ), - mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ), - mLoopingMode( DevelImageVisual::LoopingMode::RESTART ), - mFrameDurationNanoSeconds( 0 ), - mFrameRate( 60.0f ), - mCurrentFrame( 0 ), - mTotalFrame( 0 ), - mStartFrame( 0 ), - mEndFrame( 0 ), - mWidth( 0 ), - mHeight( 0 ), - mLoopCount( LOOP_FOREVER ), - mCurrentLoop( 0 ), - mNeedRender( false ), + mCompletedCallback(), mDestroyThread( false ), - mResourceReady( false ), - mCurrentFrameUpdated( false ), - mCurrentLoopUpdated( false ), - mForward( true ), - mUpdateFrameNumber( false ), - mNeedAnimationFinishedTrigger( true ), + mIsThreadStarted( false ), mLogFactory( Dali::Adaptor::Get().GetLogFactory() ) { - Initialize(); } VectorRasterizeThread::~VectorRasterizeThread() @@ -102,428 +67,75 @@ VectorRasterizeThread::~VectorRasterizeThread() Join(); } -void VectorRasterizeThread::Run() -{ - SetThreadName( "VectorImageThread" ); - mLogFactory.InstallLogFunction(); - - while( !mDestroyThread ) - { - Rasterize(); - } - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Run: End of thread [%p]\n", this ); -} - -void VectorRasterizeThread::SetRenderer( Renderer renderer ) +void VectorRasterizeThread::SetCompletedCallback( CallbackBase* callback ) { ConditionalWait::ScopedLock lock( mConditionalWait ); - mVectorRenderer.SetRenderer( renderer ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetRenderer [%p]\n", this ); -} - -void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height ) -{ - if( mWidth != width || mHeight != height ) - { - ConditionalWait::ScopedLock lock( mConditionalWait ); - mVectorRenderer.SetSize( width, height ); - - mWidth = width; - mHeight = height; - - mResourceReady = false; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetSize: width = %d, height = %d [%p]\n", width, height, this ); - } + mCompletedCallback = std::unique_ptr< CallbackBase >( callback ); } -void VectorRasterizeThread::PlayAnimation() +void VectorRasterizeThread::AddTask( VectorAnimationTaskPtr task ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - if( mPlayState != PlayState::PLAYING ) + if( !mIsThreadStarted ) { - mNeedRender = true; - mUpdateFrameNumber = false; - mPlayState = PlayState::PLAYING; - mConditionalWait.Notify( lock ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PlayAnimation: Play [%p]\n", this ); + Start(); + mIsThreadStarted = true; } -} -void VectorRasterizeThread::StopAnimation() -{ + // Lock while adding task to the queue ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState != PlayState::STOPPED && mPlayState != PlayState::STOPPING ) - { - mNeedRender = true; - mNeedAnimationFinishedTrigger = false; - mPlayState = PlayState::STOPPING; - mConditionalWait.Notify( lock ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop [%p]\n", this ); - } -} -void VectorRasterizeThread::PauseAnimation() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState == PlayState::PLAYING ) + if( mRasterizeTasks.end() == std::find( mRasterizeTasks.begin(), mRasterizeTasks.end(), task ) ) { - mPlayState = PlayState::PAUSED; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause [%p]\n", this ); - } -} - -void VectorRasterizeThread::RenderFrame() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); + mRasterizeTasks.push_back( task ); - if( !mResourceReady ) - { - mNeedRender = true; + // wake up the animation thread mConditionalWait.Notify( lock ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render [%p]\n", this ); - } -} - -void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* callback ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mAnimationFinishedTrigger = std::unique_ptr< EventThreadCallback >( callback ); -} - -void VectorRasterizeThread::SetLoopCount( int32_t count ) -{ - if( mLoopCount != count ) - { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - mLoopCount = count; - mCurrentLoop = 0; - mCurrentLoopUpdated = true; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetLoopCount: [%d] [%p]\n", count, this ); - } -} - -void VectorRasterizeThread::SetPlayRange( uint32_t startFrame, uint32_t endFrame ) -{ - // Make sure the range specified is between 0 and the total frame number - if( ( startFrame < mTotalFrame ) && ( endFrame < mTotalFrame ) ) - { - // If the range is not in order swap values - if( startFrame > endFrame ) - { - uint32_t temp = startFrame; - startFrame = endFrame; - endFrame = temp; - } - - if( startFrame != mStartFrame || endFrame != mEndFrame ) - { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - mStartFrame = startFrame; - mEndFrame = endFrame; - - // If the current frame is out of the range, change the current frame also. - if( mStartFrame > mCurrentFrame ) - { - mCurrentFrame = mStartFrame; - - mCurrentFrameUpdated = true; - mResourceReady = false; - } - else if( mEndFrame < mCurrentFrame ) - { - mCurrentFrame = mEndFrame; - - mCurrentFrameUpdated = true; - mResourceReady = false; - } - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetPlayRange: [%d, %d] [%p]\n", mStartFrame, mEndFrame, this ); - } - } -} - -DevelImageVisual::PlayState::Type VectorRasterizeThread::GetPlayState() const -{ - DevelImageVisual::PlayState::Type state = DevelImageVisual::PlayState::STOPPED; - - switch( mPlayState ) - { - case PlayState::PLAYING: - { - state = DevelImageVisual::PlayState::PLAYING; - break; - } - case PlayState::PAUSED: - { - state = DevelImageVisual::PlayState::PAUSED; - break; - } - case PlayState::STOPPING: - case PlayState::STOPPED: - { - state = DevelImageVisual::PlayState::STOPPED; - break; - } } - - return state; } -bool VectorRasterizeThread::IsResourceReady() const -{ - return mResourceReady; -} - -void VectorRasterizeThread::SetCurrentFrameNumber( uint32_t frameNumber ) +void VectorRasterizeThread::Run() { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - if( mCurrentFrame == frameNumber ) - { - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetCurrentFrameNumber: Set same frame [%d] [%p]\n", frameNumber, this ); - return; - } - - if( frameNumber >= mStartFrame && frameNumber <= mEndFrame ) - { - mCurrentFrame = frameNumber; - mCurrentFrameUpdated = true; - - mResourceReady = false; + SetThreadName( "VectorRasterizeThread" ); + mLogFactory.InstallLogFunction(); - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetCurrentFrameNumber: frame number = %d [%p]\n", mCurrentFrame, this ); - } - else + while( !mDestroyThread ) { - DALI_LOG_ERROR( "Invalid frame number [%d (%d, %d)]\n", frameNumber, mStartFrame, mEndFrame ); + Rasterize(); } } -uint32_t VectorRasterizeThread::GetCurrentFrameNumber() const -{ - return mCurrentFrame; -} - -uint32_t VectorRasterizeThread::GetTotalFrameNumber() const -{ - return mTotalFrame; -} - -void VectorRasterizeThread::GetDefaultSize( uint32_t& width, uint32_t& height ) const -{ - mVectorRenderer.GetDefaultSize( width, height ); -} - -void VectorRasterizeThread::SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mStopBehavior = stopBehavior; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetStopBehavior: stop behavor = %d [%p]\n", mStopBehavior, this ); -} - -void VectorRasterizeThread::SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mLoopingMode = loopingMode; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetLoopingMode: looping mode = %d [%p]\n", mLoopingMode, this ); -} - -VectorRasterizeThread::UploadCompletedSignalType& VectorRasterizeThread::UploadCompletedSignal() -{ - return mVectorRenderer.UploadCompletedSignal(); -} - -void VectorRasterizeThread::Initialize() -{ - mVectorRenderer = VectorAnimationRenderer::New( mUrl ); - - mTotalFrame = mVectorRenderer.GetTotalFrameNumber(); - - mEndFrame = mTotalFrame - 1; - - mFrameRate = mVectorRenderer.GetFrameRate(); - mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate; - - uint32_t width, height; - mVectorRenderer.GetDefaultSize( width, height ); - - SetSize( width, height ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Initialize: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this ); -} - void VectorRasterizeThread::Rasterize() { - bool stopped = false, needAnimationFinishedTrigger; - uint32_t currentFrame, startFrame, endFrame; - int32_t loopCount, currentLoopCount; - + VectorAnimationTaskPtr nextTask; { + // Lock while popping task out from the queue ConditionalWait::ScopedLock lock( mConditionalWait ); - if( ( mPlayState == PlayState::PAUSED || mPlayState == PlayState::STOPPED ) && !mNeedRender && !mDestroyThread ) + // conditional wait + if( mRasterizeTasks.empty() ) { - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Wait [%p]\n", this ); mConditionalWait.Wait( lock ); } - if( mPlayState == PlayState::PLAYING && mUpdateFrameNumber ) + // pop out the next task from the queue + if( !mRasterizeTasks.empty() ) { - mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1; + std::vector< VectorAnimationTaskPtr >::iterator next = mRasterizeTasks.begin(); + nextTask = *next; + mRasterizeTasks.erase( next ); } - - currentFrame = mCurrentFrame; - startFrame = mStartFrame; - endFrame = mEndFrame; - loopCount = mLoopCount; - currentLoopCount = mCurrentLoop; - needAnimationFinishedTrigger = mNeedAnimationFinishedTrigger; - - mResourceReady = true; - mNeedRender = false; - mCurrentFrameUpdated = false; - mCurrentLoopUpdated = false; - mUpdateFrameNumber = true; - mNeedAnimationFinishedTrigger = true; } - auto currentFrameStartTime = std::chrono::system_clock::now(); - - if( mPlayState == PlayState::STOPPING ) + if( nextTask ) { - currentFrame = GetStoppedFrame( startFrame, endFrame, currentFrame ); - ResetValue( mCurrentFrameUpdated, mCurrentFrame, currentFrame, mConditionalWait ); - - stopped = true; - } - else if( mPlayState == PlayState::PLAYING ) - { - bool animationFinished = false; - - if( currentFrame >= endFrame ) // last frame - { - if( mLoopingMode == DevelImageVisual::LoopingMode::AUTO_REVERSE ) - { - mForward = false; - } - else - { - if( loopCount < 0 || ++currentLoopCount < loopCount ) // repeat forever or before the last loop - { - ResetValue( mCurrentFrameUpdated, mCurrentFrame, startFrame, mConditionalWait ); // If the current frame is changed in the event thread, don't overwrite it. - mUpdateFrameNumber = false; - } - else - { - animationFinished = true; // end of animation - } - ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait ); - } - } - else if( currentFrame == startFrame && !mForward ) // first frame - { - if( loopCount < 0 || ++currentLoopCount < loopCount ) // repeat forever or before the last loop - { - mForward = true; - } - else - { - animationFinished = true; // end of animation - } - ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait ); - } + bool keepAnimation = nextTask->Rasterize(); - if( animationFinished ) + if( mCompletedCallback ) { - if( mStopBehavior == DevelImageVisual::StopBehavior::CURRENT_FRAME ) - { - stopped = true; - } - else - { - mPlayState = PlayState::STOPPING; - } + CallbackBase::Execute( *mCompletedCallback, nextTask, keepAnimation ); } } - - // Rasterize - if( !mVectorRenderer.Render( currentFrame ) ) - { - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Rendering failed. Try again later.[%d] [%p]\n", currentFrame, this ); - mUpdateFrameNumber = false; - } - - if( stopped ) - { - mPlayState = PlayState::STOPPED; - mForward = true; - mCurrentLoop = 0; - - // Animation is finished - if( needAnimationFinishedTrigger ) - { - mAnimationFinishedTrigger->Trigger(); - } - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this ); - } - - auto timeToSleepUntil = currentFrameStartTime + std::chrono::nanoseconds( mFrameDurationNanoSeconds ); - -#if defined(DEBUG_ENABLED) - auto sleepDuration = std::chrono::duration_cast< std::chrono::milliseconds >( timeToSleepUntil - std::chrono::system_clock::now() ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [current = %d, sleep duration = %lld] [%p]\n", currentFrame, sleepDuration.count(), this ); -#endif - - std::this_thread::sleep_until( timeToSleepUntil ); -} - -uint32_t VectorRasterizeThread::GetStoppedFrame( uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame ) -{ - uint32_t frame = currentFrame; - - switch( mStopBehavior ) - { - case DevelImageVisual::StopBehavior::FIRST_FRAME: - { - frame = startFrame; - break; - } - case DevelImageVisual::StopBehavior::LAST_FRAME: - { - if( mLoopingMode == DevelImageVisual::LoopingMode::AUTO_REVERSE ) - { - frame = startFrame; - } - else - { - frame = endFrame; - } - break; - } - case DevelImageVisual::StopBehavior::CURRENT_FRAME: - { - frame = currentFrame; - break; - } - } - - return frame; } } // namespace Internal