[Tizen] Revert "Support for recognizing legacy shaders."
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index 7a971f5..6cefe07 100644 (file)
 // CLASS HEADER
 #include <dali/internal/update/manager/update-manager.h>
 
 // CLASS HEADER
 #include <dali/internal/update/manager/update-manager.h>
 
+// EXTERNAL INCLUDES
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+#include <dali/devel-api/common/map-wrapper.h>
+#else
+#include <unordered_map>
+#endif
+
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
 
@@ -85,6 +92,27 @@ namespace SceneGraph
 {
 namespace
 {
 {
 namespace
 {
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+/**
+ * Flag whether property has changed, during the Update phase.
+ */
+enum ContainerRemovedFlagBits
+{
+  NOTHING               = 0x00,
+  NODE                  = 0x01,
+  RENDERER              = 0x02,
+  SHADER                = 0x04,
+  TEXTURE_SET           = 0x08,
+  ANIMATION             = 0x10,
+  PROPERTY_NOTIFICATION = 0x20,
+  CUSTOM_OBJECT         = 0x40,
+};
+
+/**
+ * @brief ContainerRemovedFlags alters behaviour of implementation
+ */
+using ContainerRemovedFlags = uint8_t;
+#endif
 /**
  * Helper to Erase an object from OwnerContainer using discard queue
  * @param container to remove from
 /**
  * Helper to Erase an object from OwnerContainer using discard queue
  * @param container to remove from
@@ -188,6 +216,9 @@ struct UpdateManager::Impl
     nodeDirtyFlags(NodePropertyFlags::TRANSFORM), // set to TransformFlag to ensure full update the first time through Update()
     frameCounter(0),
     renderingBehavior(DevelStage::Rendering::IF_REQUIRED),
     nodeDirtyFlags(NodePropertyFlags::TRANSFORM), // set to TransformFlag to ensure full update the first time through Update()
     frameCounter(0),
     renderingBehavior(DevelStage::Rendering::IF_REQUIRED),
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+    containerRemovedFlags(ContainerRemovedFlagBits::NOTHING),
+#endif
     animationFinishedDuringUpdate(false),
     previousUpdateScene(false),
     renderTaskWaiting(false),
     animationFinishedDuringUpdate(false),
     previousUpdateScene(false),
     renderTaskWaiting(false),
@@ -276,7 +307,12 @@ struct UpdateManager::Impl
 
   Vector<Node*> nodes; ///< A container of all instantiated nodes
 
 
   Vector<Node*> nodes; ///< A container of all instantiated nodes
 
-  std::unordered_map<uint32_t, Node*> nodeIdMap; ///< A container of nodes map by id.
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  using NodeIdMap = std::map<uint32_t, Node*>;
+#else
+  using NodeIdMap = std::unordered_map<uint32_t, Node*>;
+#endif
+  NodeIdMap nodeIdMap; ///< A container of nodes map by id.
 
   Vector<Camera*> cameras; ///< A container of cameras. Note : these cameras are owned by Impl::nodes.
 
 
   Vector<Camera*> cameras; ///< A container of cameras. Note : these cameras are owned by Impl::nodes.
 
@@ -313,6 +349,10 @@ struct UpdateManager::Impl
   uint32_t                 frameCounter;      ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
   DevelStage::Rendering    renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
 
   uint32_t                 frameCounter;      ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
   DevelStage::Rendering    renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
 
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  ContainerRemovedFlags containerRemovedFlags; ///< cumulative container removed flags during current frame
+#endif
+
   bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
   bool previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
   bool renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
   bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
   bool previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
   bool renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
@@ -465,6 +505,9 @@ void UpdateManager::DestroyNode(Node* node)
     if((*iter) == node)
     {
       mImpl->nodes.Erase(iter);
     if((*iter) == node)
     {
       mImpl->nodes.Erase(iter);
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+      mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::NODE;
+#endif
       break;
     }
   }
       break;
     }
   }
@@ -515,6 +558,9 @@ void UpdateManager::AddObject(OwnerPointer<PropertyOwner>& object)
 void UpdateManager::RemoveObject(PropertyOwner* object)
 {
   mImpl->customObjects.EraseObject(object);
 void UpdateManager::RemoveObject(PropertyOwner* object)
 {
   mImpl->customObjects.EraseObject(object);
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::CUSTOM_OBJECT;
+#endif
 }
 
 void UpdateManager::AddRenderTaskList(OwnerPointer<RenderTaskList>& taskList)
 }
 
 void UpdateManager::AddRenderTaskList(OwnerPointer<RenderTaskList>& taskList)
@@ -659,6 +705,9 @@ void UpdateManager::RemovePropertyNotification(PropertyNotification* propertyNot
   if(iter != mImpl->propertyNotifications.End())
   {
     mImpl->propertyNotifications.Erase(iter);
   if(iter != mImpl->propertyNotifications.End())
   {
     mImpl->propertyNotifications.Erase(iter);
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+    mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::PROPERTY_NOTIFICATION;
+#endif
   }
 }
 
   }
 }
 
@@ -677,6 +726,9 @@ void UpdateManager::RemoveShader(Shader* shader)
 {
   // Find the shader and destroy it
   EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
 {
   // Find the shader and destroy it
   EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::SHADER;
+#endif
 }
 
 void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
 }
 
 void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
@@ -715,6 +767,10 @@ void UpdateManager::RemoveRenderer(const RendererKey& rendererKey)
   EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
   // Need to remove the render object as well
   rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
   EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
   // Need to remove the render object as well
   rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
+
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::RENDERER;
+#endif
 }
 
 void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
 }
 
 void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
@@ -739,6 +795,9 @@ void UpdateManager::AddTextureSet(OwnerPointer<TextureSet>& textureSet)
 void UpdateManager::RemoveTextureSet(TextureSet* textureSet)
 {
   mImpl->textureSets.EraseObject(textureSet);
 void UpdateManager::RemoveTextureSet(TextureSet* textureSet)
 {
   mImpl->textureSets.EraseObject(textureSet);
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::TEXTURE_SET;
+#endif
 }
 
 uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene)
 }
 
 uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene)
@@ -853,6 +912,9 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
     if(animation->GetState() == Animation::Destroyed)
     {
       iter = mImpl->animations.Erase(iter);
     if(animation->GetState() == Animation::Destroyed)
     {
       iter = mImpl->animations.Erase(iter);
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+      mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::ANIMATION;
+#endif
     }
     else
     {
     }
     else
     {
@@ -1024,9 +1086,8 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     mImpl->frameCallbackProcessor ||                   // ..a frame callback processor is existed OR
     gestureUpdated;                                    // ..a gesture property was updated
 
     mImpl->frameCallbackProcessor ||                   // ..a frame callback processor is existed OR
     gestureUpdated;                                    // ..a gesture property was updated
 
-  uint32_t keepUpdating          = 0;
-  bool     keepRendererRendering = false;
-  mImpl->renderingRequired       = false;
+  uint32_t keepUpdating    = 0;
+  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.
 
   // 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.
@@ -1075,7 +1136,10 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     // Call the frame-callback-processor if set
     if(mImpl->frameCallbackProcessor)
     {
     // Call the frame-callback-processor if set
     if(mImpl->frameCallbackProcessor)
     {
-      keepRendererRendering |= mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
+      if(mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds))
+      {
+        keepUpdating |= KeepUpdating::FRAME_UPDATE_CALLBACK;
+      }
     }
 
     // Update node hierarchy, apply constraints,
     }
 
     // Update node hierarchy, apply constraints,
@@ -1117,7 +1181,9 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     if(mImpl->renderersAdded)
     {
       // Calculate how many render tasks we have in total
     if(mImpl->renderersAdded)
     {
       // Calculate how many render tasks we have in total
-      std::size_t numberOfRenderTasks = 0;
+      std::size_t numberOfRenderTasks        = 0;
+      std::size_t numberOfRenderInstructions = 0;
+      bool        renderContinuously         = false;
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->taskList)
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->taskList)
@@ -1126,8 +1192,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
         }
       }
 
         }
       }
 
-      std::size_t numberOfRenderInstructions = 0;
-      mImpl->renderInstructionCapacity       = 0u;
+      mImpl->renderInstructionCapacity = 0u;
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->root && scene->taskList && scene->scene)
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->root && scene->taskList && scene->scene)
@@ -1146,13 +1211,13 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
           // or keep rendering is requested
           if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
           {
           // or keep rendering is requested
           if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
           {
-            keepRendererRendering |= mImpl->renderTaskProcessor.Process(bufferIndex,
-                                                                        *scene->taskList,
-                                                                        *scene->root,
-                                                                        scene->sortedLayerList,
-                                                                        scene->scene->GetRenderInstructions(),
-                                                                        renderToFboEnabled,
-                                                                        isRenderingToFbo);
+            renderContinuously |= mImpl->renderTaskProcessor.Process(bufferIndex,
+                                                                     *scene->taskList,
+                                                                     *scene->root,
+                                                                     scene->sortedLayerList,
+                                                                     scene->scene->GetRenderInstructions(),
+                                                                     renderToFboEnabled,
+                                                                     isRenderingToFbo);
 
             mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
             scene->scene->SetSkipRendering(false);
 
             mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
             scene->scene->SetSkipRendering(false);
@@ -1166,6 +1231,11 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
         }
       }
 
         }
       }
 
+      if(renderContinuously)
+      {
+        keepUpdating |= KeepUpdating::RENDERER_CONTINUOUSLY;
+      }
+
       DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
     }
   }
       DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
     }
   }
@@ -1211,18 +1281,48 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   // Macro is undefined in release build.
   SNAPSHOT_NODE_LOGGING;
 
   // Macro is undefined in release build.
   SNAPSHOT_NODE_LOGGING;
 
+#if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
+  // Shrink relevant containers if required.
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::NODE)
+  {
+    mImpl->nodes.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::RENDERER)
+  {
+    mImpl->renderers.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::SHADER)
+  {
+    mImpl->shaders.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::TEXTURE_SET)
+  {
+    mImpl->textureSets.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::ANIMATION)
+  {
+    mImpl->animations.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::PROPERTY_NOTIFICATION)
+  {
+    mImpl->propertyNotifications.ShrinkToFitIfNeeded();
+  }
+  if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::CUSTOM_OBJECT)
+  {
+    mImpl->customObjects.ShrinkToFitIfNeeded();
+  }
+
+  // Reset flag
+  mImpl->containerRemovedFlags = ContainerRemovedFlagBits::NOTHING;
+#endif
+
   // A ResetProperties() may be required in the next frame
   mImpl->previousUpdateScene = updateScene;
 
   // Check whether further updates are required
   keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
 
   // A ResetProperties() may be required in the next frame
   mImpl->previousUpdateScene = updateScene;
 
   // Check whether further updates are required
   keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
 
-  if(keepRendererRendering)
-  {
-    keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
-  }
-
-  if(keepUpdating & KeepUpdating::STAGE_KEEP_RENDERING)
+  if(keepUpdating & (KeepUpdating::STAGE_KEEP_RENDERING | KeepUpdating::FRAME_UPDATE_CALLBACK | KeepUpdating::RENDERER_CONTINUOUSLY))
   {
     // Set dirty flags for next frame to continue rendering
     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
   {
     // Set dirty flags for next frame to continue rendering
     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;