If a RenderTask's exclusive actor is destoryed, then ensure the RenderTaskList of...
[platform/core/uifw/dali-core.git] / dali / internal / event / render-tasks / render-task-list-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index e7da30b..2ae57e8
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -21,7 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 #include <dali/internal/event/common/event-thread-services.h>
-#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/render-tasks/render-task-defaults.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/internal/event/actors/camera-actor-impl.h>
@@ -43,64 +43,49 @@ namespace Dali
 namespace Internal
 {
 
-RenderTaskList* RenderTaskList::New( EventThreadServices& eventServices, RenderTaskDefaults& defaults, bool systemLevel )
+RenderTaskListPtr RenderTaskList::New()
 {
-  RenderTaskList* taskList = new RenderTaskList( eventServices, defaults, systemLevel );
+  RenderTaskListPtr taskList = new RenderTaskList();
 
-  taskList->Initialize( eventServices.GetUpdateManager() );
+  taskList->Initialize();
 
   return taskList;
 }
 
-Dali::RenderTask RenderTaskList::CreateTask()
+RenderTaskPtr RenderTaskList::CreateTask()
 {
-  RenderTask* taskImpl = RenderTask::New( mIsSystemLevel );
-
-  Dali::RenderTask newTask( taskImpl );
-  mTasks.push_back( newTask );
-
-  if ( mSceneObject )
-  {
-    SceneGraph::RenderTask* sceneObject = taskImpl->CreateSceneObject();
-    DALI_ASSERT_DEBUG( NULL != sceneObject );
+  return CreateTask( &mDefaults.GetDefaultRootActor(), &mDefaults.GetDefaultCameraActor() );
+}
 
-    // Pass ownership to SceneGraph::RenderTaskList
-    AddTaskMessage( mEventThreadServices, *mSceneObject, *sceneObject );
-  }
+RenderTaskPtr RenderTaskList::CreateTask( Actor* sourceActor, CameraActor* cameraActor)
+{
+  RenderTaskPtr task = RenderTask::New( sourceActor, cameraActor, *this );
 
-  // Set the default source & camera actors
-  taskImpl->SetSourceActor( &mDefaults.GetDefaultRootActor() );
-  taskImpl->SetCameraActor( &mDefaults.GetDefaultCameraActor() );
+  mTasks.push_back( task );
 
-  return newTask;
+  return task;
 }
 
-void RenderTaskList::RemoveTask( Dali::RenderTask task )
+void RenderTaskList::RemoveTask( Internal::RenderTask& task )
 {
   for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
   {
-    if ( *iter == task )
-    {
-      RenderTask& taskImpl = GetImplementation( task );
-      if ( mSceneObject )
-      {
-        SceneGraph::RenderTask* sceneObject = taskImpl.GetRenderTaskSceneObject();
-        DALI_ASSERT_DEBUG( NULL != sceneObject );
-
-        // Send a message to remove the scene-graph RenderTask
-        RemoveTaskMessage( mEventThreadServices, *mSceneObject, *sceneObject );
+    RenderTask *ptr = iter->Get();
 
-        // The scene-graph RenderTask will be destroyed soon; discard the raw-pointer
-        taskImpl.DiscardSceneObject();
-      }
+    if ( ptr == &task )
+    {
+      const SceneGraph::RenderTask& sceneObject = task.GetRenderTaskSceneObject();
 
+      // delete the task
       mTasks.erase( iter );
+      // send a message to remove the scene-graph RenderTask
+      RemoveTaskMessage( mEventThreadServices, *mSceneObject, sceneObject );
 
-      for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
+      for ( auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt )
       {
-        if ( exclusiveIt->renderTaskPtr == &taskImpl )
+        if ( exclusiveIt->renderTaskPtr == ptr )
         {
-          mExclusives.Erase( exclusiveIt );
+          mExclusives.erase( exclusiveIt );
           break;
         }
       }
@@ -109,33 +94,33 @@ void RenderTaskList::RemoveTask( Dali::RenderTask task )
   }
 }
 
-unsigned int RenderTaskList::GetTaskCount() const
+uint32_t RenderTaskList::GetTaskCount() const
 {
-  return mTasks.size();
+  return static_cast<uint32_t>( mTasks.size() ); // only 4,294,967,295 render tasks supported
 }
 
-Dali::RenderTask RenderTaskList::GetTask( unsigned int index ) const
+RenderTaskPtr RenderTaskList::GetTask( uint32_t index ) const
 {
   DALI_ASSERT_ALWAYS( ( index < mTasks.size() ) && "RenderTask index out-of-range" );
 
-  return mTasks[index];
+  return mTasks[ index ];
 }
 
 void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive )
 {
   // Check to see if this rendertask has an entry?
-  for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
+  for ( auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt )
   {
     if ( exclusiveIt->renderTaskPtr == task )
     {
       if ( !exclusive )
       {
-        mExclusives.Erase( exclusiveIt );
+        mExclusives.erase( exclusiveIt );
         break;
       }
       else
       {
-        exclusiveIt->actorPtr = task->GetSourceActor();
+        exclusiveIt->actor.SetActor( task->GetSourceActor() );
         exclusive = false;
         break;
       }
@@ -145,30 +130,35 @@ void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive )
   {
     Exclusive exclusiveSlot;
     exclusiveSlot.renderTaskPtr = task;
-    exclusiveSlot.actorPtr = task->GetSourceActor();
-    mExclusives.PushBack( exclusiveSlot );
+    exclusiveSlot.actor.SetActor( task->GetSourceActor() );
+    mExclusives.emplace_back( std::move( exclusiveSlot ) );
   }
 }
 
-RenderTaskList::RenderTaskList( EventThreadServices& eventThreadServices, RenderTaskDefaults& defaults, bool systemLevel )
-: mEventThreadServices( eventThreadServices ),
-  mDefaults( defaults ),
-  mIsSystemLevel( systemLevel ),
-  mSceneObject( NULL )
+RenderTaskList::RenderTaskList()
+: mEventThreadServices( EventThreadServices::Get() ),
+  mDefaults( *Stage::GetCurrent() ),
+  mSceneObject( nullptr )
 {
 }
 
 RenderTaskList::~RenderTaskList()
 {
+  if( EventThreadServices::IsCoreRunning() && mSceneObject )
+  {
+    // Remove the render task list using a message to the update manager
+    RemoveRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), *mSceneObject );
+  }
 }
 
-void RenderTaskList::Initialize( UpdateManager& updateManager )
+void RenderTaskList::Initialize()
 {
-  // This should only be called once, with no existing scene-object
-  DALI_ASSERT_DEBUG( NULL == mSceneObject );
+  // Create a new render task list, Keep a const pointer to the render task list.
+  mSceneObject = SceneGraph::RenderTaskList::New();
+
+  OwnerPointer< SceneGraph::RenderTaskList > transferOwnership( const_cast< SceneGraph::RenderTaskList* >( mSceneObject ) );
+  AddRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), transferOwnership );
 
-  // Get raw-pointer to render task list
-  mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
   // set the callback to call us back when tasks are completed
   mSceneObject->SetCompleteNotificationInterface( this );
 }
@@ -177,43 +167,42 @@ void RenderTaskList::NotifyCompleted()
 {
   DALI_LOG_TRACE_METHOD(gLogRenderList);
 
-  std::vector< Dali::RenderTask > finishedRenderTasks;
+  RenderTaskContainer finishedRenderTasks;
 
   // Since render tasks can be unreferenced during the signal emissions, iterators into render tasks pointers may be invalidated.
   // First copy the finished render tasks, then emit signals
-  for ( std::vector<Dali::RenderTask>::iterator it = mTasks.begin(), endIt = mTasks.end(); it != endIt; ++it )
+  for ( RenderTaskContainer::iterator iter = mTasks.begin(), endIt = mTasks.end(); iter != endIt; ++iter )
   {
-    Dali::RenderTask& renderTask( *it );
-
-    if( GetImplementation( renderTask ).HasFinished() )
+    if( (*iter)->HasFinished() )
     {
-      finishedRenderTasks.push_back( Dali::RenderTask( renderTask ) );
+      finishedRenderTasks.push_back( *iter );
     }
   }
 
   // Now it's safe to emit the signals
-  for ( std::vector<Dali::RenderTask>::iterator it = finishedRenderTasks.begin(), endIt = finishedRenderTasks.end(); it != endIt; ++it )
+  for ( auto&& item : finishedRenderTasks )
   {
-    Dali::RenderTask& handle( *it );
-
-    GetImplementation(handle).EmitSignalFinish();
+    item->EmitSignalFinish();
   }
 }
 
 void RenderTaskList::RecoverFromContextLoss()
 {
-  for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
+  for ( auto&& item : mTasks )
   {
-    Dali::RenderTask task = *iter;
-
     // If the render target renders only once to an offscreen, re-render the render task
-    if( task.GetRefreshRate() == Dali::RenderTask::REFRESH_ONCE && task.GetTargetFrameBuffer() )
+    if( item->GetRefreshRate() == Dali::RenderTask::REFRESH_ONCE && item->GetTargetFrameBuffer() )
     {
-      task.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
+      item->SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
     }
   }
 }
 
+const SceneGraph::RenderTaskList& RenderTaskList::GetSceneObject() const
+{
+  return *mSceneObject;
+}
+
 } // namespace Internal
 
 } // namespace Dali