2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h>
22 #include <dali/devel-api/adaptor-framework/thread-settings.h>
23 #include <dali/integration-api/adaptors/adaptor.h>
24 #include <dali/integration-api/debug.h>
40 constexpr auto LOOP_FOREVER = -1;
42 #if defined(DEBUG_ENABLED)
43 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
46 } // unnamed namespace
48 VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
53 mResourceReadyTrigger(),
54 mAnimationFinishedTrigger(),
55 mPlayRange( 0.0f, 1.0f ),
56 mPlayState( DevelImageVisual::PlayState::STOPPED ),
63 mLoopCount( LOOP_FOREVER ),
66 mDestroyThread( false ),
67 mResourceReady( false ),
68 mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
70 mVectorRenderer = VectorAnimationRenderer::New( mUrl, renderer, width, height );
73 VectorRasterizeThread::~VectorRasterizeThread()
77 ConditionalWait::ScopedLock lock( mConditionalWait );
78 mDestroyThread = true;
79 mConditionalWait.Notify( lock );
81 // This should be called in the main thread to stop waiting for the dequeuable buffer.
82 mVectorRenderer.StopRender();
85 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
90 void VectorRasterizeThread::Run()
92 SetThreadName( "VectorImageThread" );
93 mLogFactory.InstallLogFunction();
95 //TODO: check the return value
98 while( IsThreadReady() )
104 void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height )
106 ConditionalWait::ScopedLock lock( mConditionalWait );
107 mVectorRenderer.SetSize( width, height );
109 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetSize: width = %d, height = %d\n", width, height );
112 void VectorRasterizeThread::StartAnimation()
114 ConditionalWait::ScopedLock lock( mConditionalWait );
115 if( mPlayState != DevelImageVisual::PlayState::PLAYING )
117 if( mPlayState == DevelImageVisual::PlayState::STOPPED )
119 // Reset the current frame and the current loop
120 mCurrentFrame = mStartFrame;
124 mPlayState = DevelImageVisual::PlayState::PLAYING;
125 mConditionalWait.Notify( lock );
127 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
131 void VectorRasterizeThread::StopAnimation()
133 ConditionalWait::ScopedLock lock( mConditionalWait );
134 if( mPlayState != DevelImageVisual::PlayState::STOPPED )
136 mPlayState = DevelImageVisual::PlayState::STOPPED;
138 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
142 void VectorRasterizeThread::PauseAnimation()
144 ConditionalWait::ScopedLock lock( mConditionalWait );
145 if( mPlayState == DevelImageVisual::PlayState::PLAYING )
147 mPlayState = DevelImageVisual::PlayState::PAUSED;
149 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
153 void VectorRasterizeThread::RenderFrame()
155 ConditionalWait::ScopedLock lock( mConditionalWait );
157 mConditionalWait.Notify( lock );
159 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
162 void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
164 ConditionalWait::ScopedLock lock( mConditionalWait );
165 mResourceReadyTrigger = std::unique_ptr< EventThreadCallback >( callback );
168 void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* callback )
170 ConditionalWait::ScopedLock lock( mConditionalWait );
171 mAnimationFinishedTrigger = std::unique_ptr< EventThreadCallback >( callback );
174 void VectorRasterizeThread::SetLoopCount( int16_t count )
176 ConditionalWait::ScopedLock lock( mConditionalWait );
182 mCurrentFrame = mStartFrame;
185 void VectorRasterizeThread::SetPlayRange( Vector2 range )
187 ConditionalWait::ScopedLock lock( mConditionalWait );
191 if( mTotalFrame != 0 )
193 mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
194 mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
198 DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState()
203 bool VectorRasterizeThread::IsThreadReady()
205 ConditionalWait::ScopedLock lock( mConditionalWait );
207 if( mPlayState != DevelImageVisual::PlayState::PLAYING && !mNeedRender && !mDestroyThread )
209 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
211 mConditionalWait.Wait( lock );
214 // Keep the thread alive if this thread is NOT to be destroyed
215 return !mDestroyThread;
218 bool VectorRasterizeThread::StartRender()
220 //TODO: check the return value
221 mVectorRenderer.StartRender();
223 mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
225 mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
226 mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
228 mCurrentFrame = mStartFrame;
230 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d (%d, %d)]\n", mTotalFrame, mStartFrame, mEndFrame );
235 void VectorRasterizeThread::Rasterize()
237 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
240 mVectorRenderer.Render( mCurrentFrame );
242 if( mPlayState == DevelImageVisual::PlayState::PLAYING )
244 if( ++mCurrentFrame >= mEndFrame )
249 mCurrentFrame = mStartFrame;
254 if( mCurrentLoop >= mLoopCount )
256 // Animation is finished
257 mPlayState = DevelImageVisual::PlayState::STOPPED;
259 mAnimationFinishedTrigger->Trigger();
261 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished\n" );
265 mCurrentFrame = mStartFrame;
273 if( !mResourceReady )
275 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
277 mResourceReadyTrigger->Trigger();
278 mResourceReady = true;
282 } // namespace Internal
284 } // namespace Toolkit