(Vector) Ensure that all animation data is applied at once 53/220553/9
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 19 Dec 2019 10:10:41 +0000 (19:10 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 8 Jun 2020 02:20:45 +0000 (11:20 +0900)
Change-Id: I22b285e52062e187a7e2117d8a543dc7f49f82c5

automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.h
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h

index 7d6e853..c3616b2 100644 (file)
@@ -26,6 +26,7 @@ class EglInterface;
 class DisplayConnection;
 class ThreadSynchronizationInterface;
 class Window;
 class DisplayConnection;
 class ThreadSynchronizationInterface;
 class Window;
+class TestApplication;
 
 namespace Integration
 {
 
 namespace Integration
 {
@@ -83,6 +84,11 @@ public:
   void AddWindow( Internal::Adaptor::SceneHolder* window );
   void RemoveWindow( Internal::Adaptor::SceneHolder* window );
 
   void AddWindow( Internal::Adaptor::SceneHolder* window );
   void RemoveWindow( Internal::Adaptor::SceneHolder* window );
 
+  void RegisterProcessor( Integration::Processor& processor );
+  void UnregisterProcessor( Integration::Processor& processor );
+
+  void SetApplication( Dali::TestApplication& testApplication );
+
   Dali::Adaptor::AdaptorSignalType& ResizedSignal();
   Dali::Adaptor::AdaptorSignalType& LanguageChangedSignal();
   Dali::Adaptor::WindowCreatedSignalType& WindowCreatedSignal();
   Dali::Adaptor::AdaptorSignalType& ResizedSignal();
   Dali::Adaptor::AdaptorSignalType& LanguageChangedSignal();
   Dali::Adaptor::WindowCreatedSignalType& WindowCreatedSignal();
@@ -97,6 +103,7 @@ private:
   Dali::Adaptor::AdaptorSignalType mResizedSignal;
   Dali::Adaptor::AdaptorSignalType mLanguageChangedSignal;
   Dali::Adaptor::WindowCreatedSignalType mWindowCreatedSignal;
   Dali::Adaptor::AdaptorSignalType mResizedSignal;
   Dali::Adaptor::AdaptorSignalType mLanguageChangedSignal;
   Dali::Adaptor::WindowCreatedSignalType mWindowCreatedSignal;
+  TestApplication* mTestApplication;
 };
 
 } // namespace Adaptor
 };
 
 } // namespace Adaptor
index 7c50cc7..5dbbe76 100644 (file)
@@ -195,6 +195,23 @@ void Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* window )
   }
 }
 
   }
 }
 
+void Adaptor::RegisterProcessor( Integration::Processor& processor )
+{
+  Integration::Core& core = mTestApplication->GetCore();
+  core.RegisterProcessor( processor );
+}
+
+void Adaptor::UnregisterProcessor( Integration::Processor& processor )
+{
+  Integration::Core& core = mTestApplication->GetCore();
+  core.UnregisterProcessor( processor );
+}
+
+void Adaptor::SetApplication( Dali::TestApplication& testApplication )
+{
+  mTestApplication = &testApplication;
+}
+
 Dali::Adaptor::AdaptorSignalType& Adaptor::ResizedSignal()
 {
   return mResizedSignal;
 Dali::Adaptor::AdaptorSignalType& Adaptor::ResizedSignal()
 {
   return mResizedSignal;
@@ -356,4 +373,14 @@ const LogFactoryInterface& Adaptor::GetLogFactory()
   return *gLogFactory;
 }
 
   return *gLogFactory;
 }
 
+void Adaptor::RegisterProcessor( Integration::Processor& processor )
+{
+  mImpl->RegisterProcessor( processor );
+}
+
+void Adaptor::UnregisterProcessor( Integration::Processor& processor )
+{
+  mImpl->UnregisterProcessor( processor );
+}
+
 } // namespace Dali
 } // namespace Dali
index d3bdd42..3e3a0d2 100644 (file)
@@ -49,6 +49,7 @@ ToolkitTestApplication::ToolkitTestApplication( size_t surfaceWidth, size_t surf
 
   // This will also emit the window created signals
   AdaptorImpl::GetImpl( *mAdaptor ).Start( *mMainWindow );
 
   // This will also emit the window created signals
   AdaptorImpl::GetImpl( *mAdaptor ).Start( *mMainWindow );
+  AdaptorImpl::GetImpl( *mAdaptor ).SetApplication( *this );
 
   Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
   lifecycleController.InitSignal().Emit();
 
   Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
   lifecycleController.InitSignal().Emit();
index cf52774..b0075d2 100755 (executable)
@@ -19,6 +19,8 @@
 #include <dali/public-api/object/base-object.h>
 #include <toolkit-application.h>
 #include <toolkit-vector-animation-renderer.h>
 #include <dali/public-api/object/base-object.h>
 #include <toolkit-application.h>
 #include <toolkit-vector-animation-renderer.h>
+#include <toolkit-event-thread-callback.h>
+#include <memory>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -39,7 +41,8 @@ public:
     mWidth( 0 ),
     mHeight( 0 ),
     mPreviousFrame( 0 ),
     mWidth( 0 ),
     mHeight( 0 ),
     mPreviousFrame( 0 ),
-    mFrameRate( 60.0f )
+    mFrameRate( 60.0f ),
+    mEventThreadCallback( new EventThreadCallback( MakeCallback( this, &VectorAnimationRenderer::OnTriggered ) ) )
   {
     mCount++;
 
   {
     mCount++;
 
@@ -83,6 +86,12 @@ public:
 
   bool Render( uint32_t frameNumber )
   {
 
   bool Render( uint32_t frameNumber )
   {
+    if( mNeedTrigger )
+    {
+      mEventThreadCallback->Trigger();
+      mNeedTrigger = false;
+    }
+
     if( frameNumber == 1 && mPreviousFrame != frameNumber )
     {
       mPreviousFrame = frameNumber;
     if( frameNumber == 1 && mPreviousFrame != frameNumber )
     {
       mPreviousFrame = frameNumber;
@@ -133,9 +142,14 @@ public:
     return mUploadCompletedSignal;
   }
 
     return mUploadCompletedSignal;
   }
 
+  void OnTriggered()
+  {
+  }
+
 public:
 
   static uint32_t mCount;
 public:
 
   static uint32_t mCount;
+  static bool mNeedTrigger;
 
   std::string mUrl;
   Dali::Renderer mRenderer;
 
   std::string mUrl;
   Dali::Renderer mRenderer;
@@ -144,9 +158,11 @@ public:
   uint32_t mPreviousFrame;
   float mFrameRate;
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
   uint32_t mPreviousFrame;
   float mFrameRate;
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
+  std::unique_ptr< EventThreadCallback > mEventThreadCallback;
 };
 
 uint32_t VectorAnimationRenderer::mCount = 0;
 };
 
 uint32_t VectorAnimationRenderer::mCount = 0;
+bool VectorAnimationRenderer::mNeedTrigger = true;
 
 inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
 {
 
 inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
 {
@@ -250,5 +266,18 @@ VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::Upl
   return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
 }
 
   return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
 }
 
-} // namespace Dali;
+} // namespace Dali
+
+namespace Test
+{
+namespace VectorAnimationRenderer
+{
+
+void RequestTrigger()
+{
+  Dali::Internal::Adaptor::VectorAnimationRenderer::mNeedTrigger = true;
+}
+
+} // VectorAnimationRenderer
+} // Test
 
 
index 670c5ca..2213465 100755 (executable)
@@ -20,6 +20,8 @@
 
 namespace Test
 {
 
 namespace Test
 {
+namespace VectorAnimationRenderer
+{
 
 #define VECTOR_ANIMATION_TOTAL_FRAME_NUMBER 5
 #define VECTOR_ANIMATION_MARKER_NAME_1 "marker1"
 
 #define VECTOR_ANIMATION_TOTAL_FRAME_NUMBER 5
 #define VECTOR_ANIMATION_MARKER_NAME_1 "marker1"
@@ -29,6 +31,9 @@ namespace Test
 #define VECTOR_ANIMATION_MARKER_START_FRAME_2 2
 #define VECTOR_ANIMATION_MARKER_END_FRAME_2 3
 
 #define VECTOR_ANIMATION_MARKER_START_FRAME_2 2
 #define VECTOR_ANIMATION_MARKER_END_FRAME_2 3
 
+void RequestTrigger();
+
+} // VectorAnimationRenderer
 } // Test
 
 
 } // Test
 
 
index daf21d3..587c7ac 100644 (file)
@@ -347,8 +347,6 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render( 16 );
 
     application.SendNotification();
     application.Render( 16 );
 
-    std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );    // wait for one animation loop (16fps, 5frames, need 80ms)
-
     Property::Map map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
     Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
     DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
     Property::Map map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
     Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
     DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PLAYING );
@@ -359,8 +357,6 @@ int UtcDaliAnimatedVectorImageVisualPlayback(void)
     application.SendNotification();
     application.Render(16);
 
     application.SendNotification();
     application.Render(16);
 
-    std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
-
     map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
     value = map.Find( DevelImageVisual::Property::PLAY_STATE );
     DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PAUSED );
     map = dummyControl.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
     value = map.Find( DevelImageVisual::Property::PLAY_STATE );
     DALI_TEST_CHECK( value->Get< int >() == DevelImageVisual::PlayState::PAUSED );
@@ -566,7 +562,7 @@ int UtcDaliAnimatedVectorImageVisualLoopCount(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - animation finished
+  // Trigger count is 1 - render a frame
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
@@ -610,6 +606,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
@@ -638,6 +636,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
@@ -658,6 +658,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
@@ -720,6 +722,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
@@ -748,6 +752,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
@@ -770,6 +776,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
@@ -814,7 +822,7 @@ int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
   application.Render();
 
   // Wait for animation finish
   application.Render();
 
   // Wait for animation finish
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_STATE );
@@ -899,6 +907,8 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
@@ -919,7 +929,7 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
 {
   ToolkitTestApplication application;
 int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliAnimatedVectorImageVisualJumpToCurrentProgress" );
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualUpdateProperty" );
 
   int startFrame = 1, endFrame = 3;
   Property::Array playRange;
 
   int startFrame = 1, endFrame = 3;
   Property::Array playRange;
@@ -947,6 +957,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
   DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
@@ -973,6 +985,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
   DALI_TEST_EQUALS( value->Get< int >(), 5, TEST_LOCATION );
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
   DALI_TEST_EQUALS( value->Get< int >(), 5, TEST_LOCATION );
@@ -997,6 +1011,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
+  std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );    // wait for next rasterize thread run
+
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
   map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
 
@@ -1057,7 +1073,7 @@ int UtcDaliAnimatedVectorImageVisualStopBehavior(void)
   application.Render();
 
   // Trigger count is 1 - animation finished
   application.Render();
 
   // Trigger count is 1 - animation finished
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
@@ -1152,7 +1168,7 @@ int UtcDaliAnimatedVectorImageVisualLoopingMode(void)
   application.Render();
 
   // Trigger count is 1 - animation finished
   application.Render();
 
   // Trigger count is 1 - animation finished
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
 
   Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
   Property::Value* value = map.Find( DevelImageVisual::Property::CURRENT_FRAME_NUMBER );
@@ -1353,6 +1369,9 @@ int UtcDaliAnimatedVectorImageVisualControlVisibilityChanged(void)
   Property::Map attributes;
   DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
   Property::Map attributes;
   DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
+  application.SendNotification();
+  application.Render();
+
   // Check rendering behavior
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
   // Check rendering behavior
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
@@ -1397,6 +1416,9 @@ int UtcDaliAnimatedVectorImageVisualWindowVisibilityChanged(void)
   Property::Map attributes;
   DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
   Property::Map attributes;
   DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
 
+  application.SendNotification();
+  application.Render();
+
   // Check rendering behavior
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
   // Check rendering behavior
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   Renderer renderer = actor.GetRendererAt( 0u );
index 1793fbc..bf3b519 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
 #include <dali/public-api/common/stage.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
@@ -46,19 +47,8 @@ namespace Internal
 namespace
 {
 
 namespace
 {
 
-constexpr auto LOOP_FOREVER = -1;
-
 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
 
 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
 
-// Flags for re-sending data to the rasterize thread
-enum Flags
-{
-  RESEND_PLAY_RANGE    = 1 << 0,
-  RESEND_LOOP_COUNT    = 1 << 1,
-  RESEND_STOP_BEHAVIOR = 1 << 2,
-  RESEND_LOOPING_MODE  = 1 << 3
-};
-
 // stop behavior
 DALI_ENUM_TO_STRING_TABLE_BEGIN( STOP_BEHAVIOR )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME )
 // stop behavior
 DALI_ENUM_TO_STRING_TABLE_BEGIN( STOP_BEHAVIOR )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME )
@@ -96,18 +86,15 @@ AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache&
 AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 : Visual::Base( factoryCache, Visual::FittingMode::FILL ),
   mUrl( imageUrl ),
 AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 : Visual::Base( factoryCache, Visual::FittingMode::FILL ),
   mUrl( imageUrl ),
+  mAnimationData(),
   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
   mImageVisualShaderFactory( shaderFactory ),
   mVisualSize(),
   mVisualScale( Vector2::ONE ),
   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
   mImageVisualShaderFactory( shaderFactory ),
   mVisualSize(),
   mVisualScale( Vector2::ONE ),
-  mPlayRange(),
   mPlacementActor(),
   mPlacementActor(),
-  mLoopCount( LOOP_FOREVER ),
-  mResendFlag( 0 ),
-  mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP ),
-  mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ),
-  mLoopingMode( DevelImageVisual::LoopingMode::RESTART ),
-  mRendererAdded( false )
+  mPlayState( DevelImageVisual::PlayState::STOPPED ),
+  mRendererAdded( false ),
+  mRasterizationTriggered( false )
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
@@ -118,6 +105,11 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factor
 
 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
 {
 
 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
 {
+  if( mRasterizationTriggered && Adaptor::IsAvailable() )
+  {
+    Adaptor::Get().UnregisterProcessor( *this );
+  }
+
   // Finalize animation task and disconnect the signal in the main thread
   mVectorAnimationTask->UploadCompletedSignal().Disconnect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
   mVectorAnimationTask->Finalize();
   // Finalize animation task and disconnect the signal in the main thread
   mVectorAnimationTask->UploadCompletedSignal().Disconnect( this, &AnimatedVectorImageVisual::OnUploadCompleted );
   mVectorAnimationTask->Finalize();
@@ -148,7 +140,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   {
     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
   }
   {
     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
   }
-  map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, mLoopCount );
+  map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, mAnimationData.loopCount );
 
   uint32_t startFrame, endFrame;
   mVectorAnimationTask->GetPlayRange( startFrame, endFrame );
 
   uint32_t startFrame, endFrame;
   mVectorAnimationTask->GetPlayRange( startFrame, endFrame );
@@ -158,12 +150,12 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   playRange.PushBack( static_cast< int32_t >( endFrame ) );
   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, playRange );
 
   playRange.PushBack( static_cast< int32_t >( endFrame ) );
   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, playRange );
 
-  map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int32_t >( mVectorAnimationTask->GetPlayState() ) );
+  map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int32_t >( mPlayState ) );
   map.Insert( Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetCurrentFrameNumber() ) );
   map.Insert( Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetTotalFrameNumber() ) );
 
   map.Insert( Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetCurrentFrameNumber() ) );
   map.Insert( Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast< int32_t >( mVectorAnimationTask->GetTotalFrameNumber() ) );
 
-  map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior );
-  map.Insert( Toolkit::DevelImageVisual::Property::LOOPING_MODE, mLoopingMode );
+  map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mAnimationData.stopBehavior );
+  map.Insert( Toolkit::DevelImageVisual::Property::LOOPING_MODE, mAnimationData.loopingMode );
 
   Property::Map layerInfo;
   mVectorAnimationTask->GetLayerInfo( layerInfo );
 
   Property::Map layerInfo;
   mVectorAnimationTask->GetLayerInfo( layerInfo );
@@ -205,6 +197,8 @@ void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMa
        }
     }
   }
        }
     }
   }
+
+  TriggerVectorRasterization();
 }
 
 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
 }
 
 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
@@ -216,8 +210,8 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       int32_t loopCount;
       if( value.Get( loopCount ) )
       {
       int32_t loopCount;
       if( value.Get( loopCount ) )
       {
-        mLoopCount = loopCount;
-        mResendFlag |= RESEND_LOOP_COUNT;
+        mAnimationData.loopCount = loopCount;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_LOOP_COUNT;
       }
       break;
     }
       }
       break;
     }
@@ -226,28 +220,28 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       Property::Array* array = value.GetArray();
       if( array )
       {
       Property::Array* array = value.GetArray();
       if( array )
       {
-        mPlayRange = *array;
-        mResendFlag |= RESEND_PLAY_RANGE;
+        mAnimationData.playRange = *array;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_RANGE;
       }
       break;
     }
     case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR:
     {
       }
       break;
     }
     case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR:
     {
-      int32_t stopBehavior = mStopBehavior;
+      int32_t stopBehavior = mAnimationData.stopBehavior;
       if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) )
       {
       if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) )
       {
-        mStopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
-        mResendFlag |= RESEND_STOP_BEHAVIOR;
+        mAnimationData.stopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior );
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_STOP_BEHAVIOR;
       }
       break;
     }
     case Toolkit::DevelImageVisual::Property::LOOPING_MODE:
     {
       }
       break;
     }
     case Toolkit::DevelImageVisual::Property::LOOPING_MODE:
     {
-      int32_t loopingMode = mLoopingMode;
+      int32_t loopingMode = mAnimationData.loopingMode;
       if( Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode ) )
       {
       if( Scripting::GetEnumerationProperty( value, LOOPING_MODE_TABLE, LOOPING_MODE_TABLE_COUNT, loopingMode ) )
       {
-        mLoopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
-        mResendFlag |= RESEND_LOOPING_MODE;
+        mAnimationData.loopingMode = DevelImageVisual::LoopingMode::Type( loopingMode );
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_LOOPING_MODE;
       }
       break;
     }
       }
       break;
     }
@@ -309,6 +303,7 @@ void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
 void AnimatedVectorImageVisual::DoSetOffStage( Actor& actor )
 {
   StopAnimation();
 void AnimatedVectorImageVisual::DoSetOffStage( Actor& actor )
 {
   StopAnimation();
+  SendAnimationData();
 
   if( mImpl->mRenderer )
   {
 
   if( mImpl->mRenderer )
   {
@@ -351,19 +346,13 @@ void AnimatedVectorImageVisual::OnSetTransform()
 
     SetVectorImageSize();
 
 
     SetVectorImageSize();
 
-    SendAnimationData();
-
-    if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
+    if( mPlayState == DevelImageVisual::PlayState::PLAYING && mAnimationData.playState != DevelImageVisual::PlayState::PLAYING )
     {
     {
-      mVectorAnimationTask->PlayAnimation();
-
-      mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
-    }
-    else
-    {
-      // Render one frame
-      mVectorAnimationTask->RenderFrame();
+      mAnimationData.playState = DevelImageVisual::PlayState::PLAYING;
+      mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
     }
     }
+
+    SendAnimationData();
   }
 }
 
   }
 }
 
@@ -376,38 +365,33 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
     {
       if( IsOnStage() && mVisualSize != Vector2::ZERO )
       {
     {
       if( IsOnStage() && mVisualSize != Vector2::ZERO )
       {
-        mVectorAnimationTask->PlayAnimation();
-
-        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
+        if( mAnimationData.playState != DevelImageVisual::PlayState::PLAYING )
+        {
+          mAnimationData.playState = DevelImageVisual::PlayState::PLAYING;
+          mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
+        }
       }
       }
-      mActionStatus = DevelAnimatedVectorImageVisual::Action::PLAY;
+      mPlayState = DevelImageVisual::PlayState::PLAYING;
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::PAUSE:
     {
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::PAUSE:
     {
-      mVectorAnimationTask->PauseAnimation();
-
-      if( mImpl->mRenderer )
+      if( mAnimationData.playState == DevelImageVisual::PlayState::PLAYING )
       {
       {
-        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
+        mAnimationData.playState = DevelImageVisual::PlayState::PAUSED;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
       }
       }
-
-      mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
+      mPlayState = DevelImageVisual::PlayState::PAUSED;
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::STOP:
     {
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::STOP:
     {
-      if( mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::STOPPED )
+      if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
       {
       {
-        mVectorAnimationTask->StopAnimation();
-      }
-
-      if( mImpl->mRenderer )
-      {
-        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
+        mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
       }
       }
-
-      mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
+      mPlayState = DevelImageVisual::PlayState::STOPPED;
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::JUMP_TO:
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::JUMP_TO:
@@ -415,13 +399,8 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       int32_t frameNumber;
       if( attributes.Get( frameNumber ) )
       {
       int32_t frameNumber;
       if( attributes.Get( frameNumber ) )
       {
-        mVectorAnimationTask->SetCurrentFrameNumber( frameNumber );
-
-        if( IsOnStage() && mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::PLAYING )
-        {
-          mVectorAnimationTask->RenderFrame();
-          Stage::GetCurrent().KeepRendering( 0.0f );    // Trigger rendering
-        }
+        mAnimationData.currentFrame = frameNumber;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_CURRENT_FRAME;
       }
       break;
     }
       }
       break;
     }
@@ -431,12 +410,21 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       if( map )
       {
         DoSetProperties( *map );
       if( map )
       {
         DoSetProperties( *map );
-
-        SendAnimationData();
       }
       break;
     }
   }
       }
       break;
     }
   }
+
+  TriggerVectorRasterization();
+}
+
+void AnimatedVectorImageVisual::Process()
+{
+  SendAnimationData();
+
+  mRasterizationTriggered = false;
+
+  Adaptor::Get().UnregisterProcessor( *this );
 }
 
 void AnimatedVectorImageVisual::OnUploadCompleted()
 }
 
 void AnimatedVectorImageVisual::OnUploadCompleted()
@@ -456,11 +444,13 @@ void AnimatedVectorImageVisual::OnUploadCompleted()
 
 void AnimatedVectorImageVisual::OnAnimationFinished()
 {
 
 void AnimatedVectorImageVisual::OnAnimationFinished()
 {
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mActionStatus, this );
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mPlayState, this );
 
 
-  if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
+  if( mPlayState != DevelImageVisual::PlayState::STOPPED )
   {
   {
-    mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
+    mPlayState = DevelImageVisual::PlayState::STOPPED;
+
+    mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
 
     if( mImpl->mEventObserver )
     {
 
     if( mImpl->mEventObserver )
     {
@@ -476,49 +466,23 @@ void AnimatedVectorImageVisual::OnAnimationFinished()
 
 void AnimatedVectorImageVisual::SendAnimationData()
 {
 
 void AnimatedVectorImageVisual::SendAnimationData()
 {
-  if( mResendFlag )
+  if( mAnimationData.resendFlag )
   {
   {
-    bool isPlaying = false;
-    if( mVectorAnimationTask->GetPlayState() == DevelImageVisual::PlayState::PLAYING )
-    {
-      mVectorAnimationTask->PauseAnimation();
-      isPlaying = true;
-    }
-
-    if( mResendFlag & RESEND_LOOP_COUNT )
-    {
-      mVectorAnimationTask->SetLoopCount( mLoopCount );
-    }
-
-    if( mResendFlag & RESEND_PLAY_RANGE )
-    {
-      mVectorAnimationTask->SetPlayRange( mPlayRange );
-    }
-
-    if( mResendFlag & RESEND_STOP_BEHAVIOR )
-    {
-      mVectorAnimationTask->SetStopBehavior( mStopBehavior );
-    }
-
-    if( mResendFlag & RESEND_LOOPING_MODE )
-    {
-      mVectorAnimationTask->SetLoopingMode( mLoopingMode );
-    }
+    mVectorAnimationTask->SetAnimationData( mAnimationData );
 
 
-    if( IsOnStage() )
+    if( mImpl->mRenderer )
     {
     {
-      if( isPlaying )
+      if( mAnimationData.playState == DevelImageVisual::PlayState::PLAYING )
       {
       {
-        mVectorAnimationTask->PlayAnimation();
+        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
       }
       else
       {
       }
       else
       {
-        mVectorAnimationTask->RenderFrame();
-        Stage::GetCurrent().KeepRendering( 0.0f );
+        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
       }
     }
 
       }
     }
 
-    mResendFlag = 0;
+    mAnimationData.resendFlag = 0;
   }
 }
 
   }
 }
 
@@ -527,27 +491,30 @@ void AnimatedVectorImageVisual::SetVectorImageSize()
   uint32_t width = static_cast< uint32_t >( mVisualSize.width * mVisualScale.width );
   uint32_t height = static_cast< uint32_t >( mVisualSize.height * mVisualScale.height );
 
   uint32_t width = static_cast< uint32_t >( mVisualSize.width * mVisualScale.width );
   uint32_t height = static_cast< uint32_t >( mVisualSize.height * mVisualScale.height );
 
-  mVectorAnimationTask->SetSize( width, height );
+  mAnimationData.width = width;
+  mAnimationData.height = height;
+  mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
+}
 
 
-  if( IsOnStage() && mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::PLAYING )
+void AnimatedVectorImageVisual::StopAnimation()
+{
+  if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
   {
   {
-    mVectorAnimationTask->RenderFrame();
-    Stage::GetCurrent().KeepRendering( 0.0f );    // Trigger rendering
+    mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
+    mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
+
+    mPlayState = DevelImageVisual::PlayState::STOPPED;
   }
 }
 
   }
 }
 
-void AnimatedVectorImageVisual::StopAnimation()
+void AnimatedVectorImageVisual::TriggerVectorRasterization()
 {
 {
-  if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
+  if( !mRasterizationTriggered )
   {
   {
-    mVectorAnimationTask->StopAnimation();
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
 
 
-    mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
-
-    if( mImpl->mRenderer )
-    {
-      mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
-    }
+    Adaptor::Get().RegisterProcessor( *this );
+    mRasterizationTriggered = true;
   }
 }
 
   }
 }
 
@@ -563,6 +530,9 @@ void AnimatedVectorImageVisual::OnScaleNotification( PropertyNotification& sourc
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnScaleNotification: scale = %f, %f [%p]\n", mVisualScale.width, mVisualScale.height, this );
 
     SetVectorImageSize();
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnScaleNotification: scale = %f, %f [%p]\n", mVisualScale.width, mVisualScale.height, this );
 
     SetVectorImageSize();
+    SendAnimationData();
+
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
   }
 }
 
   }
 }
 
@@ -578,6 +548,9 @@ void AnimatedVectorImageVisual::OnSizeNotification( PropertyNotification& source
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this );
 
     SetVectorImageSize();
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this );
 
     SetVectorImageSize();
+    SendAnimationData();
+
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
   }
 }
 
   }
 }
 
@@ -586,6 +559,7 @@ void AnimatedVectorImageVisual::OnControlVisibilityChanged( Actor actor, bool vi
   if( !visible )
   {
     StopAnimation();
   if( !visible )
   {
     StopAnimation();
+    TriggerVectorRasterization();
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
@@ -596,6 +570,7 @@ void AnimatedVectorImageVisual::OnWindowVisibilityChanged( Window window, bool v
   if( !visible )
   {
     StopAnimation();
   if( !visible )
   {
     StopAnimation();
+    TriggerVectorRasterization();
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
index 8aaed9c..6eaead5 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ANIMATED_VECTOR_IMAGE_VISUAL_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_ANIMATED_VECTOR_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,8 +22,9 @@
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/object/property-notification.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/object/property-notification.h>
-#include <dali/devel-api/actors/actor-devel.h>
 #include <dali/public-api/adaptor-framework/window.h>
 #include <dali/public-api/adaptor-framework/window.h>
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/integration-api/processor-interface.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
@@ -55,7 +56,7 @@ using AnimatedVectorImageVisualPtr = IntrusivePtr< AnimatedVectorImageVisual >;
  * | url                      | STRING           |
  *
  */
  * | url                      | STRING           |
  *
  */
-class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker
+class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker, public Integration::Processor
 {
 public:
 
 {
 public:
 
@@ -138,6 +139,13 @@ protected:
    */
   void OnDoAction( const Property::Index actionId, const Property::Value& attributes ) override;
 
    */
   void OnDoAction( const Property::Index actionId, const Property::Value& attributes ) override;
 
+protected: // Implementation of Processor
+
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process() override;
+
 private:
 
   /**
 private:
 
   /**
@@ -173,6 +181,11 @@ private:
   void StopAnimation();
 
   /**
   void StopAnimation();
 
   /**
+   * @brief Trigger rasterization of the vector content.
+   */
+  void TriggerVectorRasterization();
+
+  /**
    * @brief Callback when the world scale factor changes.
    */
   void OnScaleNotification( PropertyNotification& source );
    * @brief Callback when the world scale factor changes.
    */
   void OnScaleNotification( PropertyNotification& source );
@@ -200,20 +213,17 @@ private:
 
 private:
   VisualUrl                                    mUrl;
 
 private:
   VisualUrl                                    mUrl;
+  VectorAnimationTask::AnimationData           mAnimationData;
   VectorAnimationTaskPtr                       mVectorAnimationTask;
   ImageVisualShaderFactory&                    mImageVisualShaderFactory;
   PropertyNotification                         mScaleNotification;
   PropertyNotification                         mSizeNotification;
   Vector2                                      mVisualSize;
   Vector2                                      mVisualScale;
   VectorAnimationTaskPtr                       mVectorAnimationTask;
   ImageVisualShaderFactory&                    mImageVisualShaderFactory;
   PropertyNotification                         mScaleNotification;
   PropertyNotification                         mSizeNotification;
   Vector2                                      mVisualSize;
   Vector2                                      mVisualScale;
-  Property::Array                              mPlayRange;
   WeakHandle< Actor >                          mPlacementActor;
   WeakHandle< Actor >                          mPlacementActor;
-  int32_t                                      mLoopCount;
-  uint32_t                                     mResendFlag;
-  DevelAnimatedVectorImageVisual::Action::Type mActionStatus;
-  DevelImageVisual::StopBehavior::Type         mStopBehavior;
-  DevelImageVisual::LoopingMode::Type          mLoopingMode;
+  DevelImageVisual::PlayState::Type            mPlayState;
   bool                                         mRendererAdded;
   bool                                         mRendererAdded;
+  bool                                         mRasterizationTriggered;
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal
index e0c08bd..6072ce5 100644 (file)
@@ -46,22 +46,12 @@ constexpr auto NANOSECONDS_PER_SECOND( 1e+9 );
 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
 #endif
 
 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
 #endif
 
-template< typename T >
-inline void ResetValue( bool& updated, T& value, T newValue, ConditionalWait& conditionalWait )
-{
-  ConditionalWait::ScopedLock lock( conditionalWait );
-  if( !updated )
-  {
-    value = newValue;
-    updated = true;
-  }
-}
-
 } // unnamed namespace
 
 VectorAnimationTask::VectorAnimationTask( VisualFactoryCache& factoryCache, const std::string& url )
 : mUrl( url ),
   mVectorRenderer(),
 } // unnamed namespace
 
 VectorAnimationTask::VectorAnimationTask( VisualFactoryCache& factoryCache, const std::string& url )
 : mUrl( url ),
   mVectorRenderer(),
+  mAnimationData(),
   mVectorAnimationThread( factoryCache.GetVectorAnimationThread() ),
   mConditionalWait(),
   mAnimationFinishedTrigger(),
   mVectorAnimationThread( factoryCache.GetVectorAnimationThread() ),
   mConditionalWait(),
   mAnimationFinishedTrigger(),
@@ -77,14 +67,14 @@ VectorAnimationTask::VectorAnimationTask( VisualFactoryCache& factoryCache, cons
   mEndFrame( 0 ),
   mWidth( 0 ),
   mHeight( 0 ),
   mEndFrame( 0 ),
   mWidth( 0 ),
   mHeight( 0 ),
+  mAnimationDataIndex( 0 ),
   mLoopCount( LOOP_FOREVER ),
   mCurrentLoop( 0 ),
   mResourceReady( false ),
   mLoopCount( LOOP_FOREVER ),
   mCurrentLoop( 0 ),
   mResourceReady( false ),
-  mCurrentFrameUpdated( false ),
-  mCurrentLoopUpdated( false ),
   mForward( true ),
   mUpdateFrameNumber( false ),
   mForward( true ),
   mUpdateFrameNumber( false ),
-  mNeedAnimationFinishedTrigger( true )
+  mNeedAnimationFinishedTrigger( true ),
+  mAnimationDataUpdated( false )
 {
   Initialize();
 }
 {
   Initialize();
 }
@@ -116,11 +106,30 @@ void VectorAnimationTask::SetRenderer( Renderer renderer )
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetRenderer [%p]\n", this );
 }
 
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetRenderer [%p]\n", this );
 }
 
+void VectorAnimationTask::SetAnimationData( const AnimationData& data )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetAnimationData [%p]\n", this );
+
+  uint32_t index = mAnimationDataIndex == 0 ? 1 : 0;  // Use the other buffer
+
+  mAnimationData[index] = data;
+  mAnimationDataUpdated = true;
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_SIZE )
+  {
+    // The size should be changed in the main thread.
+    SetSize( data.width, data.height );
+  }
+
+  mVectorAnimationThread.AddTask( this );
+}
+
 void VectorAnimationTask::SetSize( uint32_t width, uint32_t height )
 {
   if( mWidth != width || mHeight != height )
   {
 void VectorAnimationTask::SetSize( uint32_t width, uint32_t height )
 {
   if( mWidth != width || mHeight != height )
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
     mVectorRenderer.SetSize( width, height );
 
     mWidth = width;
     mVectorRenderer.SetSize( width, height );
 
     mWidth = width;
@@ -134,23 +143,18 @@ void VectorAnimationTask::SetSize( uint32_t width, uint32_t height )
 
 void VectorAnimationTask::PlayAnimation()
 {
 
 void VectorAnimationTask::PlayAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   if( mPlayState != PlayState::PLAYING )
   {
     mUpdateFrameNumber = false;
     mPlayState = PlayState::PLAYING;
 
   if( mPlayState != PlayState::PLAYING )
   {
     mUpdateFrameNumber = false;
     mPlayState = PlayState::PLAYING;
 
-    mVectorAnimationThread.AddTask( this );
-
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::PlayAnimation: Play [%p]\n", this );
   }
 }
 
 void VectorAnimationTask::StopAnimation()
 {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::PlayAnimation: Play [%p]\n", this );
   }
 }
 
 void VectorAnimationTask::StopAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlayState != PlayState::STOPPED && mPlayState != PlayState::STOPPING )
+  if( mPlayState != PlayState::STOPPING )
   {
     mNeedAnimationFinishedTrigger = false;
     mPlayState = PlayState::STOPPING;
   {
     mNeedAnimationFinishedTrigger = false;
     mPlayState = PlayState::STOPPING;
@@ -161,7 +165,6 @@ void VectorAnimationTask::StopAnimation()
 
 void VectorAnimationTask::PauseAnimation()
 {
 
 void VectorAnimationTask::PauseAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
   if( mPlayState == PlayState::PLAYING )
   {
     mPlayState = PlayState::PAUSED;
   if( mPlayState == PlayState::PLAYING )
   {
     mPlayState = PlayState::PAUSED;
@@ -170,18 +173,6 @@ void VectorAnimationTask::PauseAnimation()
   }
 }
 
   }
 }
 
-void VectorAnimationTask::RenderFrame()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
-  if( !mResourceReady )
-  {
-    mVectorAnimationThread.AddTask( this );
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::RenderFrame: Render [%p]\n", this );
-  }
-}
-
 void VectorAnimationTask::SetAnimationFinishedCallback( EventThreadCallback* callback )
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
 void VectorAnimationTask::SetAnimationFinishedCallback( EventThreadCallback* callback )
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
@@ -195,20 +186,15 @@ void VectorAnimationTask::SetLoopCount( int32_t count )
 {
   if( mLoopCount != count )
   {
 {
   if( mLoopCount != count )
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
-
     mLoopCount = count;
     mCurrentLoop = 0;
     mLoopCount = count;
     mCurrentLoop = 0;
-    mCurrentLoopUpdated = true;
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopCount: [%d] [%p]\n", count, this );
   }
 }
 
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopCount: [%d] [%p]\n", count, this );
   }
 }
 
-void VectorAnimationTask::SetPlayRange( Property::Array& playRange )
+void VectorAnimationTask::SetPlayRange( const Property::Array& playRange )
 {
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   bool valid = false;
   uint32_t startFrame = 0, endFrame = 0;
   size_t count = playRange.Count();
   bool valid = false;
   uint32_t startFrame = 0, endFrame = 0;
   size_t count = playRange.Count();
@@ -277,15 +263,11 @@ void VectorAnimationTask::SetPlayRange( Property::Array& playRange )
       if( mStartFrame > mCurrentFrame )
       {
         mCurrentFrame = mStartFrame;
       if( mStartFrame > mCurrentFrame )
       {
         mCurrentFrame = mStartFrame;
-
-        mCurrentFrameUpdated = true;
         mResourceReady = false;
       }
       else if( mEndFrame < mCurrentFrame )
       {
         mCurrentFrame = mEndFrame;
         mResourceReady = false;
       }
       else if( mEndFrame < mCurrentFrame )
       {
         mCurrentFrame = mEndFrame;
-
-        mCurrentFrameUpdated = true;
         mResourceReady = false;
       }
 
         mResourceReady = false;
       }
 
@@ -305,37 +287,8 @@ void VectorAnimationTask::GetPlayRange( uint32_t& startFrame, uint32_t& endFrame
   endFrame = mEndFrame;
 }
 
   endFrame = mEndFrame;
 }
 
-DevelImageVisual::PlayState::Type VectorAnimationTask::GetPlayState() const
-{
-  DevelImageVisual::PlayState::Type state = DevelImageVisual::PlayState::STOPPED;
-
-  switch( mPlayState )
-  {
-    case PlayState::PLAYING:
-    {
-      state = DevelImageVisual::PlayState::PLAYING;
-      break;
-    }
-    case PlayState::PAUSED:
-    {
-      state = DevelImageVisual::PlayState::PAUSED;
-      break;
-    }
-    case PlayState::STOPPING:
-    case PlayState::STOPPED:
-    {
-      state = DevelImageVisual::PlayState::STOPPED;
-      break;
-    }
-  }
-
-  return state;
-}
-
 void VectorAnimationTask::SetCurrentFrameNumber( uint32_t frameNumber )
 {
 void VectorAnimationTask::SetCurrentFrameNumber( uint32_t frameNumber )
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   if( mCurrentFrame == frameNumber )
   {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: Set same frame [%d] [%p]\n", frameNumber, this );
   if( mCurrentFrame == frameNumber )
   {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: Set same frame [%d] [%p]\n", frameNumber, this );
@@ -345,8 +298,6 @@ void VectorAnimationTask::SetCurrentFrameNumber( uint32_t frameNumber )
   if( frameNumber >= mStartFrame && frameNumber <= mEndFrame )
   {
     mCurrentFrame = frameNumber;
   if( frameNumber >= mStartFrame && frameNumber <= mEndFrame )
   {
     mCurrentFrame = frameNumber;
-    mCurrentFrameUpdated = true;
-
     mUpdateFrameNumber = false;
     mResourceReady = false;
 
     mUpdateFrameNumber = false;
     mResourceReady = false;
 
@@ -375,7 +326,6 @@ void VectorAnimationTask::GetDefaultSize( uint32_t& width, uint32_t& height ) co
 
 void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior )
 {
 
 void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior )
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
   mStopBehavior = stopBehavior;
 
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetStopBehavior: stop behavor = %d [%p]\n", mStopBehavior, this );
   mStopBehavior = stopBehavior;
 
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetStopBehavior: stop behavor = %d [%p]\n", mStopBehavior, this );
@@ -383,7 +333,6 @@ void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type
 
 void VectorAnimationTask::SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode )
 {
 
 void VectorAnimationTask::SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode )
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
   mLoopingMode = loopingMode;
 
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopingMode: looping mode = %d [%p]\n", mLoopingMode, this );
   mLoopingMode = loopingMode;
 
   DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetLoopingMode: looping mode = %d [%p]\n", mLoopingMode, this );
@@ -420,48 +369,35 @@ void VectorAnimationTask::Initialize()
 
 bool VectorAnimationTask::Rasterize()
 {
 
 bool VectorAnimationTask::Rasterize()
 {
-  bool stopped = false, needAnimationFinishedTrigger, resourceReady;
-  uint32_t currentFrame, startFrame, endFrame;
-  int32_t loopCount, currentLoopCount;
-  PlayState playState;
+  bool stopped = false;
+  uint32_t currentFrame;
+
+  ApplyAnimationData();
 
 
+  if( mPlayState == PlayState::PLAYING && mUpdateFrameNumber )
   {
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
+    mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1;
+    Dali::ClampInPlace( mCurrentFrame, mStartFrame, mEndFrame );
+  }
 
 
-    if( mPlayState == PlayState::PLAYING && mUpdateFrameNumber )
-    {
-      mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1;
-      Dali::ClampInPlace( mCurrentFrame, mStartFrame, mEndFrame );
-    }
+  currentFrame = mCurrentFrame;
 
 
-    currentFrame = mCurrentFrame;
-    startFrame = mStartFrame;
-    endFrame = mEndFrame;
-    loopCount = mLoopCount;
-    currentLoopCount = mCurrentLoop;
-    needAnimationFinishedTrigger = mNeedAnimationFinishedTrigger;
-    playState = mPlayState;
-    resourceReady = mResourceReady;
-
-    mResourceReady = true;
-    mCurrentFrameUpdated = false;
-    mCurrentLoopUpdated = false;
-    mUpdateFrameNumber = true;
-    mNeedAnimationFinishedTrigger = true;
-  }
+  // Reset values
+  mResourceReady = true;
+  mUpdateFrameNumber = true;
+  mNeedAnimationFinishedTrigger = true;
 
 
-  if( playState == PlayState::STOPPING )
+  if( mPlayState == PlayState::STOPPING )
   {
   {
-    currentFrame = GetStoppedFrame( startFrame, endFrame, currentFrame );
-    ResetValue( mCurrentFrameUpdated, mCurrentFrame, currentFrame, mConditionalWait );
-
+    mCurrentFrame = GetStoppedFrame( mStartFrame, mEndFrame, mCurrentFrame );
+    currentFrame = mCurrentFrame;
     stopped = true;
   }
     stopped = true;
   }
-  else if( playState == PlayState::PLAYING )
+  else if( mPlayState == PlayState::PLAYING )
   {
     bool animationFinished = false;
 
   {
     bool animationFinished = false;
 
-    if( currentFrame >= endFrame )  // last frame
+    if( currentFrame >= mEndFrame )  // last frame
     {
       if( mLoopingMode == DevelImageVisual::LoopingMode::AUTO_REVERSE )
       {
     {
       if( mLoopingMode == DevelImageVisual::LoopingMode::AUTO_REVERSE )
       {
@@ -469,21 +405,20 @@ bool VectorAnimationTask::Rasterize()
       }
       else
       {
       }
       else
       {
-        if( loopCount < 0 || ++currentLoopCount < loopCount )   // repeat forever or before the last loop
+        if( mLoopCount < 0 || ++mCurrentLoop < mLoopCount )   // repeat forever or before the last loop
         {
         {
-          ResetValue( mCurrentFrameUpdated, mCurrentFrame, startFrame, mConditionalWait );  // If the current frame is changed in the event thread, don't overwrite it.
+          mCurrentFrame = mStartFrame;
           mUpdateFrameNumber = false;
         }
         else
         {
           animationFinished = true;   // end of animation
         }
           mUpdateFrameNumber = false;
         }
         else
         {
           animationFinished = true;   // end of animation
         }
-        ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait );
       }
     }
       }
     }
-    else if( currentFrame == startFrame && !mForward )  // first frame
+    else if( currentFrame == mStartFrame && !mForward )  // first frame
     {
     {
-      if( loopCount < 0 || ++currentLoopCount < loopCount )   // repeat forever or before the last loop
+      if( mLoopCount < 0 || ++mCurrentLoop < mLoopCount )   // repeat forever or before the last loop
       {
         mForward = true;
       }
       {
         mForward = true;
       }
@@ -491,7 +426,6 @@ bool VectorAnimationTask::Rasterize()
       {
         animationFinished = true;   // end of animation
       }
       {
         animationFinished = true;   // end of animation
       }
-      ResetValue( mCurrentLoopUpdated, mCurrentLoop, currentLoopCount, mConditionalWait );
     }
 
     if( animationFinished )
     }
 
     if( animationFinished )
@@ -517,9 +451,8 @@ bool VectorAnimationTask::Rasterize()
       DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Rendering failed. Try again later.[%d] [%p]\n", currentFrame, this );
       mUpdateFrameNumber = false;
 
       DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Rendering failed. Try again later.[%d] [%p]\n", currentFrame, this );
       mUpdateFrameNumber = false;
 
-      if( !resourceReady )
+      if( !mResourceReady )
       {
       {
-        ConditionalWait::ScopedLock lock( mConditionalWait );
         mResourceReady = false;
       }
     }
         mResourceReady = false;
       }
     }
@@ -527,23 +460,24 @@ bool VectorAnimationTask::Rasterize()
 
   if( stopped && renderSuccess )
   {
 
   if( stopped && renderSuccess )
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
-
     mPlayState = PlayState::STOPPED;
     mForward = true;
     mCurrentLoop = 0;
 
     // Animation is finished
     mPlayState = PlayState::STOPPED;
     mForward = true;
     mCurrentLoop = 0;
 
     // Animation is finished
-    if( needAnimationFinishedTrigger && mAnimationFinishedTrigger )
     {
     {
-      mAnimationFinishedTrigger->Trigger();
+      ConditionalWait::ScopedLock lock( mConditionalWait );
+      if( mNeedAnimationFinishedTrigger && mAnimationFinishedTrigger )
+      {
+        mAnimationFinishedTrigger->Trigger();
+      }
     }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this );
   }
 
   bool keepAnimation = true;
     }
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this );
   }
 
   bool keepAnimation = true;
-  if( playState == PlayState::PAUSED || playState == PlayState::STOPPED )
+  if( mPlayState == PlayState::PAUSED || mPlayState == PlayState::STOPPED )
   {
     keepAnimation = false;
   }
   {
     keepAnimation = false;
   }
@@ -604,6 +538,69 @@ std::chrono::time_point< std::chrono::system_clock > VectorAnimationTask::GetNex
   return mNextFrameStartTime;
 }
 
   return mNextFrameStartTime;
 }
 
+void VectorAnimationTask::ApplyAnimationData()
+{
+  uint32_t index;
+
+  {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
+
+    if( !mAnimationDataUpdated || mAnimationData[mAnimationDataIndex].resendFlag != 0 )
+    {
+      // Data is not updated or the previous data is not applied yet.
+      return;
+    }
+
+    mAnimationDataIndex = mAnimationDataIndex == 0 ? 1 : 0;  // Swap index
+    mAnimationDataUpdated = false;
+
+    index = mAnimationDataIndex;
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOP_COUNT )
+  {
+    SetLoopCount( mAnimationData[index].loopCount );
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_RANGE )
+  {
+    SetPlayRange( mAnimationData[index].playRange );
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_STOP_BEHAVIOR )
+  {
+    SetStopBehavior( mAnimationData[index].stopBehavior );
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOPING_MODE )
+  {
+    SetLoopingMode( mAnimationData[index].loopingMode );
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_CURRENT_FRAME )
+  {
+    SetCurrentFrameNumber( mAnimationData[index].currentFrame );
+  }
+
+  if( mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE )
+  {
+    if( mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING )
+    {
+      PlayAnimation();
+    }
+    else if( mAnimationData[index].playState == DevelImageVisual::PlayState::PAUSED )
+    {
+      PauseAnimation();
+    }
+    else if( mAnimationData[index].playState == DevelImageVisual::PlayState::STOPPED )
+    {
+      StopAnimation();
+    }
+  }
+
+  mAnimationData[index].resendFlag = 0;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index f2e3042..8e91788 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
 
 /*
 #define DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
  */
 
 // EXTERNAL INCLUDES
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/object/property-array.h>
 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
 #include <dali/devel-api/threading/conditional-wait.h>
 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
 #include <dali/devel-api/threading/conditional-wait.h>
@@ -51,6 +52,63 @@ public:
   using UploadCompletedSignalType = Dali::VectorAnimationRenderer::UploadCompletedSignalType;
 
   /**
   using UploadCompletedSignalType = Dali::VectorAnimationRenderer::UploadCompletedSignalType;
 
   /**
+   * Flags for re-sending data to the vector animation thread
+   */
+  enum ResendFlags
+  {
+    RESEND_PLAY_RANGE    = 1 << 0,
+    RESEND_LOOP_COUNT    = 1 << 1,
+    RESEND_STOP_BEHAVIOR = 1 << 2,
+    RESEND_LOOPING_MODE  = 1 << 3,
+    RESEND_CURRENT_FRAME = 1 << 4,
+    RESEND_SIZE          = 1 << 5,
+    RESEND_PLAY_STATE    = 1 << 6
+  };
+
+  /**
+   * @brief Structure used to pass parameters to the vector animation task
+   */
+  struct AnimationData
+  {
+    AnimationData()
+    : resendFlag( 0 ),
+      playRange(),
+      playState(),
+      stopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ),
+      loopingMode( DevelImageVisual::LoopingMode::RESTART ),
+      currentFrame( 0 ),
+      width( 0 ),
+      height( 0 ),
+      loopCount( -1 )
+    {
+    }
+
+    AnimationData& operator= ( const AnimationData& rhs )
+    {
+      resendFlag |= rhs.resendFlag; // OR resend flag
+      playRange = rhs.playRange;
+      playState = rhs.playState;
+      stopBehavior = rhs.stopBehavior;
+      loopingMode = rhs.loopingMode;
+      currentFrame = rhs.currentFrame;
+      width = rhs.width;
+      height = rhs.height;
+      loopCount = rhs.loopCount;
+      return *this;
+    }
+
+    uint32_t                             resendFlag;
+    Property::Array                      playRange;
+    DevelImageVisual::PlayState::Type    playState;
+    DevelImageVisual::StopBehavior::Type stopBehavior;
+    DevelImageVisual::LoopingMode::Type  loopingMode;
+    uint32_t                             currentFrame;
+    uint32_t                             width;
+    uint32_t                             height;
+    int32_t                              loopCount;
+  };
+
+  /**
    * @brief Constructor.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @brief Constructor.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
@@ -76,32 +134,10 @@ public:
   void SetRenderer( Renderer renderer );
 
   /**
   void SetRenderer( Renderer renderer );
 
   /**
-   * @brief Sets the target image size.
-   *
-   * @param[in] width The target image width
-   * @param[in] height The target image height
-   */
-  void SetSize( uint32_t width, uint32_t height );
-
-  /**
-   * @brief Play the vector animation.
-   */
-  void PlayAnimation();
-
-  /**
-   * @brief Stop the vector animation.
-   */
-  void StopAnimation();
-
-  /**
-   * @brief Pause the vector animation.
-   */
-  void PauseAnimation();
-
-  /**
-   * @brief Render one frame. The current frame number will be increased.
+   * @brief Sets data to specify animation playback.
+   * @param[in] data The animation data
    */
    */
-  void RenderFrame();
+  void SetAnimationData( const AnimationData& data );
 
   /**
    * @brief This callback is called after the animation is finished.
 
   /**
    * @brief This callback is called after the animation is finished.
@@ -110,19 +146,6 @@ public:
   void SetAnimationFinishedCallback( EventThreadCallback* callback );
 
   /**
   void SetAnimationFinishedCallback( EventThreadCallback* callback );
 
   /**
-   * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
-   * @param[in] count The number of times to loop
-   */
-  void SetLoopCount( int32_t count );
-
-  /**
-   * @brief Set the playing range in frame number.
-   * @param[in] playRange The array to specify minimum and maximum progress.
-   * The animation will play between those values.
-   */
-  void SetPlayRange( Property::Array& playRange );
-
-  /**
    * @brief Gets the playing range in frame number.
    * @param[out] startFrame The frame number to specify minimum progress.
    * @param[out] endFrame The frame number to specify maximum progress.
    * @brief Gets the playing range in frame number.
    * @param[out] startFrame The frame number to specify minimum progress.
    * @param[out] endFrame The frame number to specify maximum progress.
@@ -130,18 +153,6 @@ public:
   void GetPlayRange( uint32_t& startFrame, uint32_t& endFrame );
 
   /**
   void GetPlayRange( uint32_t& startFrame, uint32_t& endFrame );
 
   /**
-   * @brief Get the play state
-   * @return The play state
-   */
-  DevelImageVisual::PlayState::Type GetPlayState() const;
-
-  /**
-   * @brief Sets the current frame number of the animation.
-   * @param[in] frameNumber The new frame number between [0, the maximum frame number] or between the play range if specified.
-   */
-  void SetCurrentFrameNumber( uint32_t frameNumber );
-
-  /**
    * @brief Retrieves the current frame number of the animation.
    * @return The current frame number
    */
    * @brief Retrieves the current frame number of the animation.
    * @return The current frame number
    */
@@ -160,19 +171,6 @@ public:
   void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
 
   /**
   void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
 
   /**
-   * @brief Sets the stop behavior of the animation. This is performed when the animation is stopped.
-   * @param[in] stopBehavior The stop behavior
-   */
-  void SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior );
-
-  /**
-   * @brief Sets the looping mode.
-   * Animation plays forwards and then restarts from the beginning or runs backwards again.
-   * @param[in] loopingMode The looping mode
-   */
-  void SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode );
-
-  /**
    * @brief Gets the layer information of all the child layers.
    * @param[out] map The layer information
    */
    * @brief Gets the layer information of all the child layers.
    * @param[out] map The layer information
    */
@@ -210,10 +208,70 @@ private:
   void Initialize();
 
   /**
   void Initialize();
 
   /**
+   * @brief Play the vector animation.
+   */
+  void PlayAnimation();
+
+  /**
+   * @brief Stop the vector animation.
+   */
+  void StopAnimation();
+
+  /**
+   * @brief Pause the vector animation.
+   */
+  void PauseAnimation();
+
+  /**
+   * @brief Sets the target image size.
+   *
+   * @param[in] width The target image width
+   * @param[in] height The target image height
+   */
+  void SetSize( uint32_t width, uint32_t height );
+
+  /**
+   * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
+   * @param[in] count The number of times to loop
+   */
+  void SetLoopCount( int32_t count );
+
+  /**
+   * @brief Set the playing range in frame number.
+   * @param[in] playRange The array to specify minimum and maximum progress.
+   * The animation will play between those values.
+   */
+  void SetPlayRange( const Property::Array& playRange );
+
+  /**
+   * @brief Sets the current frame number of the animation.
+   * @param[in] frameNumber The new frame number between [0, the maximum frame number] or between the play range if specified.
+   */
+  void SetCurrentFrameNumber( uint32_t frameNumber );
+
+  /**
+   * @brief Sets the stop behavior of the animation. This is performed when the animation is stopped.
+   * @param[in] stopBehavior The stop behavior
+   */
+  void SetStopBehavior( DevelImageVisual::StopBehavior::Type stopBehavior );
+
+  /**
+   * @brief Sets the looping mode.
+   * Animation plays forwards and then restarts from the beginning or runs backwards again.
+   * @param[in] loopingMode The looping mode
+   */
+  void SetLoopingMode( DevelImageVisual::LoopingMode::Type loopingMode );
+
+  /**
    * @brief Gets the frame number when the animation is stopped according to the stop behavior.
    */
   uint32_t GetStoppedFrame( uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame );
 
    * @brief Gets the frame number when the animation is stopped according to the stop behavior.
    */
   uint32_t GetStoppedFrame( uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame );
 
+  /**
+   * @brief Applies the animation data set by the main thread.
+   */
+  void ApplyAnimationData();
+
   // Undefined
   VectorAnimationTask( const VectorAnimationTask& task ) = delete;
 
   // Undefined
   VectorAnimationTask( const VectorAnimationTask& task ) = delete;
 
@@ -232,10 +290,10 @@ private:
 
   std::string                            mUrl;
   VectorAnimationRenderer                mVectorRenderer;
 
   std::string                            mUrl;
   VectorAnimationRenderer                mVectorRenderer;
+  AnimationData                          mAnimationData[2];
   VectorAnimationThread&                 mVectorAnimationThread;
   ConditionalWait                        mConditionalWait;
   std::unique_ptr< EventThreadCallback > mAnimationFinishedTrigger;
   VectorAnimationThread&                 mVectorAnimationThread;
   ConditionalWait                        mConditionalWait;
   std::unique_ptr< EventThreadCallback > mAnimationFinishedTrigger;
-  Vector2                                mPlayRange;
   PlayState                              mPlayState;
   DevelImageVisual::StopBehavior::Type   mStopBehavior;
   DevelImageVisual::LoopingMode::Type    mLoopingMode;
   PlayState                              mPlayState;
   DevelImageVisual::StopBehavior::Type   mStopBehavior;
   DevelImageVisual::LoopingMode::Type    mLoopingMode;
@@ -248,14 +306,14 @@ private:
   uint32_t                               mEndFrame;
   uint32_t                               mWidth;
   uint32_t                               mHeight;
   uint32_t                               mEndFrame;
   uint32_t                               mWidth;
   uint32_t                               mHeight;
+  uint32_t                               mAnimationDataIndex;
   int32_t                                mLoopCount;
   int32_t                                mCurrentLoop;
   bool                                   mResourceReady;
   int32_t                                mLoopCount;
   int32_t                                mCurrentLoop;
   bool                                   mResourceReady;
-  bool                                   mCurrentFrameUpdated;
-  bool                                   mCurrentLoopUpdated;
   bool                                   mForward;
   bool                                   mUpdateFrameNumber;
   bool                                   mNeedAnimationFinishedTrigger;
   bool                                   mForward;
   bool                                   mUpdateFrameNumber;
   bool                                   mNeedAnimationFinishedTrigger;
+  bool                                   mAnimationDataUpdated;
 
 };
 
 
 };