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=9a3f909cd2a605fe8c90ba6f89ec98756b444152;hp=35f485f952577353732c47ca976931c395eb2f4d;hb=7018f61b640b6fcf9cb576b537bafcb6bb8240e8;hpb=7c1ca2d9ab3bc63f3dc164c4f5d4ea0d8bf5ba3e 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 35f485f..9a3f909 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -20,307 +20,118 @@ // EXTERNAL INCLUDES #include -#include +#include #include - -// INTERNAL INCLUDES +#include +#include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - -constexpr auto LOOP_FOREVER = -1; - #if defined(DEBUG_ENABLED) -Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" ); +Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_VECTOR_ANIMATION"); #endif } // unnamed namespace -VectorRasterizeThread::VectorRasterizeThread( const std::string& url ) -: mUrl( url ), - mVectorRenderer(), +VectorRasterizeThread::VectorRasterizeThread() +: mRasterizeTasks(), mConditionalWait(), - mMutex(), - mResourceReadyTrigger(), - mAnimationFinishedTrigger(), - mPlayRange( 0.0f, 1.0f ), - mPlayState( DevelImageVisual::PlayState::STOPPED ), - mProgress( 0.0f ), - mCurrentFrame( 0 ), - mTotalFrame( 0 ), - mStartFrame( 0 ), - mEndFrame( 0 ), - mWidth( 0 ), - mHeight( 0 ), - mLoopCount( LOOP_FOREVER ), - mCurrentLoop( 0 ), - mNeedRender( false ), - mDestroyThread( false ), - mResourceReady( false ), - mLogFactory( Dali::Adaptor::Get().GetLogFactory() ) + mCompletedCallback(), + mDestroyThread(false), + mIsThreadStarted(false), + mLogFactory(Dali::Adaptor::Get().GetLogFactory()) { - mVectorRenderer = VectorAnimationRenderer::New( mUrl ); } VectorRasterizeThread::~VectorRasterizeThread() { // Stop the thread { - ConditionalWait::ScopedLock lock( mConditionalWait ); + ConditionalWait::ScopedLock lock(mConditionalWait); mDestroyThread = true; - mConditionalWait.Notify( lock ); - - // This should be called in the main thread to stop waiting for the dequeuable buffer. - mVectorRenderer.StopRender(); + mConditionalWait.Notify(lock); } - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" ); + DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join [%p]\n", this); Join(); } -void VectorRasterizeThread::Run() +void VectorRasterizeThread::SetCompletedCallback(CallbackBase* callback) { - SetThreadName( "VectorImageThread" ); - mLogFactory.InstallLogFunction(); + ConditionalWait::ScopedLock lock(mConditionalWait); - //TODO: check the return value - StartRender(); - - while( IsThreadReady() ) - { - Rasterize(); - } + mCompletedCallback = std::unique_ptr(callback); } -void VectorRasterizeThread::SetRenderer( Renderer renderer ) +void VectorRasterizeThread::AddTask(VectorAnimationTaskPtr task) { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - mVectorRenderer.SetRenderer( renderer ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetRenderer\n" ); -} + // Lock while adding task to the queue + ConditionalWait::ScopedLock lock(mConditionalWait); -void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height ) -{ - if( mWidth != width || mHeight != height ) + if(!mIsThreadStarted) { - 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\n", width, height ); + Start(); + mIsThreadStarted = true; } -} -void VectorRasterizeThread::PlayAnimation() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState != DevelImageVisual::PlayState::PLAYING ) + if(mRasterizeTasks.end() == std::find(mRasterizeTasks.begin(), mRasterizeTasks.end(), task)) { - if( mPlayState == DevelImageVisual::PlayState::STOPPED ) - { - // Reset the current frame and the current loop - mCurrentFrame = mStartFrame; - mCurrentLoop = 0; - } - - mPlayState = DevelImageVisual::PlayState::PLAYING; - mConditionalWait.Notify( lock ); + mRasterizeTasks.push_back(task); - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PlayAnimation: Start\n" ); + // wake up the animation thread + mConditionalWait.Notify(lock); } } -void VectorRasterizeThread::StopAnimation() +void VectorRasterizeThread::Run() { - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState != DevelImageVisual::PlayState::STOPPED ) - { - mPlayState = DevelImageVisual::PlayState::STOPPED; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" ); - } -} + SetThreadName("VectorRasterizeThread"); + mLogFactory.InstallLogFunction(); -void VectorRasterizeThread::PauseAnimation() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - if( mPlayState == DevelImageVisual::PlayState::PLAYING ) + while(!mDestroyThread) { - mPlayState = DevelImageVisual::PlayState::PAUSED; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" ); + Rasterize(); } } -void VectorRasterizeThread::RenderFrame() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mNeedRender = true; - mConditionalWait.Notify( lock ); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" ); -} - -void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mResourceReadyTrigger = std::unique_ptr< EventThreadCallback >( callback ); -} - -void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* callback ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - mAnimationFinishedTrigger = std::unique_ptr< EventThreadCallback >( callback ); -} - -void VectorRasterizeThread::SetLoopCount( int32_t count ) -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - - mLoopCount = count; - - // Reset progress - mCurrentLoop = 0; - mCurrentFrame = mStartFrame; -} - -int32_t VectorRasterizeThread::GetLoopCount() const -{ - return mLoopCount; -} - -void VectorRasterizeThread::SetPlayRange( Vector2 range ) +void VectorRasterizeThread::Rasterize() { - ConditionalWait::ScopedLock lock( mConditionalWait ); - - // Make sure the range specified is between 0.0 and 1.0 - if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f ) + VectorAnimationTaskPtr nextTask; { - Vector2 orderedRange( range ); - // If the range is not in order swap values - if( range.x > range.y ) + // Lock while popping task out from the queue + ConditionalWait::ScopedLock lock(mConditionalWait); + + // conditional wait + if(mRasterizeTasks.empty()) { - orderedRange = Vector2( range.y, range.x ); + mConditionalWait.Wait(lock); } - mPlayRange = orderedRange; - - if( mTotalFrame != 0 ) + // pop out the next task from the queue + if(!mRasterizeTasks.empty()) { - mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f ); - mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f ); + std::vector::iterator next = mRasterizeTasks.begin(); + nextTask = *next; + mRasterizeTasks.erase(next); } } -} -Vector2 VectorRasterizeThread::GetPlayRange() const -{ - return mPlayRange; -} - -DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState() const -{ - return mPlayState; -} - -bool VectorRasterizeThread::IsResourceReady() const -{ - return mResourceReady; -} - -bool VectorRasterizeThread::IsThreadReady() -{ - ConditionalWait::ScopedLock lock( mConditionalWait ); - - if( mPlayState != DevelImageVisual::PlayState::PLAYING && !mNeedRender && !mDestroyThread ) + if(nextTask) { - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" ); - - mConditionalWait.Wait( lock ); - } - - // Keep the thread alive if this thread is NOT to be destroyed - return !mDestroyThread; -} - -bool VectorRasterizeThread::StartRender() -{ - //TODO: check the return value - mVectorRenderer.StartRender(); - - mTotalFrame = mVectorRenderer.GetTotalFrameNumber(); + bool keepAnimation = nextTask->Rasterize(); - mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f ); - mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f ); - - mCurrentFrame = mStartFrame; - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d (%d, %d)]\n", mTotalFrame, mStartFrame, mEndFrame ); - - return true; -} - -void VectorRasterizeThread::Rasterize() -{ - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame ); - - // Rasterize - mVectorRenderer.Render( mCurrentFrame ); - - if( mPlayState == DevelImageVisual::PlayState::PLAYING ) - { - if( ++mCurrentFrame >= mEndFrame ) + if(mCompletedCallback) { - if( mLoopCount < 0 ) - { - // repeat forever - mCurrentFrame = mStartFrame; - } - else - { - mCurrentLoop++; - if( mCurrentLoop >= mLoopCount ) - { - // Animation is finished - mPlayState = DevelImageVisual::PlayState::STOPPED; - - mAnimationFinishedTrigger->Trigger(); - - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished\n" ); - } - else - { - mCurrentFrame = mStartFrame; - } - } + CallbackBase::Execute(*mCompletedCallback, nextTask, keepAnimation); } } - - mNeedRender = false; - - if( !mResourceReady ) - { - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" ); - - mResourceReadyTrigger->Trigger(); - mResourceReady = true; - } } } // namespace Internal