[Tizen](Vector) Ensure that all animation data is applied at once
authorJoogab Yun <joogab.yun@samsung.com>
Fri, 27 Dec 2019 08:49:02 +0000 (17:49 +0900)
committerJoogab Yun <joogab.yun@samsung.com>
Fri, 27 Dec 2019 08:50:13 +0000 (17:50 +0900)
This reverts commit e739aba4e8399de7126916116b8dbbcf0595928b.

Change-Id: I5a69c9dece6ff85a3c514ef89a516a45de04a966

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/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 TestApplication;
 
 namespace Integration
 {
@@ -83,6 +84,11 @@ public:
   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();
@@ -97,6 +103,7 @@ private:
   Dali::Adaptor::AdaptorSignalType mResizedSignal;
   Dali::Adaptor::AdaptorSignalType mLanguageChangedSignal;
   Dali::Adaptor::WindowCreatedSignalType mWindowCreatedSignal;
+  TestApplication* mTestApplication;
 };
 
 } // namespace Adaptor
index 5890d58..f84726b 100644 (file)
@@ -196,6 +196,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;
@@ -357,4 +374,14 @@ const LogFactoryInterface& Adaptor::GetLogFactory()
   return *gLogFactory;
 }
 
+void Adaptor::RegisterProcessor( Integration::Processor& processor )
+{
+  mImpl->RegisterProcessor( processor );
+}
+
+void Adaptor::UnregisterProcessor( Integration::Processor& processor )
+{
+  mImpl->UnregisterProcessor( processor );
+}
+
 } // namespace Dali
index f75123d..e77fc88 100644 (file)
@@ -54,6 +54,7 @@ ToolkitTestApplication::ToolkitTestApplication( size_t surfaceWidth, size_t surf
 
   // 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();
index 1fe89ea..af1fbb0 100644 (file)
@@ -1353,6 +1353,9 @@ int UtcDaliAnimatedVectorImageVisualControlVisibilityChanged(void)
   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 );
@@ -1397,6 +1400,9 @@ int UtcDaliAnimatedVectorImageVisualWindowVisibilityChanged(void)
   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 );
index 2ed0502..4661600 100644 (file)
@@ -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/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
@@ -46,19 +47,8 @@ namespace Internal
 namespace
 {
 
-constexpr auto LOOP_FOREVER = -1;
-
 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 )
@@ -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 ),
+  mAnimationData(),
   mVectorAnimationTask( new VectorAnimationTask( factoryCache, imageUrl.GetUrl() ) ),
   mImageVisualShaderFactory( shaderFactory ),
   mVisualSize(),
   mVisualScale( Vector2::ONE ),
-  mPlayRange(),
   mPlacementActor(),
-  mLoopCount( LOOP_FOREVER ),
-  mResendFlag( 0 ),
   mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP ),
-  mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ),
-  mLoopingMode( DevelImageVisual::LoopingMode::RESTART ),
-  mRendererAdded( false )
+  mRendererAdded( false ),
+  mRasterizationTriggered( false )
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
@@ -118,7 +105,13 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factor
 
 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
 {
-  // Finalize animation task in the main thread
+  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();
 }
 
@@ -147,7 +140,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   {
     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 );
@@ -161,8 +154,8 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   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 );
@@ -204,6 +197,8 @@ void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMa
        }
     }
   }
+
+  TriggerVectorRasterization();
 }
 
 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
@@ -215,8 +210,8 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       int32_t loopCount;
       if( value.Get( loopCount ) )
       {
-        mLoopCount = loopCount;
-        mResendFlag |= RESEND_LOOP_COUNT;
+        mAnimationData.loopCount = loopCount;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_LOOP_COUNT;
       }
       break;
     }
@@ -225,28 +220,28 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       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:
     {
-      int32_t stopBehavior = mStopBehavior;
+      int32_t stopBehavior = mAnimationData.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:
     {
-      int32_t loopingMode = mLoopingMode;
+      int32_t loopingMode = mAnimationData.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;
     }
@@ -308,6 +303,7 @@ void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
 void AnimatedVectorImageVisual::DoSetOffStage( Actor& actor )
 {
   StopAnimation();
+  SendAnimationData();
 
   if( mImpl->mRenderer )
   {
@@ -350,19 +346,13 @@ void AnimatedVectorImageVisual::OnSetTransform()
 
     SetVectorImageSize();
 
-    SendAnimationData();
-
-    if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
+    if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY && 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();
   }
 }
 
@@ -375,37 +365,32 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
     {
       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;
       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;
       break;
     }
     case DevelAnimatedVectorImageVisual::Action::STOP:
     {
-      if( mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::STOPPED )
+      if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
       {
-        mVectorAnimationTask->StopAnimation();
+        mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
+        mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
       }
-
-      if( mImpl->mRenderer )
-      {
-        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
-      }
-
       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
       break;
     }
@@ -414,13 +399,8 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       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;
     }
@@ -430,12 +410,21 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       if( map )
       {
         DoSetProperties( *map );
-
-        SendAnimationData();
       }
       break;
     }
   }
+
+  TriggerVectorRasterization();
+}
+
+void AnimatedVectorImageVisual::Process()
+{
+  SendAnimationData();
+
+  mRasterizationTriggered = false;
+
+  Adaptor::Get().UnregisterProcessor( *this );
 }
 
 void AnimatedVectorImageVisual::OnUploadCompleted()
@@ -461,6 +450,8 @@ void AnimatedVectorImageVisual::OnAnimationFinished()
   {
     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
 
+    mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
+
     if( mImpl->mEventObserver )
     {
       mImpl->mEventObserver->NotifyVisualEvent( *this, DevelAnimatedVectorImageVisual::Signal::ANIMATION_FINISHED );
@@ -475,49 +466,23 @@ void AnimatedVectorImageVisual::OnAnimationFinished()
 
 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 );
-    }
+    mVectorAnimationTask->SetAnimationData( mAnimationData );
 
-    if( mResendFlag & RESEND_STOP_BEHAVIOR )
-    {
-      mVectorAnimationTask->SetStopBehavior( mStopBehavior );
-    }
-
-    if( mResendFlag & RESEND_LOOPING_MODE )
-    {
-      mVectorAnimationTask->SetLoopingMode( mLoopingMode );
-    }
-
-    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
       {
-        mVectorAnimationTask->RenderFrame();
-        Stage::GetCurrent().KeepRendering( 0.0f );
+        mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
       }
     }
 
-    mResendFlag = 0;
+    mAnimationData.resendFlag = 0;
   }
 }
 
@@ -526,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 );
 
-  mVectorAnimationTask->SetSize( width, height );
-
-  if( IsOnStage() && mVectorAnimationTask->GetPlayState() != DevelImageVisual::PlayState::PLAYING )
-  {
-    mVectorAnimationTask->RenderFrame();
-    Stage::GetCurrent().KeepRendering( 0.0f );    // Trigger rendering
-  }
+  mAnimationData.width = width;
+  mAnimationData.height = height;
+  mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
 }
 
 void AnimatedVectorImageVisual::StopAnimation()
 {
-  if( mActionStatus != DevelAnimatedVectorImageVisual::Action::STOP )
+  if( mAnimationData.playState != DevelImageVisual::PlayState::STOPPED )
   {
-    mVectorAnimationTask->StopAnimation();
+    mAnimationData.playState = DevelImageVisual::PlayState::STOPPED;
+    mAnimationData.resendFlag |= VectorAnimationTask::RESEND_PLAY_STATE;
 
     mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
+  }
+}
 
-    if( mImpl->mRenderer )
-    {
-      mImpl->mRenderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
-    }
+void AnimatedVectorImageVisual::TriggerVectorRasterization()
+{
+  if( !mRasterizationTriggered )
+  {
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
+
+    Adaptor::Get().RegisterProcessor( *this );
+    mRasterizationTriggered = true;
   }
 }
 
@@ -562,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();
+    SendAnimationData();
+
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
   }
 }
 
@@ -577,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();
+    SendAnimationData();
+
+    Stage::GetCurrent().KeepRendering( 0.0f );  // Trigger event processing
   }
 }
 
@@ -585,6 +559,7 @@ void AnimatedVectorImageVisual::OnControlVisibilityChanged( Actor actor, bool vi
   if( !visible )
   {
     StopAnimation();
+    TriggerVectorRasterization();
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
@@ -595,6 +570,7 @@ void AnimatedVectorImageVisual::OnWindowVisibilityChanged( Window window, bool v
   if( !visible )
   {
     StopAnimation();
+    TriggerVectorRasterization();
 
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this );
   }
index 8aaed9c..0152869 100644 (file)
@@ -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/devel-api/actors/actor-devel.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>
@@ -55,7 +56,7 @@ using AnimatedVectorImageVisualPtr = IntrusivePtr< AnimatedVectorImageVisual >;
  * | url                      | STRING           |
  *
  */
-class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker
+class AnimatedVectorImageVisual: public Visual::Base, public ConnectionTracker, public Integration::Processor
 {
 public:
 
@@ -138,6 +139,13 @@ protected:
    */
   void OnDoAction( const Property::Index actionId, const Property::Value& attributes ) override;
 
+protected: // Implementation of Processor
+
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process() override;
+
 private:
 
   /**
@@ -173,6 +181,11 @@ private:
   void StopAnimation();
 
   /**
+   * @brief Trigger rasterization of the vector content.
+   */
+  void TriggerVectorRasterization();
+
+  /**
    * @brief Callback when the world scale factor changes.
    */
   void OnScaleNotification( PropertyNotification& source );
@@ -200,20 +213,17 @@ private:
 
 private:
   VisualUrl                                    mUrl;
+  VectorAnimationTask::AnimationData           mAnimationData;
   VectorAnimationTaskPtr                       mVectorAnimationTask;
   ImageVisualShaderFactory&                    mImageVisualShaderFactory;
   PropertyNotification                         mScaleNotification;
   PropertyNotification                         mSizeNotification;
   Vector2                                      mVisualSize;
   Vector2                                      mVisualScale;
-  Property::Array                              mPlayRange;
   WeakHandle< Actor >                          mPlacementActor;
-  int32_t                                      mLoopCount;
-  uint32_t                                     mResendFlag;
   DevelAnimatedVectorImageVisual::Action::Type mActionStatus;
-  DevelImageVisual::StopBehavior::Type         mStopBehavior;
-  DevelImageVisual::LoopingMode::Type          mLoopingMode;
   bool                                         mRendererAdded;
+  bool                                         mRasterizationTriggered;
 };
 
 } // namespace Internal
index f8598ab..bb6fb7e 100644 (file)
@@ -96,6 +96,8 @@ VectorAnimationTask::~VectorAnimationTask()
 
 void VectorAnimationTask::Finalize()
 {
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
   // Release some objects in the main thread
   if( mAnimationFinishedTrigger )
   {
@@ -114,11 +116,71 @@ void VectorAnimationTask::SetRenderer( Renderer renderer )
   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 );
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_LOOP_COUNT )
+  {
+    SetLoopCount( data.loopCount );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_PLAY_RANGE )
+  {
+    SetPlayRange( data.playRange );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_STOP_BEHAVIOR )
+  {
+    SetStopBehavior( data.stopBehavior );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_LOOPING_MODE )
+  {
+    SetLoopingMode( data.loopingMode );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_CURRENT_FRAME )
+  {
+    SetCurrentFrameNumber( data.currentFrame );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_SIZE )
+  {
+    SetSize( data.width, data.height );
+  }
+
+  if( data.resendFlag & VectorAnimationTask::RESEND_PLAY_STATE )
+  {
+    if( data.playState == DevelImageVisual::PlayState::PLAYING )
+    {
+      PlayAnimation();
+    }
+    else if( data.playState == DevelImageVisual::PlayState::PAUSED )
+    {
+      PauseAnimation();
+      RenderFrame();
+    }
+    else if( data.playState == DevelImageVisual::PlayState::STOPPED )
+    {
+      StopAnimation();
+    }
+  }
+  else
+  {
+    if( mPlayState == PlayState::PAUSED || mPlayState == PlayState::STOPPED )
+    {
+      RenderFrame();
+    }
+  }
+}
+
 void VectorAnimationTask::SetSize( uint32_t width, uint32_t height )
 {
   if( mWidth != width || mHeight != height )
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
     mVectorRenderer.SetSize( width, height );
 
     mWidth = width;
@@ -132,8 +194,6 @@ void VectorAnimationTask::SetSize( uint32_t width, uint32_t height )
 
 void VectorAnimationTask::PlayAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   if( mPlayState != PlayState::PLAYING )
   {
     mUpdateFrameNumber = false;
@@ -147,7 +207,6 @@ void VectorAnimationTask::PlayAnimation()
 
 void VectorAnimationTask::StopAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
   if( mPlayState != PlayState::STOPPED && mPlayState != PlayState::STOPPING )
   {
     mNeedAnimationFinishedTrigger = false;
@@ -159,7 +218,6 @@ void VectorAnimationTask::StopAnimation()
 
 void VectorAnimationTask::PauseAnimation()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
   if( mPlayState == PlayState::PLAYING )
   {
     mPlayState = PlayState::PAUSED;
@@ -170,8 +228,6 @@ void VectorAnimationTask::PauseAnimation()
 
 void VectorAnimationTask::RenderFrame()
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   if( !mResourceReady )
   {
     mVectorAnimationThread.AddTask( this );
@@ -193,8 +249,6 @@ void VectorAnimationTask::SetLoopCount( int32_t count )
 {
   if( mLoopCount != count )
   {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
-
     mLoopCount = count;
     mCurrentLoop = 0;
     mCurrentLoopUpdated = true;
@@ -203,10 +257,8 @@ void VectorAnimationTask::SetLoopCount( int32_t count )
   }
 }
 
-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();
@@ -332,8 +384,6 @@ DevelImageVisual::PlayState::Type VectorAnimationTask::GetPlayState() const
 
 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 );
@@ -373,7 +423,6 @@ void VectorAnimationTask::GetDefaultSize( uint32_t& width, uint32_t& height ) co
 
 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 );
@@ -381,7 +430,6 @@ void VectorAnimationTask::SetStopBehavior( DevelImageVisual::StopBehavior::Type
 
 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 );
@@ -418,7 +466,7 @@ void VectorAnimationTask::Initialize()
 
 bool VectorAnimationTask::Rasterize()
 {
-  bool stopped = false, needAnimationFinishedTrigger;
+  bool stopped = false, needAnimationFinishedTrigger, resourceReady;
   uint32_t currentFrame, startFrame, endFrame;
   int32_t loopCount, currentLoopCount;
   PlayState playState;
@@ -439,6 +487,7 @@ bool VectorAnimationTask::Rasterize()
     currentLoopCount = mCurrentLoop;
     needAnimationFinishedTrigger = mNeedAnimationFinishedTrigger;
     playState = mPlayState;
+    resourceReady = mResourceReady;
 
     mResourceReady = true;
     mCurrentFrameUpdated = false;
@@ -513,11 +562,19 @@ bool VectorAnimationTask::Rasterize()
     {
       DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Rendering failed. Try again later.[%d] [%p]\n", currentFrame, this );
       mUpdateFrameNumber = false;
+
+      if( !resourceReady )
+      {
+        ConditionalWait::ScopedLock lock( mConditionalWait );
+        mResourceReady = false;
+      }
     }
   }
 
   if( stopped && renderSuccess )
   {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
+
     mPlayState = PlayState::STOPPED;
     mForward = true;
     mCurrentLoop = 0;
index f2e3042..6fbd293 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 // 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>
@@ -51,6 +52,49 @@ public:
   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 )
+    {
+    }
+
+    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
@@ -76,32 +120,10 @@ public:
   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.
+   * @brief Sets data to specify animation playback.
+   * @param[in] data The animation data
    */
-  void PauseAnimation();
-
-  /**
-   * @brief Render one frame. The current frame number will be increased.
-   */
-  void RenderFrame();
+  void SetAnimationData( const AnimationData& data );
 
   /**
    * @brief This callback is called after the animation is finished.
@@ -110,19 +132,6 @@ public:
   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.
@@ -136,12 +145,6 @@ public:
   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
    */
@@ -160,19 +163,6 @@ public:
   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
    */
@@ -210,6 +200,66 @@ private:
   void Initialize();
 
   /**
+   * @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.
+   */
+  void RenderFrame();
+
+  /**
+   * @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 );
@@ -235,7 +285,6 @@ private:
   VectorAnimationThread&                 mVectorAnimationThread;
   ConditionalWait                        mConditionalWait;
   std::unique_ptr< EventThreadCallback > mAnimationFinishedTrigger;
-  Vector2                                mPlayRange;
   PlayState                              mPlayState;
   DevelImageVisual::StopBehavior::Type   mStopBehavior;
   DevelImageVisual::LoopingMode::Type    mLoopingMode;