Merge "Further refactoring of text-controller-impl" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-vector-image / animated-vector-image-visual.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/stage.h>
23 #include <dali/devel-api/rendering/renderer-devel.h>
24 #include <dali/devel-api/adaptor-framework/window-devel.h>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
29 #include <dali-toolkit/public-api/visuals/visual-properties.h>
30 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
31 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
32 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
33 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
34 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
35 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
36 #include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.h>
37
38 namespace Dali
39 {
40
41 namespace Toolkit
42 {
43
44 namespace Internal
45 {
46
47 namespace
48 {
49
50 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
51
52 // stop behavior
53 DALI_ENUM_TO_STRING_TABLE_BEGIN( STOP_BEHAVIOR )
54 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME )
55 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, FIRST_FRAME )
56 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, LAST_FRAME )
57 DALI_ENUM_TO_STRING_TABLE_END( STOP_BEHAVIOR )
58
59 // looping mode
60 DALI_ENUM_TO_STRING_TABLE_BEGIN( LOOPING_MODE )
61 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::LoopingMode, RESTART )
62 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::LoopingMode, AUTO_REVERSE )
63 DALI_ENUM_TO_STRING_TABLE_END( LOOPING_MODE )
64
65 #if defined(DEBUG_ENABLED)
66 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
67 #endif
68
69 } // unnamed namespace
70
71 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
72 {
73   AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
74   visual->SetProperties( properties );
75
76   return visual;
77 }
78
79 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
80 {
81   AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
82
83   return visual;
84 }
85
86 AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
87 : Visual::Base( factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>( Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE ) ),
88   mUrl( imageUrl ),
89   mAnimationData(),
90   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
91   mImageVisualShaderFactory( shaderFactory ),
92   mVisualSize(),
93   mVisualScale( Vector2::ONE ),
94   mPlacementActor(),
95   mPlayState( DevelImageVisual::PlayState::STOPPED ),
96   mEventCallback( nullptr ),
97   mRendererAdded( false ),
98   mCoreShutdown(false)
99 {
100   // the rasterized image is with pre-multiplied alpha format
101   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
102
103   mVectorAnimationTask->UploadCompletedSignal().Connect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
104   mVectorAnimationTask->SetAnimationFinishedCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnAnimationFinished ) ) );
105
106   auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
107   vectorAnimationManager.AddObserver(*this);
108 }
109
110 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
111 {
112   if( ! mCoreShutdown )
113   {
114     auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
115     vectorAnimationManager.RemoveObserver(*this);
116
117     if( mEventCallback )
118     {
119       mFactoryCache.GetVectorAnimationManager().UnregisterEventCallback( mEventCallback );
120     }
121
122     // Finalize animation task and disconnect the signal in the main thread
123     mVectorAnimationTask->UploadCompletedSignal().Disconnect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
124     mVectorAnimationTask->Finalize();
125   }
126 }
127
128 void AnimatedVectorImageVisual::VectorAnimationManagerDestroyed()
129 {
130   // Core is shutting down. Don't talk to the plugin any more.
131   mCoreShutdown = true;
132 }
133
134 void AnimatedVectorImageVisual::GetNaturalSize( Vector2& naturalSize )
135 {
136   if( mVisualSize != Vector2::ZERO )
137   {
138     naturalSize = mVisualSize;
139   }
140   else
141   {
142     uint32_t width, height;
143     mVectorAnimationTask->GetDefaultSize( width, height );
144     naturalSize.x = width;
145     naturalSize.y = height;
146   }
147
148   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::GetNaturalSize: w = %f, h = %f [%p]\n", naturalSize.width, naturalSize.height, this );
149 }
150
151 void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
152 {
153   map.Clear();
154   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE );
155   if( mUrl.IsValid() )
156   {
157     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
158   }
159   map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, mAnimationData.loopCount );
160
161   uint32_t startFrame, endFrame;
162   mVectorAnimationTask->GetPlayRange( startFrame, endFrame );
163
164   Property::Array playRange;
165   playRange.PushBack( static_cast< int32_t >( startFrame ) );
166   playRange.PushBack( static_cast< int32_t >( endFrame ) );
167   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, playRange );
168
169   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int32_t >( mPlayState ) );
170   map.Insert( Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetCurrentFrameNumber() ) );
171   map.Insert( Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetTotalFrameNumber() ) );
172
173   map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mAnimationData.stopBehavior );
174   map.Insert( Toolkit::DevelImageVisual::Property::LOOPING_MODE, mAnimationData.loopingMode );
175
176   Property::Map layerInfo;
177   mVectorAnimationTask->GetLayerInfo( layerInfo );
178   map.Insert( Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo );
179 }
180
181 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
182 {
183   // Do nothing
184 }
185
186 void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMap )
187 {
188   // url already passed in from constructor
189   for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter )
190   {
191     KeyValuePair keyValue = propertyMap.GetKeyValue( iter );
192     if( keyValue.first.type == Property::Key::INDEX )
193     {
194       DoSetProperty( keyValue.first.indexKey, keyValue.second );
195     }
196     else
197     {
198        if( keyValue.first == LOOP_COUNT_NAME )
199        {
200           DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second );
201        }
202        else if( keyValue.first == PLAY_RANGE_NAME )
203        {
204           DoSetProperty( Toolkit::DevelImageVisual::Property::PLAY_RANGE, keyValue.second );
205        }
206        else if( keyValue.first == STOP_BEHAVIOR_NAME )
207        {
208           DoSetProperty( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second );
209        }
210        else if( keyValue.first == LOOPING_MODE_NAME )
211        {
212           DoSetProperty( Toolkit::DevelImageVisual::Property::LOOPING_MODE, keyValue.second );
213        }
214     }
215   }
216
217   TriggerVectorRasterization();
218 }
219
220 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
221 {
222   switch(index)
223   {
224     case Toolkit::DevelImageVisual::Property::LOOP_COUNT:
225     {
226       int32_t loopCount;
227       if( value.Get( loopCount ) )
228       {
229         mAnimationData.loopCount = loopCount;
230         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_LOOP_COUNT;
231       }
232       break;
233     }
234     case Toolkit::DevelImageVisual::Property::PLAY_RANGE:
235     {
236       const Property::Array* array = value.GetArray();
237       if( array )
238       {
239         mAnimationData.playRange = *array;
240         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_RANGE;
241       }
242       break;
243     }
244     case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR:
245     {
246       int32_t stopBehavior = mAnimationData.stopBehavior;
247       if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) )
248       {
249         mAnimationData.stopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
250         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_STOP_BEHAVIOR;
251       }
252       break;
253     }
254     case Toolkit::DevelImageVisual::Property::LOOPING_MODE:
255     {
256       int32_t loopingMode = mAnimationData.loopingMode;
257       if( Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode ) )
258       {
259         mAnimationData.loopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
260         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_LOOPING_MODE;
261       }
262       break;
263     }
264   }
265 }
266
267 void AnimatedVectorImageVisual::DoSetOnScene( Actor& actor )
268 {
269   Shader shader;
270
271   if( mImpl->mCustomShader )
272   {
273     shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource().data() : mImpl->mCustomShader->mVertexShader,
274                           mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource().data() : mImpl->mCustomShader->mFragmentShader,
275                           mImpl->mCustomShader->mHints );
276
277     shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
278   }
279   else
280   {
281     shader = mImageVisualShaderFactory.GetShader( mFactoryCache, false, true, false );
282   }
283
284   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
285
286   mImpl->mRenderer = Renderer::New( geometry, shader );
287
288   TextureSet textureSet = TextureSet::New();
289   mImpl->mRenderer.SetTextures( textureSet );
290
291   // Register transform properties
292   mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
293
294   // Defer the rasterisation task until we get given a size (by Size Negotiation algorithm)
295
296   // Hold the weak handle of the placement actor and delay the adding of renderer until the rasterization is finished.
297   mPlacementActor = actor;
298
299   mVectorAnimationTask->SetRenderer( mImpl->mRenderer );
300
301   // Add property notification for scaling & size
302   mScaleNotification = actor.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
303   mScaleNotification.NotifySignal().Connect( this, &AnimatedVectorImageVisual::OnScaleNotification );
304
305   mSizeNotification = actor.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 3.0f ) );
306   mSizeNotification.NotifySignal().Connect( this, &AnimatedVectorImageVisual::OnSizeNotification );
307
308   DevelActor::VisibilityChangedSignal( actor ).Connect( this, &AnimatedVectorImageVisual::OnControlVisibilityChanged );
309
310   Window window = DevelWindow::Get( actor );
311   if( window )
312   {
313     DevelWindow::VisibilityChangedSignal( window ).Connect( this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged );
314   }
315
316   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOnScene [%p]\n", this );
317 }
318
319 void AnimatedVectorImageVisual::DoSetOffScene( Actor& actor )
320 {
321   StopAnimation();
322   SendAnimationData();
323
324   if( mImpl->mRenderer )
325   {
326     actor.RemoveRenderer( mImpl->mRenderer );
327     mImpl->mRenderer.Reset();
328
329     mRendererAdded = false;
330   }
331
332   // Remove property notification
333   actor.RemovePropertyNotification( mScaleNotification );
334   actor.RemovePropertyNotification( mSizeNotification );
335
336   DevelActor::VisibilityChangedSignal( actor ).Disconnect( this, &AnimatedVectorImageVisual::OnControlVisibilityChanged );
337
338   Window window = DevelWindow::Get( actor );
339   if( window )
340   {
341     DevelWindow::VisibilityChangedSignal( window ).Disconnect( this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged );
342   }
343
344   mPlacementActor.Reset();
345
346   // Reset the visual size to zero so that when adding the actor back to stage the rasterization is forced
347   mVisualSize = Vector2::ZERO;
348   mVisualScale = Vector2::ONE;
349
350   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOffScene [%p]\n", this );
351 }
352
353 void AnimatedVectorImageVisual::OnSetTransform()
354 {
355   Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
356
357   if( IsOnScene() && visualSize != mVisualSize )
358   {
359     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSetTransform: width = %f, height = %f [%p]\n", visualSize.width, visualSize.height, this );
360
361     mVisualSize = visualSize;
362
363     SetVectorImageSize();
364
365     if( mPlayState == DevelImageVisual::PlayState::PLAYING && mAnimationData.playState != DevelImageVisual::PlayState::PLAYING )
366     {
367       mAnimationData.playState = DevelImageVisual::PlayState::PLAYING;
368       mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
369     }
370
371     SendAnimationData();
372   }
373 }
374
375 void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
376 {
377   // Check if action is valid for this visual type and perform action if possible
378   switch( actionId )
379   {
380     case DevelAnimatedVectorImageVisual::Action::PLAY:
381     {
382       if( IsOnScene() && mVisualSize != Vector2::ZERO )
383       {
384         if( mAnimationData.playState != DevelImageVisual::PlayState::PLAYING )
385         {
386           mAnimationData.playState = DevelImageVisual::PlayState::PLAYING;
387           mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
388         }
389       }
390       mPlayState = DevelImageVisual::PlayState::PLAYING;
391       break;
392     }
393     case DevelAnimatedVectorImageVisual::Action::PAUSE:
394     {
395       if( mAnimationData.playState == DevelImageVisual::PlayState::PLAYING )
396       {
397         mAnimationData.playState = DevelImageVisual::PlayState::PAUSED;
398         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
399       }
400       mPlayState = DevelImageVisual::PlayState::PAUSED;
401       break;
402     }
403     case DevelAnimatedVectorImageVisual::Action::STOP:
404     {
405       if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
406       {
407         mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
408         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
409       }
410       mPlayState = DevelImageVisual::PlayState::STOPPED;
411       break;
412     }
413     case DevelAnimatedVectorImageVisual::Action::JUMP_TO:
414     {
415       int32_t frameNumber;
416       if( attributes.Get( frameNumber ) )
417       {
418         mAnimationData.currentFrame = frameNumber;
419         mAnimationData.resendFlag |= VectorAnimationTask::RESEND_CURRENT_FRAME;
420       }
421       break;
422     }
423     case DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY:
424     {
425       const Property::Map* map = attributes.GetMap();
426       if( map )
427       {
428         DoSetProperties( *map );
429       }
430       break;
431     }
432   }
433
434   TriggerVectorRasterization();
435 }
436
437 void AnimatedVectorImageVisual::OnUploadCompleted()
438 {
439   // If weak handle is holding a placement actor, it is the time to add the renderer to actor.
440   Actor actor = mPlacementActor.GetHandle();
441   if( actor && !mRendererAdded )
442   {
443     actor.AddRenderer( mImpl->mRenderer );
444     mRendererAdded = true;
445
446     ResourceReady( Toolkit::Visual::ResourceStatus::READY );
447
448     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnUploadCompleted: Renderer is added [%p]\n", this );
449   }
450 }
451
452 void AnimatedVectorImageVisual::OnAnimationFinished()
453 {
454   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mPlayState, this );
455
456   if( mPlayState != DevelImageVisual::PlayState::STOPPED )
457   {
458     mPlayState = DevelImageVisual::PlayState::STOPPED;
459
460     mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
461
462     if( mImpl->mEventObserver )
463     {
464       mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
465     }
466   }
467
468   if( mImpl->mRenderer )
469   {
470     mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
471   }
472 }
473
474 void AnimatedVectorImageVisual::SendAnimationData()
475 {
476   if( mAnimationData.resendFlag )
477   {
478     mVectorAnimationTask->SetAnimationData( mAnimationData );
479
480     if( mImpl->mRenderer )
481     {
482       if( mAnimationData.playState == DevelImageVisual::PlayState::PLAYING )
483       {
484         mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
485       }
486       else
487       {
488         mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
489       }
490     }
491
492     mAnimationData.resendFlag = 0;
493   }
494 }
495
496 void AnimatedVectorImageVisual::SetVectorImageSize()
497 {
498   uint32_t width = static_cast< uint32_t >( mVisualSize.width * mVisualScale.width );
499   uint32_t height = static_cast< uint32_t >( mVisualSize.height * mVisualScale.height );
500
501   mAnimationData.width = width;
502   mAnimationData.height = height;
503   mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
504 }
505
506 void AnimatedVectorImageVisual::StopAnimation()
507 {
508   if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
509   {
510     mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
511     mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
512
513     mPlayState = DevelImageVisual::PlayState::STOPPED;
514   }
515 }
516
517 void AnimatedVectorImageVisual::TriggerVectorRasterization()
518 {
519   if( !mEventCallback && !mCoreShutdown )
520   {
521     mEventCallback = MakeCallback( this, &AnimatedVectorImageVisual::OnProcessEvents );
522     auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
523     vectorAnimationManager.RegisterEventCallback( mEventCallback );
524     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
525   }
526 }
527
528 void AnimatedVectorImageVisual::OnScaleNotification( PropertyNotification& source )
529 {
530   Actor actor = mPlacementActor.GetHandle();
531   if( actor )
532   {
533     Vector3 scale = actor.GetProperty< Vector3 >( Actor::Property::WORLD_SCALE );
534     mVisualScale.width = scale.width;
535     mVisualScale.height = scale.height;
536
537     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnScaleNotification: scale = %f, %f [%p]\n", mVisualScale.width, mVisualScale.height, this );
538
539     SetVectorImageSize();
540     SendAnimationData();
541
542     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
543   }
544 }
545
546 void AnimatedVectorImageVisual::OnSizeNotification( PropertyNotification& source )
547 {
548   Actor actor = mPlacementActor.GetHandle();
549   if( actor )
550   {
551     Vector3 size = actor.GetCurrentProperty< Vector3 >( Actor::Property::SIZE );
552     mVisualSize.width = size.width;
553     mVisualSize.height = size.height;
554
555     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this );
556
557     SetVectorImageSize();
558     SendAnimationData();
559
560     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
561   }
562 }
563
564 void AnimatedVectorImageVisual::OnControlVisibilityChanged( Actor actor, bool visible, DevelActor::VisibilityChange::Type type )
565 {
566   if( !visible )
567   {
568     StopAnimation();
569     TriggerVectorRasterization();
570
571     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
572   }
573 }
574
575 void AnimatedVectorImageVisual::OnWindowVisibilityChanged( Window window, bool visible )
576 {
577   if( !visible )
578   {
579     StopAnimation();
580     TriggerVectorRasterization();
581
582     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
583   }
584 }
585
586 void AnimatedVectorImageVisual::OnProcessEvents()
587 {
588   SendAnimationData();
589
590   mEventCallback = nullptr;  // The callback will be deleted in the VectorAnimationManager
591 }
592
593 } // namespace Internal
594
595 } // namespace Toolkit
596
597 } // namespace Dali