Adding clear color to scene-graph Scene 39/321239/4
authorDavid Steele <david.steele@samsung.com>
Mon, 17 Mar 2025 18:58:03 +0000 (18:58 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 21 Mar 2025 11:00:34 +0000 (11:00 +0000)
Change-Id: Iee4f76dcb41feab4d0bce7d8bc2bc4cbbe7bcc58

automated-tests/src/dali-internal/utc-Dali-Internal-Core.cpp
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/common/scene-impl.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/update/common/scene-graph-scene.cpp
dali/internal/update/common/scene-graph-scene.h
dali/internal/update/manager/update-manager.cpp

index 9a20ada33a9bdb20c90a0ad71b79712733f969fe..971ff23001528568aab18bc0075fe178a470369d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -222,3 +222,30 @@ int UtcDaliCoreForceRelayout2(void)
 
   END_TEST;
 }
+
+int UtcDaliCoreClearScene(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::Integration::Core::ClearScene");
+
+  application.GetScene().SetBackgroundColor(Color::MAGENTA);
+
+  TestGraphicsController& controller = application.GetGraphicsController();
+  auto&                   contTrace  = controller.mCallStack;
+  auto&                   cmdTrace   = controller.mCommandBufferCallStack;
+  contTrace.Enable(true);
+  contTrace.EnableLogging(true);
+  cmdTrace.Enable(true);
+  cmdTrace.EnableLogging(true);
+
+  application.SendNotification();
+  application.Render();
+
+  auto& core = application.GetCore();
+  core.ClearScene(application.GetScene());
+
+  DALI_TEST_CHECK(cmdTrace.FindMethod("BeginRenderPass"));
+  DALI_TEST_CHECK(contTrace.FindMethod("SubmitCommandBuffers"));
+  DALI_TEST_CHECK(contTrace.FindMethod("PresentRenderTarget"));
+  END_TEST;
+}
index 30f734544ff09d1919a40d7398eca36456e06113..9e352f1787f264121aee59b7bd335ceea1e87b9d 100644 (file)
@@ -124,6 +124,11 @@ void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool ren
   mImpl->RenderScene(status, scene, renderToFbo, clippingRect);
 }
 
+void Core::ClearScene(Integration::Scene scene)
+{
+  mImpl->ClearScene(scene);
+}
+
 void Core::PostRender()
 {
   mImpl->PostRender();
index b0f09746b502b54384f888c5e0b5d7cfb43a988d..4c3070fdc76460b76d9afd23dc705f0d354b215f 100644 (file)
@@ -383,6 +383,14 @@ public:
    */
   void RenderScene(RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect<int>& clippingRect);
 
+  /**
+   * Clear the scene's surface if there is nothing else to draw.
+   *
+   * Don't need to call this if there is something to draw;
+   * @param[in] scene The scene to be cleared.
+   */
+  void ClearScene(Integration::Scene scene);
+
   /**
    * This is called after rendering all the scenes in the next frame. This method should be
    * followed by a call to RenderScene.
index 22d037dd2a3666e0592d601427a9be85175edd4a..0d8bef354709febc9be31221dc800a9d6e733bfc 100644 (file)
@@ -231,6 +231,11 @@ void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool ren
   mRenderManager->RenderScene(status, scene, renderToFbo, clippingRect);
 }
 
+void Core::ClearScene(Integration::Scene scene)
+{
+  mRenderManager->ClearScene(scene);
+}
+
 void Core::PostRender()
 {
   mUpdateManager->PostRender();
index 502043ba272427d6fce4dbac265abc45b1e8d220..87a4a353b9853390d1b93ee11f19119edcf1029b 100644 (file)
@@ -141,6 +141,11 @@ public:
    */
   void RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect<int>& clippingRect);
 
+  /**
+   * @copydoc Dali::Integration::Core::ClearScene()
+   */
+  void ClearScene(Integration::Scene scene);
+
   /**
    * @copydoc Dali::Integration::Core::Render()
    */
index 38c54a3441c3577b0c4ae5e101aefadf5061b18e..721ef6aab9a6a11285252921dbaa7d43869d6176 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -332,8 +332,15 @@ void Scene::SetBackgroundColor(const Vector4& color)
 {
   mBackgroundColor = color;
 
+  // Normally, clear color is taken from render instruction, so set the
+  // background color to the render task (which generates render instructions).
   mRenderTaskList->GetTask(0u)->SetClearColor(color);
   mRenderTaskList->GetTask(0u)->SetClearEnabled(true);
+
+  // But, if nothing is drawn, and a clear is required, then there are no
+  // render instructions, so we need to get it from the scene object instead.
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  SetClearColorMessage(tls->GetEventThreadServices(), *mSceneObject, color);
 }
 
 Vector4 Scene::GetBackgroundColor() const
index 1f0a039481e1e3c5e37ce2c0156faa9c16f1f977..2fc5d34a1348f6579895c2e7feff0a1958d91404 100644 (file)
@@ -1386,6 +1386,47 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
   }
 }
 
+void RenderManager::ClearScene(Integration::Scene scene)
+{
+  Internal::Scene&   sceneInternal = GetImplementation(scene);
+  SceneGraph::Scene* sceneObject   = sceneInternal.GetSceneObject();
+  if(!sceneObject)
+  {
+    return;
+  }
+
+  auto& currentClearValues = sceneObject->GetGraphicsRenderPassClearValues();
+  DALI_ASSERT_DEBUG(!currentClearValues.empty());
+
+  Graphics::RenderTarget* currentRenderTarget = sceneObject->GetSurfaceRenderTarget();
+  Graphics::RenderPass*   currentRenderPass   = sceneObject->GetGraphicsRenderPass(
+    Graphics::AttachmentLoadOp::CLEAR, Graphics::AttachmentStoreOp::STORE);
+
+  Rect<int32_t>    surfaceRect = sceneObject->GetSurfaceRect();
+  Graphics::Rect2D scissorArea{0, 0, uint32_t(surfaceRect.width), uint32_t(surfaceRect.height)};
+  int32_t          surfaceOrientation = sceneObject->GetSurfaceOrientation() + sceneObject->GetScreenOrientation();
+  if(surfaceOrientation >= 360)
+  {
+    surfaceOrientation -= 360;
+  }
+  scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, surfaceRect);
+
+  auto commandBuffer = mImpl->graphicsController.CreateCommandBuffer(Graphics::CommandBufferCreateInfo().SetLevel(Graphics::CommandBufferLevel::PRIMARY), nullptr);
+  commandBuffer->Begin(Graphics::CommandBufferBeginInfo()
+                         .SetUsage(0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT)
+                         .SetRenderTarget(*currentRenderTarget));
+
+  commandBuffer->BeginRenderPass(currentRenderPass, currentRenderTarget, scissorArea, currentClearValues);
+  commandBuffer->EndRenderPass(nullptr);
+  commandBuffer->End();
+
+  Graphics::SubmitInfo submitInfo;
+  submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
+  submitInfo.cmdBuffer.push_back(commandBuffer.get());
+  mImpl->graphicsController.SubmitCommandBuffers(submitInfo);
+  mImpl->graphicsController.PresentRenderTarget(currentRenderTarget);
+}
+
 void RenderManager::PostRender()
 {
   if(!mImpl->commandBufferSubmitted)
index a0a43df4c4b0c9a7a758e9aa944bcdafd506fea7..2f7ab509439b45775db08ca3c892b8e063dcd392 100644 (file)
@@ -414,6 +414,16 @@ public:
    */
   void RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect<int>& clippingRect);
 
+  /**
+   * Clear the scene's surface.
+   *
+   * Note, this does not need to be called if there is something to render.
+   *
+   * Multi-threading note: this method should be called from a dedicated rendering thread.
+   * @param[in] scene The scene to be rendered.
+   */
+  void ClearScene(Integration::Scene scene);
+
   // This method should be called from Core::PostRender()
 
   /**
index 73ddffe6c70a3ee480d1e58328071517b83ff374..a3268cd188c43f13b23b42a11cefa04e478d083a 100644 (file)
@@ -19,6 +19,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/core-enumerations.h>
+#include <dali/internal/update/controllers/render-message-dispatcher.h>
 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
 
 namespace Dali
@@ -28,7 +29,8 @@ namespace Internal
 namespace SceneGraph
 {
 Scene::Scene()
-: mFrameRenderedCallbacks(),
+: mRenderMessageDispatcher(nullptr),
+  mFrameRenderedCallbacks(),
   mFramePresentedCallbacks(),
   mSurfaceRect(),
   mSurfaceOrientation(0),
@@ -47,6 +49,30 @@ Scene::~Scene()
   mFramePresentedCallbacks.clear();
 }
 
+void Scene::SetRenderMessageDispatcher(RenderMessageDispatcher* messageDispatcher)
+{
+  mRenderMessageDispatcher = messageDispatcher;
+}
+
+void Scene::SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
+{
+  if(mRenderTarget != nullptr &&
+     mRenderTargetCreateInfo.surface != renderTargetCreateInfo.surface)
+  {
+    // Only recreate if the surface has changed.
+    mRenderTargetCreateInfo = renderTargetCreateInfo;
+    if(mGraphicsController) // shouldn't be null, as we can't have already set mRenderTarget unless graphics controller exists.
+    {
+      mRenderTarget = mGraphicsController->CreateRenderTarget(renderTargetCreateInfo, std::move(mRenderTarget));
+    }
+  }
+  else
+  {
+    // 2nd Stage initialization happens in RenderManager, not UpdateManager, so is delayed.
+    mRenderTargetCreateInfo = renderTargetCreateInfo;
+  }
+}
+
 void Scene::Initialize(Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable)
 {
   mGraphicsController = &graphicsController;
@@ -92,7 +118,7 @@ void Scene::Initialize(Graphics::Controller& graphicsController, Integration::De
   rpInfo.SetAttachments(attachmentDescriptions);
 
   // Add default render pass (loadOp = clear)
-  mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr); // Warning: Shallow ptr
+  mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr);
 
   desc.SetLoadOp(Graphics::AttachmentLoadOp::LOAD);
   attachmentDescriptions[0] = desc;
@@ -227,23 +253,18 @@ Scene::ItemsDirtyRectsContainer& Scene::GetItemsDirtyRects()
   return mItemsDirtyRects;
 }
 
-void Scene::SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
+void Scene::SetClearColor(const Vector4& color)
 {
-  if(mRenderTarget != nullptr &&
-     mRenderTargetCreateInfo.surface != renderTargetCreateInfo.surface)
-  {
-    // Only recreate if the surface has changed.
-    mRenderTargetCreateInfo = renderTargetCreateInfo;
-    if(mGraphicsController) // shouldn't be null, as we can't have already set mRenderTarget unless graphics controller exists.
-    {
-      mRenderTarget = mGraphicsController->CreateRenderTarget(renderTargetCreateInfo, std::move(mRenderTarget));
-    }
-  }
-  else
-  {
-    // 2nd Stage initialization happens in RenderManager, not UpdateManager, so is delayed.
-    mRenderTargetCreateInfo = renderTargetCreateInfo;
-  }
+  DALI_ASSERT_DEBUG(!mClearValues.empty());
+  mClearValues[0].color = {color.r, color.g, color.b, color.a};
+}
+
+void Scene::SetClearColorInRenderQ(const Vector4& color)
+{
+  // Tramp the color through the render manager's queue to ensure it happens after Initialize().
+  using DerivedType = MessageValue1<Scene, Vector4>;
+  uint32_t* slot    = mRenderMessageDispatcher->ReserveMessageSlot(sizeof(DerivedType));
+  new(slot) DerivedType(this, &Scene::SetClearColor, color);
 }
 
 void Scene::KeepRendering(float durationSeconds)
index b66c2cdbc8466fb01d751607ff10a23273394614..6951a92c172a763fc0d42af321dd2ff8edc50bbf 100644 (file)
@@ -43,6 +43,7 @@ namespace Internal
 {
 namespace SceneGraph
 {
+class RenderMessageDispatcher;
 class RenderInstructionContainer;
 class Node;
 
@@ -109,6 +110,15 @@ struct DirtyRectValue
   bool          visited{true};
 };
 
+/**
+ * SceneGraph::Scene is a core object representing the window and it's scene-graph. It's used in both
+ * UpdateManager and RenderManager, so has to live in both worlds, and has to know how to send
+ * messages to itself to be run in RenderManager's Queue.
+ *
+ * Initialization is tricky - the Scene's render target has to be setup in RenderManager, so needs
+ * mRenderTargetCreateInfo to be defined before Initialize is called in RenderManage's Queue.
+ * Also, a scene's background color may also get set before Initialize is called.
+ */
 class Scene
 {
 public:
@@ -120,7 +130,6 @@ public:
 
   /**
    * Constructor
-   * @param[in] surface The render surface
    */
   Scene();
 
@@ -130,7 +139,25 @@ public:
   virtual ~Scene();
 
   /**
-   * Creates a scene object in the GPU.
+   * Set the render message dispatcher.
+   * Called from UpdateManagerQueue, before Initialize.
+   */
+  void SetRenderMessageDispatcher(RenderMessageDispatcher* dispatcher);
+
+  /**
+   * Set the render target of the surface
+   * Called from UpdateManager Queue, before Initialize
+   *
+   * @param[in] renderTarget The render target.
+   */
+  void SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo);
+
+  /**
+   * Creates a scene object
+   * Note, this is run inside RenderManager Queue, not UpdateManagerQueue.
+   * So, other APIs must also run inside RenderManager Queue if they need
+   * to run afterwards.
+   *
    * @param[in] graphicsController The graphics controller
    * @param[in] depthBufferAvailable True if there is a depth buffer
    * @param[in] stencilBufferAvailable True if there is a stencil buffer
@@ -262,11 +289,23 @@ public:
   bool IsRotationCompletedAcknowledgementSet();
 
   /**
-   * Set the render target of the surface
+   * @brief Set the clear color for the scene's render passes
    *
-   * @param[in] renderTarget The render target.
+   * @note Normally, the render instruction's clear color is used (from the render task).
+   *
+   * @param[in] color The color to clear for the render passes
    */
-  void SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo);
+  void SetClearColor(const Vector4& color);
+
+  /**
+   * @brief Set the clear color for the scene's ClearOp render pass
+   *
+   * @note Needs to run after 2nd stage Initialize in RenderManagerQ, so
+   * has to re-send.
+   *
+   * @param[in] color The color to clear for the render pass
+   */
+  void SetClearColorInRenderQ(const Vector4& color);
 
   /**
    * @brief Keep rendering for at least the given amount of time.
@@ -386,7 +425,8 @@ private:
 
   RenderInstructionContainer mInstructions; ///< Render instructions for the scene
 
-  Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
+  RenderMessageDispatcher* mRenderMessageDispatcher{nullptr}; ///< RenderManager message dispatcher
+  Graphics::Controller*    mGraphicsController{nullptr};      ///< Graphics controller
 
   Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks;  ///< Frame rendered callbacks
   Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
@@ -513,6 +553,17 @@ inline void SetPartialUpdateEnabledMessage(EventThreadServices& eventThreadServi
   new(slot) LocalType(&scene, &Scene::SetPartialUpdateEnabled, enabled);
 }
 
+inline void SetClearColorMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Vector4& color)
+{
+  using LocalType = MessageValue1<Scene, Vector4>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&scene, &Scene::SetClearColorInRenderQ, color);
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 6926e64c9780fded132fe38b50c8fd87076ec78b..cb1fc4f0d39e39d4e619ea2945404e2f1c51a83d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -182,11 +182,11 @@ struct UpdateManager::Impl
     {
     }
 
-    ~SceneInfo()               = default;                ///< Default non-virtual destructor
-    SceneInfo(SceneInfo&& rhs) = default;                ///< Move constructor
-    SceneInfo& operator=(SceneInfo&& rhs) = default;     ///< Move assignment operator
-    SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
-    SceneInfo(const SceneInfo& rhs)            = delete; ///< Copy constructor
+    ~SceneInfo()                               = default; ///< Default non-virtual destructor
+    SceneInfo(SceneInfo&& rhs)                 = default; ///< Move constructor
+    SceneInfo& operator=(SceneInfo&& rhs)      = default; ///< Move assignment operator
+    SceneInfo& operator=(const SceneInfo& rhs) = delete;  ///< Assignment operator
+    SceneInfo(const SceneInfo& rhs)            = delete;  ///< Copy constructor
 
     Layer*                       root{nullptr};   ///< Root node (root is a layer). The layer is not stored in the node memory pool.
     OwnerPointer<RenderTaskList> taskList;        ///< Scene graph render task list
@@ -457,7 +457,8 @@ void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
 
   Layer* rootLayer = layer.Release();
 
-  DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
+  DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene)
+                                 { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
                     "Root Node already installed");
 
   rootLayer->CreateTransform(&mImpl->transformManager);
@@ -652,6 +653,7 @@ void UpdateManager::AddScene(OwnerPointer<Scene>& scene)
 
   // Set root to the Scene
   sceneInfo->scene->SetRoot(sceneInfo->root);
+  sceneInfo->scene->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher);
 
   // Initialize the context from render manager
   typedef MessageValue1<RenderManager, SceneGraph::Scene*> DerivedType;
@@ -979,9 +981,8 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
 
   auto&& iter = mImpl->animations.Begin();
 
-  DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss) {
-    oss << "[" << mImpl->animations.Count() << "]";
-  });
+  DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss)
+                                          { oss << "[" << mImpl->animations.Count() << "]"; });
 
   while(iter != mImpl->animations.End())
   {
@@ -1032,9 +1033,8 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
     mImpl->notificationManager.QueueNotification(&mImpl->animationPlaylist, std::move(mImpl->notifyRequiredAnimations));
   }
 
-  DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss) {
-    oss << "[" << mImpl->animations.Count() << "]";
-  });
+  DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss)
+                                        { oss << "[" << mImpl->animations.Count() << "]"; });
 
   return animationActive;
 }
@@ -1129,9 +1129,8 @@ void UpdateManager::UpdateRenderers(PropertyOwnerContainer& postPropertyOwners,
     return;
   }
 
-  DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_RENDERERS", [&](std::ostringstream& oss) {
-    oss << "[" << mImpl->renderers.Count() << "]";
-  });
+  DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_RENDERERS", [&](std::ostringstream& oss)
+                                          { oss << "[" << mImpl->renderers.Count() << "]"; });
 
   for(const auto& rendererKey : mImpl->renderers)
   {
@@ -1231,14 +1230,14 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
   if(updateScene || mImpl->previousUpdateScene)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_INTERNAL", [&](std::ostringstream& oss) {
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_INTERNAL", [&](std::ostringstream& oss)
+                                            {
       oss << "[n:" << mImpl->nodes.Size() << ",";
       oss << "c:" << mImpl->customObjects.Size() << ",";
       oss << "a:" << mImpl->animations.Size() << ",";
       oss << "r:" << mImpl->renderers.Size() << ",";
       oss << "t:" << mImpl->textureSets.Size() << ",";
-      oss << "s:" << mImpl->shaders.Size() << "]";
-    });
+      oss << "s:" << mImpl->shaders.Size() << "]"; });
 
     // Animate
     bool animationActive = Animate(bufferIndex, elapsedSeconds);
@@ -1588,7 +1587,8 @@ void UpdateManager::SetDepthIndices(OwnerPointer<NodeDepths>& nodeDepths)
     {
       // Reorder children container only if sibiling order changed.
       NodeContainer& container = node->GetChildren();
-      std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
+      std::sort(container.Begin(), container.End(), [](Node* a, Node* b)
+                { return a->GetDepthIndex() < b->GetDepthIndex(); });
     }
   }
 }