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-animation-task.cpp;h=c5978d66230034060039e22a5b9b50dda04ae754;hp=f8598abde1bc9fc1310b8c5e0baf8205dfab68d6;hb=f36f8f52fba9353136846f4bcabbbb7a9e0401e7;hpb=3a205c679c52e3504cc9487d6a7d95e458c3539f diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index f8598ab..c5978d6 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -46,23 +47,13 @@ constexpr auto NANOSECONDS_PER_SECOND( 1e+9 ); 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 VectorAnimationTask::VectorAnimationTask( VisualFactoryCache& factoryCache, const std::string& url ) : mUrl( url ), mVectorRenderer(), - mVectorAnimationThread( factoryCache.GetVectorAnimationThread() ), + mAnimationData(), + mVectorAnimationThread( factoryCache.GetVectorAnimationManager().GetVectorAnimationThread() ), mConditionalWait(), mAnimationFinishedTrigger(), mPlayState( PlayState::STOPPED ), @@ -77,14 +68,14 @@ VectorAnimationTask::VectorAnimationTask( VisualFactoryCache& factoryCache, cons mEndFrame( 0 ), mWidth( 0 ), mHeight( 0 ), + mAnimationDataIndex( 0 ), mLoopCount( LOOP_FOREVER ), mCurrentLoop( 0 ), - mResourceReady( false ), - mCurrentFrameUpdated( false ), - mCurrentLoopUpdated( false ), mForward( true ), mUpdateFrameNumber( false ), - mNeedAnimationFinishedTrigger( true ) + mNeedAnimationFinishedTrigger( true ), + mAnimationDataUpdated( false ), + mDestroyTask( false ) { Initialize(); } @@ -96,6 +87,8 @@ VectorAnimationTask::~VectorAnimationTask() void VectorAnimationTask::Finalize() { + ConditionalWait::ScopedLock lock( mConditionalWait ); + // Release some objects in the main thread if( mAnimationFinishedTrigger ) { @@ -103,6 +96,8 @@ void VectorAnimationTask::Finalize() } mVectorRenderer.Finalize(); + + mDestroyTask = true; } void VectorAnimationTask::SetRenderer( Renderer renderer ) @@ -114,41 +109,54 @@ void VectorAnimationTask::SetRenderer( Renderer renderer ) DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetRenderer [%p]\n", this ); } +void VectorAnimationTask::SetAnimationData( const AnimationData& data ) +{ + ConditionalWait::ScopedLock lock( mConditionalWait ); + + DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetAnimationData [%p]\n", this ); + + uint32_t index = mAnimationDataIndex == 0 ? 1 : 0; // Use the other buffer + + mAnimationData[index] = data; + mAnimationDataUpdated = true; + + if( data.resendFlag & VectorAnimationTask::RESEND_SIZE ) + { + // The size should be changed in the main thread. + SetSize( data.width, data.height ); + } + + mVectorAnimationThread.AddTask( this ); +} + void VectorAnimationTask::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, "VectorAnimationTask::SetSize: width = %d, height = %d [%p]\n", width, height, this ); } } void VectorAnimationTask::PlayAnimation() { - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState != PlayState::PLAYING ) { + mNeedAnimationFinishedTrigger = true; mUpdateFrameNumber = false; mPlayState = PlayState::PLAYING; - mVectorAnimationThread.AddTask( this ); - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::PlayAnimation: Play [%p]\n", this ); } } void VectorAnimationTask::StopAnimation() { - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState != PlayState::STOPPED && mPlayState != PlayState::STOPPING ) + if( mPlayState != PlayState::STOPPING ) { mNeedAnimationFinishedTrigger = false; mPlayState = PlayState::STOPPING; @@ -159,7 +167,6 @@ void VectorAnimationTask::StopAnimation() void VectorAnimationTask::PauseAnimation() { - ConditionalWait::ScopedLock lock( mConditionalWait ); if( mPlayState == PlayState::PLAYING ) { mPlayState = PlayState::PAUSED; @@ -168,18 +175,6 @@ void VectorAnimationTask::PauseAnimation() } } -void VectorAnimationTask::RenderFrame() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - - if( !mResourceReady ) - { - mVectorAnimationThread.AddTask( this ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::RenderFrame: Render [%p]\n", this ); - } -} - void VectorAnimationTask::SetAnimationFinishedCallback( EventThreadCallback* callback ) { ConditionalWait::ScopedLock lock( mConditionalWait ); @@ -193,20 +188,15 @@ void VectorAnimationTask::SetLoopCount( int32_t count ) { if( mLoopCount != count ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); - mLoopCount = count; mCurrentLoop = 0; - mCurrentLoopUpdated = true; DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopCount: [%d] [%p]\n", count, this ); } } -void VectorAnimationTask::SetPlayRange( Property::Array& playRange ) +void VectorAnimationTask::SetPlayRange( const Property::Array& playRange ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); - bool valid = false; uint32_t startFrame = 0, endFrame = 0; size_t count = playRange.Count(); @@ -256,7 +246,7 @@ void VectorAnimationTask::SetPlayRange( Property::Array& playRange ) } // Make sure the range specified is between 0 and the total frame number - if( startFrame >= 0 && startFrame < mTotalFrame && endFrame >= 0 && endFrame < mTotalFrame ) + if( startFrame < mTotalFrame && endFrame < mTotalFrame ) { // If the range is not in order swap values if( startFrame > endFrame ) @@ -275,16 +265,10 @@ void VectorAnimationTask::SetPlayRange( Property::Array& playRange ) 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, "VectorAnimationTask::SetPlayRange: [%d, %d] [%p]\n", mStartFrame, mEndFrame, this ); @@ -303,37 +287,8 @@ void VectorAnimationTask::GetPlayRange( uint32_t& startFrame, uint32_t& endFrame endFrame = mEndFrame; } -DevelImageVisual::PlayState::Type VectorAnimationTask::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; -} - void VectorAnimationTask::SetCurrentFrameNumber( uint32_t frameNumber ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mCurrentFrame == frameNumber ) { DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: Set same frame [%d] [%p]\n", frameNumber, this ); @@ -343,10 +298,7 @@ void VectorAnimationTask::SetCurrentFrameNumber( uint32_t frameNumber ) if( frameNumber >= mStartFrame && frameNumber <= mEndFrame ) { mCurrentFrame = frameNumber; - mCurrentFrameUpdated = true; - mUpdateFrameNumber = false; - mResourceReady = false; DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: frame number = %d [%p]\n", mCurrentFrame, this ); } @@ -373,7 +325,6 @@ void VectorAnimationTask::GetDefaultSize( uint32_t& width, uint32_t& height ) co void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); mStopBehavior = stopBehavior; DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetStopBehavior: stop behavor = %d [%p]\n", mStopBehavior, this ); @@ -381,7 +332,6 @@ void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type void VectorAnimationTask::SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode ) { - ConditionalWait::ScopedLock lock( mConditionalWait ); mLoopingMode = loopingMode; DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopingMode: looping mode = %d [%p]\n", mLoopingMode, this ); @@ -418,47 +368,41 @@ void VectorAnimationTask::Initialize() bool VectorAnimationTask::Rasterize() { - bool stopped = false, needAnimationFinishedTrigger; - uint32_t currentFrame, startFrame, endFrame; - int32_t loopCount, currentLoopCount; - PlayState playState; + bool stopped = false; + uint32_t currentFrame; { ConditionalWait::ScopedLock lock( mConditionalWait ); - - if( mPlayState == PlayState::PLAYING && mUpdateFrameNumber ) + if( mDestroyTask ) { - mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1; - Dali::ClampInPlace( mCurrentFrame, mStartFrame, mEndFrame ); + // The task will be destroyed. We don't need rasterization. + return false; } - - currentFrame = mCurrentFrame; - startFrame = mStartFrame; - endFrame = mEndFrame; - loopCount = mLoopCount; - currentLoopCount = mCurrentLoop; - needAnimationFinishedTrigger = mNeedAnimationFinishedTrigger; - playState = mPlayState; - - mResourceReady = true; - mCurrentFrameUpdated = false; - mCurrentLoopUpdated = false; - mUpdateFrameNumber = true; - mNeedAnimationFinishedTrigger = true; } - if( playState == PlayState::STOPPING ) + ApplyAnimationData(); + + if( mPlayState == PlayState::PLAYING && mUpdateFrameNumber ) { - currentFrame = GetStoppedFrame( startFrame, endFrame, currentFrame ); - ResetValue( mCurrentFrameUpdated, mCurrentFrame, currentFrame, mConditionalWait ); + mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1; + Dali::ClampInPlace( mCurrentFrame, mStartFrame, mEndFrame ); + } + + currentFrame = mCurrentFrame; + + mUpdateFrameNumber = true; + if( mPlayState == PlayState::STOPPING ) + { + mCurrentFrame = GetStoppedFrame( mStartFrame, mEndFrame, mCurrentFrame ); + currentFrame = mCurrentFrame; stopped = true; } - else if( playState == PlayState::PLAYING ) + else if( mPlayState == PlayState::PLAYING ) { bool animationFinished = false; - if( currentFrame >= endFrame ) // last frame + if( currentFrame >= mEndFrame ) // last frame { if( mLoopingMode == DevelImageVisual::LoopingMode::AUTO_REVERSE ) { @@ -466,21 +410,20 @@ bool VectorAnimationTask::Rasterize() } else { - if( loopCount < 0 || ++currentLoopCount < loopCount ) // repeat forever or before the last loop + if( mLoopCount < 0 || ++mCurrentLoop < mLoopCount ) // 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. + mCurrentFrame = mStartFrame; mUpdateFrameNumber = false; } else { animationFinished = true; // end of animation } - ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait ); } } - else if( currentFrame == startFrame && !mForward ) // first frame + else if( currentFrame == mStartFrame && !mForward ) // first frame { - if( loopCount < 0 || ++currentLoopCount < loopCount ) // repeat forever or before the last loop + if( mLoopCount < 0 || ++mCurrentLoop < mLoopCount ) // repeat forever or before the last loop { mForward = true; } @@ -488,7 +431,6 @@ bool VectorAnimationTask::Rasterize() { animationFinished = true; // end of animation } - ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait ); } if( animationFinished ) @@ -523,16 +465,19 @@ bool VectorAnimationTask::Rasterize() mCurrentLoop = 0; // Animation is finished - if( needAnimationFinishedTrigger && mAnimationFinishedTrigger ) { - mAnimationFinishedTrigger->Trigger(); + ConditionalWait::ScopedLock lock( mConditionalWait ); + if( mNeedAnimationFinishedTrigger && mAnimationFinishedTrigger ) + { + mAnimationFinishedTrigger->Trigger(); + } } DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this ); } bool keepAnimation = true; - if( playState == PlayState::PAUSED || playState == PlayState::STOPPED ) + if( mPlayState == PlayState::PAUSED || mPlayState == PlayState::STOPPED ) { keepAnimation = false; } @@ -593,6 +538,69 @@ std::chrono::time_point< std::chrono::system_clock > VectorAnimationTask::GetNex return mNextFrameStartTime; } +void VectorAnimationTask::ApplyAnimationData() +{ + uint32_t index; + + { + ConditionalWait::ScopedLock lock( mConditionalWait ); + + if( !mAnimationDataUpdated || mAnimationData[mAnimationDataIndex].resendFlag != 0 ) + { + // Data is not updated or the previous data is not applied yet. + return; + } + + mAnimationDataIndex = mAnimationDataIndex == 0 ? 1 : 0; // Swap index + mAnimationDataUpdated = false; + + index = mAnimationDataIndex; + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOP_COUNT ) + { + SetLoopCount( mAnimationData[index].loopCount ); + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_RANGE ) + { + SetPlayRange( mAnimationData[index].playRange ); + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_STOP_BEHAVIOR ) + { + SetStopBehavior( mAnimationData[index].stopBehavior ); + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOPING_MODE ) + { + SetLoopingMode( mAnimationData[index].loopingMode ); + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_CURRENT_FRAME ) + { + SetCurrentFrameNumber( mAnimationData[index].currentFrame ); + } + + if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE ) + { + if( mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING ) + { + PlayAnimation(); + } + else if( mAnimationData[index].playState == DevelImageVisual::PlayState::PAUSED ) + { + PauseAnimation(); + } + else if( mAnimationData[index].playState == DevelImageVisual::PlayState::STOPPED ) + { + StopAnimation(); + } + } + + mAnimationData[index].resendFlag = 0; +} + } // namespace Internal } // namespace Toolkit