[Tizen](Vector) Ensure that all animation data is applied at once
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-vector-image / animated-vector-image-visual.cpp
1 /*
2  * Copyright (c) 2019 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/public-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/adaptor-framework/adaptor.h>
26 #include <dali/integration-api/debug.h>
27
28 // INTERNAL INCLUDES
29 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
30 #include <dali-toolkit/public-api/visuals/visual-properties.h>
31 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
32 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-signals-devel.h>
33 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
34 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
35 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
36 #include <dali-toolkit/internal/visuals/visual-base-data-impl.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 ),
88   mUrl( imageUrl ),
89   mAnimationData(),
90   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
91   mImageVisualShaderFactory( shaderFactory ),
92   mVisualSize(),
93   mVisualScale( Vector2::ONE ),
94   mPlacementActor(),
95   mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP ),
96   mRendererAdded( false ),
97   mRasterizationTriggered( 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( mRasterizationTriggered && Adaptor::IsAvailable() )
109   {
110     Adaptor::Get().UnregisterProcessor( *this );
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 >( mVectorAnimationTask->GetPlayState() ) );
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::DoSetOnStage( 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 );
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::DoSetOnStage [%p]\n", this );
301 }
302
303 void AnimatedVectorImageVisual::DoSetOffStage( 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::DoSetOffStage [%p]\n", this );
335 }
336
337 void AnimatedVectorImageVisual::OnSetTransform()
338 {
339   Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
340
341   if( IsOnStage() && 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( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY && 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( IsOnStage() && 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       mActionStatus = DevelAnimatedVectorImageVisual::Action::PLAY;
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       mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
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       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
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::Process()
422 {
423   SendAnimationData();
424
425   mRasterizationTriggered = false;
426
427   Adaptor::Get().UnregisterProcessor( *this );
428 }
429
430 void AnimatedVectorImageVisual::OnUploadCompleted()
431 {
432   // If weak handle is holding a placement actor, it is the time to add the renderer to actor.
433   Actor actor = mPlacementActor.GetHandle();
434   if( actor && !mRendererAdded )
435   {
436     actor.AddRenderer( mImpl->mRenderer );
437     mRendererAdded = true;
438
439     ResourceReady( Toolkit::Visual::ResourceStatus::READY );
440
441     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnUploadCompleted: Renderer is added [%p]\n", this );
442   }
443 }
444
445 void AnimatedVectorImageVisual::OnAnimationFinished()
446 {
447   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mActionStatus, this );
448
449   if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
450   {
451     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
452
453     mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
454
455     if( mImpl->mEventObserver )
456     {
457       mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
458     }
459   }
460
461   if( mImpl->mRenderer )
462   {
463     mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
464   }
465 }
466
467 void AnimatedVectorImageVisual::SendAnimationData()
468 {
469   if( mAnimationData.resendFlag )
470   {
471     mVectorAnimationTask->SetAnimationData( mAnimationData );
472
473     if( mAnimationData.playState == DevelImageVisual::PlayState::PLAYING )
474     {
475       mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
476     }
477     else
478     {
479       mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
480     }
481
482     mAnimationData.resendFlag = 0;
483   }
484 }
485
486 void AnimatedVectorImageVisual::SetVectorImageSize()
487 {
488   uint32_t width = static_cast< uint32_t >( mVisualSize.width * mVisualScale.width );
489   uint32_t height = static_cast< uint32_t >( mVisualSize.height * mVisualScale.height );
490
491   mAnimationData.width = width;
492   mAnimationData.height = height;
493   mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
494 }
495
496 void AnimatedVectorImageVisual::StopAnimation()
497 {
498   if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
499   {
500     mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
501     mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
502
503     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
504   }
505 }
506
507 void AnimatedVectorImageVisual::TriggerVectorRasterization()
508 {
509   if( !mRasterizationTriggered )
510   {
511     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
512
513     Adaptor::Get().RegisterProcessor( *this );
514     mRasterizationTriggered = true;
515   }
516 }
517
518 void AnimatedVectorImageVisual::OnScaleNotification( PropertyNotification& source )
519 {
520   Actor actor = mPlacementActor.GetHandle();
521   if( actor )
522   {
523     Vector3 scale = actor.GetProperty< Vector3 >( Actor::Property::WORLD_SCALE );
524     mVisualScale.width = scale.width;
525     mVisualScale.height = scale.height;
526
527     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnScaleNotification: scale = %f, %f [%p]\n", mVisualScale.width, mVisualScale.height, this );
528
529     SetVectorImageSize();
530     SendAnimationData();
531
532     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
533   }
534 }
535
536 void AnimatedVectorImageVisual::OnSizeNotification( PropertyNotification& source )
537 {
538   Actor actor = mPlacementActor.GetHandle();
539   if( actor )
540   {
541     Vector3 size = actor.GetCurrentSize();
542     mVisualSize.width = size.width;
543     mVisualSize.height = size.height;
544
545     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this );
546
547     SetVectorImageSize();
548     SendAnimationData();
549
550     Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
551   }
552 }
553
554 void AnimatedVectorImageVisual::OnControlVisibilityChanged( Actor actor, bool visible, DevelActor::VisibilityChange::Type type )
555 {
556   if( !visible )
557   {
558     StopAnimation();
559     TriggerVectorRasterization();
560
561     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
562   }
563 }
564
565 void AnimatedVectorImageVisual::OnWindowVisibilityChanged( Window window, bool visible )
566 {
567   if( !visible )
568   {
569     StopAnimation();
570     TriggerVectorRasterization();
571
572     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
573   }
574 }
575
576 } // namespace Internal
577
578 } // namespace Toolkit
579
580 } // namespace Dali