Revert "[Tizen] Revert "Skip rendering if no animation is currently active""
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 19 Nov 2020 02:45:18 +0000 (11:45 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 19 Nov 2020 02:54:52 +0000 (11:54 +0900)
This reverts commit 35952536d36e03b9ddf5356a8844a959644bbf55.

Change-Id: I1b6e5a772ef79dbbfb809c23e80f47f8a8ed080e

dali/internal/event/actors/actor-impl.cpp
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/manager/transform-manager.cpp
dali/internal/update/manager/transform-manager.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h

index eccc527..f4a1067 100755 (executable)
@@ -835,6 +835,8 @@ void Actor::SetOpacity( float opacity )
 
   // node is being used in a separate thread; queue a message to set the value & base value
   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity );
+
+  RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
 }
 
 float Actor::GetCurrentOpacity() const
@@ -854,6 +856,8 @@ void Actor::SetColor( const Vector4& color )
 
   // node is being used in a separate thread; queue a message to set the value & base value
   SceneGraph::NodePropertyMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color );
+
+  RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
 }
 
 void Actor::SetColorRed( float red )
@@ -862,6 +866,8 @@ void Actor::SetColorRed( float red )
 
   // node is being used in a separate thread; queue a message to set the value & base value
   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red );
+
+  RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
 }
 
 void Actor::SetColorGreen( float green )
@@ -870,6 +876,8 @@ void Actor::SetColorGreen( float green )
 
   // node is being used in a separate thread; queue a message to set the value & base value
   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green );
+
+  RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
 }
 
 void Actor::SetColorBlue( float blue )
@@ -878,6 +886,8 @@ void Actor::SetColorBlue( float blue )
 
   // node is being used in a separate thread; queue a message to set the value & base value
   SceneGraph::NodePropertyComponentMessage<Vector4>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue );
+
+  RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
 }
 
 const Vector4& Actor::GetCurrentColor() const
@@ -2493,6 +2503,8 @@ void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
     {
       // node is being used in a separate thread; queue a message to set the value & base value
       SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible );
+
+      RequestRenderingMessage( GetEventThreadServices().GetUpdateManager() );
     }
 
     mVisible = visible;
index 3a95d54..aa01b10 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.
@@ -78,7 +78,8 @@ Animation::Animation( float durationSeconds, float speedFactor, const Vector2& p
   mDisconnectAction(disconnectAction),
   mState(Stopped),
   mProgressReachedSignalRequired( false ),
-  mAutoReverseEnabled( false )
+  mAutoReverseEnabled( false ),
+  mIsActive{ false }
 {
 }
 
@@ -424,6 +425,8 @@ void Animation::Update( BufferIndex bufferIndex, float elapsedSeconds, bool& loo
 
 void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished )
 {
+  mIsActive[bufferIndex] = false;
+
   const Vector2 playRange( mPlayRange * mDurationSeconds );
   float elapsedSecondsClamped = Clamp( mElapsedSeconds, playRange.x, playRange.y );
 
@@ -454,6 +457,11 @@ void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animat
             progress = Clamp((elapsedSecondsClamped - intervalDelay) / animatorDuration, 0.0f , 1.0f );
           }
           animator->Update(bufferIndex, progress, bake);
+
+          if (animatorDuration > 0.0f && (elapsedSecondsClamped - intervalDelay) <= animatorDuration)
+          {
+            mIsActive[bufferIndex] = true;
+          }
         }
         applied = true;
       }
index a4e309f..0617041 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_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.
@@ -259,6 +259,16 @@ public:
   }
 
   /**
+   * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
+   * @return True if the animation is currently active
+   */
+  bool IsActive() const
+  {
+    // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
+    return mIsActive[0] || mIsActive[1];
+  }
+
+  /**
    * @brief Sets the looping mode.
    *
    * Animation plays forwards and then restarts from the beginning or runs backwards again.
@@ -349,6 +359,7 @@ protected:
 
   bool mProgressReachedSignalRequired;  // Flag to indicate the progress marker was hit
   bool mAutoReverseEnabled;             // Flag to identify that the looping mode is auto reverse.
+  bool mIsActive[2];                    // Flag to indicate whether the animation is active in the current frame (which is double buffered)
 };
 
 }; //namespace SceneGraph
index a51b0d7..277ccfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 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.
@@ -228,8 +228,10 @@ void TransformManager::ResetToBaseValue()
   }
 }
 
-void TransformManager::Update()
+bool TransformManager::Update()
 {
+  bool componentsChanged = false;
+
   if( mReorder )
   {
     //If some transform component has change its parent or has been removed since last update
@@ -321,8 +323,11 @@ void TransformManager::Update()
     mBoundingSpheres[i] = mWorld[i].GetTranslation();
     mBoundingSpheres[i].w = Length( centerToEdgeWorldSpace );
 
+    componentsChanged = componentsChanged || mComponentDirty[i];
     mComponentDirty[i] = false;
   }
+
+  return componentsChanged;
 }
 
 void TransformManager::SwapComponents( unsigned int i, unsigned int j )
@@ -381,31 +386,26 @@ Vector3& TransformManager::GetVector3PropertyValue( TransformId id, TransformMan
     case TRANSFORM_PROPERTY_POSITION:
     {
       TransformId index( mIds[id] );
-      mComponentDirty[ index ] = true;
       return mTxComponentAnimatable[ index ].mPosition;
     }
     case TRANSFORM_PROPERTY_SCALE:
     {
       TransformId index( mIds[id] );
-      mComponentDirty[ index ] = true;
       return mTxComponentAnimatable[ index ].mScale;
     }
     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
     {
       TransformId index( mIds[id] );
-      mComponentDirty[ index ] = true;
       return mTxComponentStatic[ index ].mParentOrigin;
     }
     case TRANSFORM_PROPERTY_ANCHOR_POINT:
     {
       TransformId index( mIds[id] );
-      mComponentDirty[ index ] = true;
       return mTxComponentStatic[ index ].mAnchorPoint;
     }
     case TRANSFORM_PROPERTY_SIZE:
     {
       TransformId index( mIds[id] );
-      mComponentDirty[ index ] = true;
       return mSize[ index ];
     }
     default:
@@ -834,7 +834,6 @@ void TransformManager::BakeZVector3PropertyValue( TransformId id, TransformManag
 Quaternion& TransformManager::GetQuaternionPropertyValue( TransformId id )
 {
   TransformId index( mIds[id] );
-  mComponentDirty[ index ] = true;
   return mTxComponentAnimatable[ index ].mOrientation;
 }
 
index d003f57..068c39f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_TRANSFORM_MANAGER_H
 
 /*
- * Copyright (c) 2018 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.
@@ -192,8 +192,9 @@ public:
 
   /**
    * Recomputes all world transform matrices
+   * @return true if any component has been changed in this frame, false otherwise
    */
-  void Update();
+  bool Update();
 
   /**
    * Resets all the animatable properties to its base value
index f29997a..ce30100 100644 (file)
@@ -189,7 +189,8 @@ struct UpdateManager::Impl
     previousUpdateScene( false ),
     renderTaskWaiting( false ),
     renderersAdded( false ),
-    surfaceRectChanged( false )
+    surfaceRectChanged( false ),
+    renderingRequired( false )
   {
     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
 
@@ -298,6 +299,7 @@ struct UpdateManager::Impl
   bool                                 renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
   bool                                 renderersAdded;                ///< Flag to keep track when renderers have been added to avoid unnecessary processing
   bool                                 surfaceRectChanged;            ///< True if the default surface rect is changed
+  bool                                 renderingRequired;             ///< True if required to render the current frame
 
 private:
 
@@ -734,8 +736,10 @@ bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSync
   return gestureUpdated;
 }
 
-void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
+bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
 {
+  bool animationActive = false;
+
   auto&& iter = mImpl->animations.Begin();
   bool animationLooped = false;
 
@@ -747,6 +751,8 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
     bool progressMarkerReached = false;
     animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
 
+    animationActive = animationActive || animation->IsActive();
+
     if ( progressMarkerReached )
     {
       mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
@@ -772,6 +778,8 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
     // The application should be notified by NotificationManager, in another thread
     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
   }
+
+  return animationActive;
 }
 
 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
@@ -852,7 +860,7 @@ void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
     //Apply constraints
     ConstrainPropertyOwner( *renderer, bufferIndex );
 
-    renderer->PrepareRender( bufferIndex );
+    mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
   }
 }
 
@@ -884,17 +892,20 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
   //Clear nodes/resources which were previously discarded
   mImpl->discardQueue.Clear( bufferIndex );
 
+  bool isAnimationRunning = IsAnimationRunning();
+
   //Process Touches & Gestures
   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
 
   bool updateScene = // The scene-graph requires an update if..
       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
-      IsAnimationRunning()                            ||    // ..at least one animation is running OR
+      isAnimationRunning                              ||    // ..at least one animation is running OR
       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
       mImpl->frameCallbackProcessor                   ||    // ..a frame callback processor is existed OR
       gestureUpdated;                                       // ..a gesture property was updated
 
   bool keepRendererRendering = false;
+  mImpl->renderingRequired = false;
 
   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
   // values if the scene was updated in the previous frame.
@@ -919,7 +930,7 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
   if( updateScene || mImpl->previousUpdateScene )
   {
     //Animate
-    Animate( bufferIndex, elapsedSeconds );
+    bool animationActive = Animate( bufferIndex, elapsedSeconds );
 
     //Constraint custom objects
     ConstrainCustomObjects( bufferIndex );
@@ -957,7 +968,10 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
     UpdateRenderers( bufferIndex );
 
     //Update the transformations of all the nodes
-    mImpl->transformManager.Update();
+    if ( mImpl->transformManager.Update() )
+    {
+      mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
+    }
 
     //Process Property Notifications
     ProcessPropertyNotifications( bufferIndex );
@@ -982,7 +996,6 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
         }
       }
 
-
       std::size_t numberOfRenderInstructions = 0;
       for ( auto&& scene : mImpl->scenes )
       {
@@ -991,13 +1004,19 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
           scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
                                                      static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
 
-          keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
-                                              *scene->taskList,
-                                              *scene->root,
-                                              scene->sortedLayerList,
-                                              scene->scene->GetRenderInstructions(),
-                                              renderToFboEnabled,
-                                              isRenderingToFbo );
+          // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
+          // or the nodes are dirty
+          if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
+          {
+            keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
+                                                *scene->taskList,
+                                                *scene->root,
+                                                scene->sortedLayerList,
+                                                scene->scene->GetRenderInstructions(),
+                                                renderToFboEnabled,
+                                                isRenderingToFbo );
+
+          }
 
           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
         }
@@ -1150,6 +1169,11 @@ void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavio
   mImpl->renderingBehavior = renderingBehavior;
 }
 
+void UpdateManager::RequestRendering()
+{
+  mImpl->renderingRequired = true;
+}
+
 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
 {
   for ( auto&& scene : mImpl->scenes )
index 194dd29..0954733 100644 (file)
@@ -650,6 +650,14 @@ public:
   void SetRenderingBehavior( DevelStage::Rendering renderingBehavior );
 
   /**
+   * Request to render the current frame
+   * @note This is a temporary workaround (to be removed in the future) to request the rendering of
+   *       the current frame if the color or visibility of any actor is updated. It MUST NOT be used
+   *       for any other purposes.
+   */
+  void RequestRendering();
+
+  /**
    * Sets the depths of all layers.
    * @param layers The layers in depth order.
    * @param[in] rootLayer The root layer of the sorted layers.
@@ -715,8 +723,9 @@ private:
    * Perform animation updates
    * @param[in] bufferIndex to use
    * @param[in] elapsedSeconds time since last frame
+   * @return true if at least one animations is currently active or false otherwise
    */
-  void Animate( BufferIndex bufferIndex, float elapsedSeconds );
+  bool Animate( BufferIndex bufferIndex, float elapsedSeconds );
 
   /**
    * Applies constraints to CustomObjects
@@ -1125,6 +1134,17 @@ inline void SetRenderingBehaviorMessage( UpdateManager& manager, DevelStage::Ren
   new (slot) LocalType( &manager, &UpdateManager::SetRenderingBehavior, renderingBehavior );
 }
 
+inline void RequestRenderingMessage( UpdateManager& manager )
+{
+  using LocalType = Message<UpdateManager>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = manager.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &manager, &UpdateManager::RequestRendering );
+}
+
 /**
  * Create a message for setting the depth of a layer
  * @param[in] manager The update manager
index e821f6e..cce7464 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 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.
@@ -181,7 +181,7 @@ void Renderer::operator delete( void* ptr )
 }
 
 
-void Renderer::PrepareRender( BufferIndex updateBufferIndex )
+bool Renderer::PrepareRender( BufferIndex updateBufferIndex )
 {
   if( mRegenerateUniformMap == UNIFORM_MAP_READY )
   {
@@ -221,6 +221,8 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
     mRegenerateUniformMap--;
   }
 
+  bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag;
+
   if( mResendFlag != 0 )
   {
     if( mResendFlag & RESEND_GEOMETRY )
@@ -365,6 +367,8 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
 
     mResendFlag = 0;
   }
+
+  return rendererUpdated;
 }
 
 void Renderer::SetTextures( TextureSet* textureSet )
index b3ab63e..a06fa2a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_RENDERER_H
 
 /*
- * Copyright (c) 2018 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.
@@ -339,8 +339,9 @@ public:
    * Prepare the object for rendering.
    * This is called by the UpdateManager when an object is due to be rendered in the current frame.
    * @param[in] updateBufferIndex The current update buffer index.
+   * @return Whether this renderer has been updated in the current frame
    */
-  void PrepareRender( BufferIndex updateBufferIndex );
+  bool PrepareRender( BufferIndex updateBufferIndex );
 
   /**
    * Retrieve the Render thread renderer