Merge "Change RenderTaskList to behave like any other SceneGraph object" into devel...
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index 8b21b09..308b6a5 100644 (file)
 const uint32_t FRAME_COUNT_TRIGGER = 16;\
 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
   {\
-    if ( NULL != mImpl->root )\
+    for( auto root : mImpl->roots )
     {\
-      mImpl->frameCounter = 0;\
-      PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
+      if ( NULL != root )\
+      {\
+        mImpl->frameCounter = 0;\
+        PrintNodeTree( *root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
+      }\
     }\
   }\
 mImpl->frameCounter++;
@@ -188,10 +191,6 @@ struct UpdateManager::Impl
     renderInstructions( renderManager.GetRenderInstructionContainer() ),
     renderTaskProcessor( renderTaskProcessor ),
     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
-    taskList( renderMessageDispatcher ),
-    systemLevelTaskList( renderMessageDispatcher ),
-    root( NULL ),
-    systemLevelRoot( NULL ),
     renderers(),
     textureSets(),
     shaders(),
@@ -217,16 +216,13 @@ struct UpdateManager::Impl
   ~Impl()
   {
     // Disconnect render tasks from nodes, before destroying the nodes
-    RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
-    for ( auto&& iter : tasks )
+    for( auto taskList : taskLists )
     {
-      iter->SetSourceNode( NULL );
-    }
-    // ..repeat for system level RenderTasks
-    RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
-    for ( auto&& iter : systemLevelTasks )
-    {
-      iter->SetSourceNode( NULL );
+      RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
+      for ( auto&& task : tasks )
+      {
+        task->SetSourceNode( NULL );
+      }
     }
 
     // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
@@ -239,21 +235,9 @@ struct UpdateManager::Impl
       Node::Delete(*iter);
     }
 
-    // If there is root, reset it, otherwise do nothing as rendering was never started
-    if( root )
+    for( auto root : roots )
     {
       root->OnDestroy();
-
-      Node::Delete( root );
-      root = NULL;
-    }
-
-    if( systemLevelRoot )
-    {
-      systemLevelRoot->OnDestroy();
-
-      Node::Delete( systemLevelRoot );
-      systemLevelRoot = NULL;
     }
 
     delete sceneController;
@@ -288,16 +272,13 @@ struct UpdateManager::Impl
 
   Vector4                              backgroundColor;               ///< The glClear color used at the beginning of each frame.
 
-  RenderTaskList                       taskList;                      ///< The list of scene graph render-tasks
-  RenderTaskList                       systemLevelTaskList;           ///< Separate render-tasks for system-level content
+  OwnerContainer<RenderTaskList*>      taskLists;                     ///< A container of scene graph render task lists
 
-  Layer*                               root;                          ///< The root node (root is a layer)
-  Layer*                               systemLevelRoot;               ///< A separate root-node for system-level content
+  OwnerContainer<Layer*>               roots;                         ///< A container of root nodes (root is a layer). The layers are not stored in the node memory pool.
 
   Vector<Node*>                        nodes;                         ///< A container of all instantiated nodes
 
-  SortedLayerPointers                  sortedLayers;                  ///< A container of Layer pointers sorted by depth
-  SortedLayerPointers                  systemLevelSortedLayers;       ///< A separate container of system-level Layers
+  std::vector<SortedLayerPointers>     sortedLayerLists;              ///< A container of lists of Layer pointers sorted by depth (one list of sorted layers per root)
 
   OwnerContainer< Camera* >            cameras;                       ///< A container of cameras
   OwnerContainer< PropertyOwner* >     customObjects;                 ///< A container of owned objects (with custom properties)
@@ -362,26 +343,18 @@ UpdateManager::~UpdateManager()
   delete mImpl;
 }
 
-void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer, bool systemLevel )
+void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
 {
   DALI_ASSERT_DEBUG( layer->IsLayer() );
   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
 
-  if ( !systemLevel )
-  {
-    DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
-    mImpl->root = layer.Release();
-    mImpl->root->CreateTransform( &mImpl->transformManager );
-    mImpl->root->SetRoot(true);
-  }
-  else
-  {
-    DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
-    mImpl->systemLevelRoot = layer.Release();
-    mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
-    mImpl->systemLevelRoot->SetRoot(true);
-  }
+  Layer* rootLayer = layer.Release();
+
+  DALI_ASSERT_DEBUG( std::find( mImpl->roots.begin(), mImpl->roots.end(), rootLayer ) == mImpl->roots.end() && "Root Node already installed" );
 
+  rootLayer->CreateTransform( &mImpl->transformManager );
+  rootLayer->SetRoot(true);
+  mImpl->roots.PushBack( rootLayer );
 }
 
 void UpdateManager::AddNode( OwnerPointer<Node>& node )
@@ -475,6 +448,18 @@ void UpdateManager::RemoveObject( PropertyOwner* object )
   mImpl->customObjects.EraseObject( object );
 }
 
+void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
+{
+  RenderTaskList* taskListPointer = taskList.Release();
+  taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
+  mImpl->taskLists.PushBack( taskListPointer );
+}
+
+void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
+{
+  mImpl->taskLists.EraseObject( taskList );
+}
+
 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
 {
   mImpl->animations.PushBack( animation.Release() );
@@ -612,20 +597,6 @@ void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
   mImpl->textureSets.EraseObject( textureSet );
 }
 
-RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
-{
-  if ( !systemLevel )
-  {
-    // copy the list, this is only likely to happen once in application life cycle
-    return &(mImpl->taskList);
-  }
-  else
-  {
-    // copy the list, this is only likely to happen once in application life cycle
-    return &(mImpl->systemLevelTaskList);
-  }
-}
-
 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
 {
   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
@@ -738,18 +709,14 @@ void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
 
 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
 {
-  // Constrain system-level render-tasks
-  const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
-  for ( auto&& task : systemLevelTasks )
-  {
-    ConstrainPropertyOwner( *task, bufferIndex );
-  }
-
   // Constrain render-tasks
-  const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
-  for ( auto&& task : tasks )
+  for( auto taskList : mImpl->taskLists )
   {
-    ConstrainPropertyOwner( *task, bufferIndex );
+    RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
+    for ( auto&& task : tasks )
+    {
+      ConstrainPropertyOwner( *task, bufferIndex );
+    }
   }
 }
 
@@ -814,22 +781,13 @@ void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
 {
   mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
 
-  if ( !mImpl->root )
+  for( auto&& rootLayer : mImpl->roots )
   {
-    return;
-  }
-
-  // Prepare resources, update shaders, for each node
-  // And add the renderers to the sorted layers. Start from root, which is also a layer
-  mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
-                                          bufferIndex,
-                                          mImpl->renderQueue );
-
-  if ( mImpl->systemLevelRoot )
-  {
-    mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
-                                             bufferIndex,
-                                             mImpl->renderQueue );
+    // Prepare resources, update shaders, for each node
+    // And add the renderers to the sorted layers. Start from root, which is also a layer
+    mImpl->nodeDirtyFlags |= UpdateNodeTree( *rootLayer,
+                                            bufferIndex,
+                                            mImpl->renderQueue );
   }
 }
 
@@ -883,14 +841,12 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
     ConstrainCustomObjects( bufferIndex );
 
     //Clear the lists of renderers from the previous update
-    for( auto&& layer : mImpl->sortedLayers )
+    for( auto sortedLayers : mImpl->sortedLayerLists )
     {
-      layer->ClearRenderables();
-    }
-
-    for( auto&& layer : mImpl->systemLevelSortedLayers )
-    {
-      layer->ClearRenderables();
+      for( auto&& layer : sortedLayers )
+      {
+        layer->ClearRenderables();
+      }
     }
 
     //Update node hierarchy, apply constraints and perform sorting / culling.
@@ -926,25 +882,26 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
     //reset the update buffer index and make sure there is enough room in the instruction container
     if( mImpl->renderersAdded )
     {
-      mImpl->renderInstructions.ResetAndReserve( bufferIndex, mImpl->taskList.GetTaskCount() + mImpl->systemLevelTaskList.GetTaskCount() );
+      // Calculate how many render tasks we have in total
+      VectorBase::SizeType numberOfRenderTasks = 0;
+
+      const VectorBase::SizeType taskListCount = mImpl->taskLists.Count();
+      for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
+      {
+        numberOfRenderTasks += mImpl->taskLists[index]->GetTasks().Count();
+      }
 
-      if ( NULL != mImpl->root )
+      mImpl->renderInstructions.ResetAndReserve( bufferIndex,
+                                                 static_cast<uint32_t>( numberOfRenderTasks ) );
+
+      for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
       {
-        mImpl->renderTaskProcessor.Process( bufferIndex,
-                                            mImpl->taskList,
-                                            *mImpl->root,
-                                            mImpl->sortedLayers,
-                                            mImpl->renderInstructions,
-                                            renderToFboEnabled,
-                                            isRenderingToFbo );
-
-        // Process the system-level RenderTasks last
-        if ( NULL != mImpl->systemLevelRoot )
+        if ( NULL != mImpl->roots[index] )
         {
           mImpl->renderTaskProcessor.Process( bufferIndex,
-                                              mImpl->systemLevelTaskList,
-                                              *mImpl->systemLevelRoot,
-                                              mImpl->systemLevelSortedLayers,
+                                              *mImpl->taskLists[index],
+                                              *mImpl->roots[index],
+                                              mImpl->sortedLayerLists[index],
                                               mImpl->renderInstructions,
                                               renderToFboEnabled,
                                               isRenderingToFbo );
@@ -953,31 +910,36 @@ uint32_t UpdateManager::Update( float elapsedSeconds,
     }
   }
 
-  // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
-  bool doRenderOnceNotify = false;
-  mImpl->renderTaskWaiting = false;
-  for ( auto&& renderTask : mImpl->taskList.GetTasks() )
+  for( auto taskList : mImpl->taskLists )
   {
-    renderTask->UpdateState();
+    RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
 
-    if( renderTask->IsWaitingToRender() &&
-        renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
+    // check the countdown and notify
+    bool doRenderOnceNotify = false;
+    mImpl->renderTaskWaiting = false;
+    for ( auto&& renderTask : tasks )
     {
-      mImpl->renderTaskWaiting = true; // keep update/render threads alive
+      renderTask->UpdateState();
+
+      if( renderTask->IsWaitingToRender() &&
+          renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
+      {
+        mImpl->renderTaskWaiting = true; // keep update/render threads alive
+      }
+
+      if( renderTask->HasRendered() )
+      {
+        doRenderOnceNotify = true;
+      }
     }
 
-    if( renderTask->HasRendered() )
+    if( doRenderOnceNotify )
     {
-      doRenderOnceNotify = true;
+      DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
+      mImpl->notificationManager.QueueCompleteNotification( taskList->GetCompleteNotificationInterface() );
     }
   }
 
-  if( doRenderOnceNotify )
-  {
-    DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
-    mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
-  }
-
   // Macro is undefined in release build.
   SNAPSHOT_NODE_LOGGING;
 
@@ -1067,16 +1029,22 @@ void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavio
   mImpl->renderingBehavior = renderingBehavior;
 }
 
-void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
+void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
 {
-  if ( !systemLevel )
-  {
-    // just copy the vector of pointers
-    mImpl->sortedLayers = layers;
-  }
-  else
+  const VectorBase::SizeType rootCount = mImpl->roots.Count();
+
+  // Make sure we reserve the correct size for the container so that
+  // we can save the sorted layers in the same order as the root layer
+  mImpl->sortedLayerLists.resize( rootCount );
+
+  for ( VectorBase::SizeType rootIndex = 0u; rootIndex < rootCount; rootIndex++ )
   {
-    mImpl->systemLevelSortedLayers = layers;
+    Layer* root = mImpl->roots[rootIndex];
+    if ( root == rootLayer )
+    {
+      mImpl->sortedLayerLists[rootIndex] = layers;
+      break;
+    }
   }
 }
 
@@ -1089,8 +1057,11 @@ void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
     iter.node->SetDepthIndex( iter.sortedDepth );
   }
 
-  // Go through node hierarchy and rearrange siblings according to depth-index
-  SortSiblingNodesRecursively( *( mImpl->root ) );
+  for( auto root : mImpl->roots )
+  {
+    // Go through node hierarchy and rearrange siblings according to depth-index
+    SortSiblingNodesRecursively( *root );
+  }
 }
 
 bool UpdateManager::IsDefaultSurfaceRectChanged()