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