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/integration-api/adaptors/adaptor.h>
23 #include <dali/integration-api/debug.h>
39 constexpr auto LOOP_FOREVER = -1;
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
45 } // unnamed namespace
47 VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
52 mResourceReadyTrigger( NULL ),
53 mAnimationFinishedTrigger( NULL ),
54 mPlayRange( 0.0f, 1.0f ),
55 mPlayState( DevelImageVisual::PlayState::STOPPED ),
62 mLoopCount( LOOP_FOREVER ),
65 mDestroyThread( false ),
66 mResourceReady( false ),
67 mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
69 mVectorRenderer = VectorAnimationRenderer::New( mUrl, renderer, width, height );
72 VectorRasterizeThread::~VectorRasterizeThread()
76 ConditionalWait::ScopedLock lock( mConditionalWait );
77 mDestroyThread = true;
78 mConditionalWait.Notify( lock );
80 // This should be called in the main thread to stop waiting for the dequeuable buffer.
81 mVectorRenderer.StopRender();
84 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
88 delete mResourceReadyTrigger;
89 delete mAnimationFinishedTrigger;
92 void VectorRasterizeThread::Run()
94 mLogFactory.InstallLogFunction();
96 //TODO: check the return value
99 while( IsThreadReady() )
105 void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height )
107 ConditionalWait::ScopedLock lock( mConditionalWait );
108 mVectorRenderer.SetSize( width, height );
110 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetSize: width = %d, height = %d\n", width, height );
113 void VectorRasterizeThread::StartAnimation()
115 ConditionalWait::ScopedLock lock( mConditionalWait );
116 if( mPlayState != DevelImageVisual::PlayState::PLAYING )
118 if( mPlayState == DevelImageVisual::PlayState::STOPPED )
120 // Reset the current frame and the current loop
121 mCurrentFrame = mStartFrame;
125 mPlayState = DevelImageVisual::PlayState::PLAYING;
126 mConditionalWait.Notify( lock );
128 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
132 void VectorRasterizeThread::StopAnimation()
134 ConditionalWait::ScopedLock lock( mConditionalWait );
135 if( mPlayState != DevelImageVisual::PlayState::STOPPED )
137 mPlayState = DevelImageVisual::PlayState::STOPPED;
139 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
143 void VectorRasterizeThread::PauseAnimation()
145 ConditionalWait::ScopedLock lock( mConditionalWait );
146 if( mPlayState == DevelImageVisual::PlayState::PLAYING )
148 mPlayState = DevelImageVisual::PlayState::PAUSED;
150 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
154 void VectorRasterizeThread::RenderFrame()
156 ConditionalWait::ScopedLock lock( mConditionalWait );
158 mConditionalWait.Notify( lock );
160 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
163 void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
165 ConditionalWait::ScopedLock lock( mConditionalWait );
166 mResourceReadyTrigger = callback;
169 void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* callback )
171 ConditionalWait::ScopedLock lock( mConditionalWait );
172 mAnimationFinishedTrigger = callback;
175 void VectorRasterizeThread::SetLoopCount( int16_t count )
177 ConditionalWait::ScopedLock lock( mConditionalWait );
183 mCurrentFrame = mStartFrame;
186 void VectorRasterizeThread::SetPlayRange( Vector2 range )
188 ConditionalWait::ScopedLock lock( mConditionalWait );
192 if( mTotalFrame != 0 )
194 mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
195 mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
199 DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState()
204 bool VectorRasterizeThread::IsThreadReady()
206 ConditionalWait::ScopedLock lock( mConditionalWait );
208 if( mPlayState != DevelImageVisual::PlayState::PLAYING && !mNeedRender && !mDestroyThread )
210 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
212 mConditionalWait.Wait( lock );
215 // Keep the thread alive if this thread is NOT to be destroyed
216 return !mDestroyThread;
219 bool VectorRasterizeThread::StartRender()
221 //TODO: check the return value
222 mVectorRenderer.StartRender();
224 mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
226 mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
227 mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
229 mCurrentFrame = mStartFrame;
231 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d (%d, %d)]\n", mTotalFrame, mStartFrame, mEndFrame );
236 void VectorRasterizeThread::Rasterize()
238 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
241 mVectorRenderer.Render( mCurrentFrame );
243 if( mPlayState == DevelImageVisual::PlayState::PLAYING )
245 if( ++mCurrentFrame >= mEndFrame )
250 mCurrentFrame = mStartFrame;
255 if( mCurrentLoop >= mLoopCount )
257 // Animation is finished
258 mPlayState = DevelImageVisual::PlayState::STOPPED;
260 mAnimationFinishedTrigger->Trigger();
262 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished\n" );
266 mCurrentFrame = mStartFrame;
274 if( !mResourceReady )
276 DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
278 mResourceReadyTrigger->Trigger();
279 mResourceReady = true;
283 } // namespace Internal
285 } // namespace Toolkit