Merge "Added memory pool logging" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 16 Dec 2022 11:45:52 +0000 (11:45 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 16 Dec 2022 11:45:52 +0000 (11:45 +0000)
36 files changed:
automated-tests/src/dali/utc-Dali-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/common/fixed-size-memory-pool.cpp
dali/internal/common/fixed-size-memory-pool.h
dali/internal/common/memory-pool-object-allocator.h
dali/internal/event/images/pixel-data-impl.cpp
dali/internal/event/images/pixel-data-impl.h
dali/internal/event/size-negotiation/relayout-controller-impl.cpp
dali/internal/event/size-negotiation/relayout-controller-impl.h
dali/internal/render/common/render-instruction-container.cpp
dali/internal/render/common/render-instruction-container.h
dali/internal/render/common/render-instruction.cpp
dali/internal/render/common/render-instruction.h
dali/internal/render/common/render-item.cpp
dali/internal/render/common/render-item.h
dali/internal/render/queue/render-queue.cpp
dali/internal/render/queue/render-queue.h
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/internal/update/queue/update-message-queue.cpp
dali/internal/update/queue/update-message-queue.h
dali/internal/update/render-tasks/scene-graph-render-task-list.cpp
dali/internal/update/render-tasks/scene-graph-render-task-list.h
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/internal/update/rendering/scene-graph-texture-set.cpp
dali/internal/update/rendering/scene-graph-texture-set.h
dali/public-api/images/pixel-data.cpp
dali/public-api/images/pixel-data.h

index 67d14a5..ae881b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -50,3 +50,14 @@ int UtcDaliCoreGetObjectRegistry(void)
   DALI_TEST_CHECK(application.GetCore().GetObjectRegistry());
   END_TEST;
 }
+
+int UtcDaliCoreCheckMemoryPool(void)
+{
+  TestApplication application;
+
+  // Calling LogMemoryPools should check capacity across the board.
+  application.GetCore().LogMemoryPools();
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 05f6d52..870861b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -145,6 +145,11 @@ ObjectRegistry Core::GetObjectRegistry() const
   return ObjectRegistry(&mImpl->GetObjectRegistry());
 }
 
+void Core::LogMemoryPools() const
+{
+  mImpl->LogMemoryPools();
+}
+
 Core::Core()
 : mImpl(nullptr)
 {
index 0a4ce07..0b44348 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTEGRATION_CORE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -409,6 +409,11 @@ public:
    */
   ObjectRegistry GetObjectRegistry() const;
 
+  /**
+   * Log core's memory pool's capacities
+   */
+  void LogMemoryPools() const;
+
 private:
   /**
    * Private constructor; see also Core::New()
index 9a5c89e..28b8a6c 100644 (file)
@@ -138,6 +138,10 @@ Core::Core(RenderController&                   renderController,
   mUpdateManager->SetShaderSaver(*mShaderFactory);
 
   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
+
+  DALI_LOG_RELEASE_INFO("Node size: %lu\n", sizeof(Dali::Internal::SceneGraph::Node));
+  DALI_LOG_RELEASE_INFO("Renderer size: %lu\n", sizeof(Dali::Internal::SceneGraph::Renderer));
+  DALI_LOG_RELEASE_INFO("RenderItem size: %lu\n", sizeof(Dali::Internal::SceneGraph::RenderItem));
 }
 
 Core::~Core()
@@ -484,6 +488,47 @@ ObjectRegistry& Core::GetObjectRegistry() const
   return *(mObjectRegistry.Get());
 }
 
+void Core::LogMemoryPools() const
+{
+  uint32_t animationPoolCapacity    = SceneGraph::Animation::GetMemoryPoolCapacity();
+  uint32_t renderItemPoolCapacity   = SceneGraph::RenderItem::GetMemoryPoolCapacity();
+  uint32_t relayoutItemPoolCapacity = mRelayoutController->GetMemoryPoolCapacity();
+  uint32_t rendererPoolCapacity     = SceneGraph::Renderer::GetMemoryPoolCapacity();
+  uint32_t textureSetPoolCapacity   = SceneGraph::TextureSet::GetMemoryPoolCapacity();
+  uint32_t renderTaskPoolCapacity   = SceneGraph::RenderTaskList::GetMemoryPoolCapacity();
+  uint32_t nodePoolCapacity         = SceneGraph::Node::GetMemoryPoolCapacity();
+
+  DALI_LOG_RELEASE_INFO(
+    "\nMemory Pool capacities:\n"
+    "  Animations:    %lu\n"
+    "  RenderItems:   %lu\n"
+    "  RelayoutItems: %lu\n"
+    "  Renderers:     %lu\n"
+    "  TextureSets:   %lu\n"
+    "  RenderTasks:   %lu\n"
+    "  Nodes:         %lu\n",
+    animationPoolCapacity,
+    renderItemPoolCapacity,
+    relayoutItemPoolCapacity,
+    rendererPoolCapacity,
+    textureSetPoolCapacity,
+    renderTaskPoolCapacity,
+    nodePoolCapacity);
+
+  uint32_t updateQCapacity = mUpdateManager->GetUpdateMessageQueueCapacity();
+  uint32_t renderQCapacity = mUpdateManager->GetRenderMessageQueueCapacity();
+
+  DALI_LOG_RELEASE_INFO(
+    "\nMessage Queue capacities:\n"
+    "  UpdateQueue: %lu\n"
+    "  RenderQueue: %lu\n",
+    updateQCapacity,
+    renderQCapacity);
+
+  size_t renderInstructionCapacity = mUpdateManager->GetRenderInstructionCapacity();
+  DALI_LOG_RELEASE_INFO("\nRenderInstruction capacity: %lu\n", renderInstructionCapacity);
+}
+
 EventThreadServices& Core::GetEventThreadServices()
 {
   return *this;
index 8d218aa..5c21a44 100644 (file)
@@ -198,6 +198,11 @@ public:
    */
   ObjectRegistry& GetObjectRegistry() const;
 
+  /**
+   * Log the capacity of DALi memory pools
+   */
+  void LogMemoryPools() const;
+
 public: // Implementation of EventThreadServices
   /**
    * @copydoc EventThreadServices::RegisterObject
index 452437c..f225a8d 100644 (file)
@@ -231,6 +231,22 @@ void FixedSizeMemoryPool::FreeThreadSafe(void* memory)
   }
 }
 
+uint32_t FixedSizeMemoryPool::GetCapacity() const
+{
+  // Ignores deleted objects list, just returns currently allocated size
+  uint32_t totalAllocation = 0;
+#ifdef DEBUG_ENABLED
+  Mutex::ScopedLock lock(mImpl->mMutex);
+  Impl::Block*      block = &mImpl->mMemoryBlocks;
+  while(block)
+  {
+    totalAllocation += block->mBlockSize;
+    block = block->nextBlock;
+  }
+#endif
+  return totalAllocation;
+}
+
 } // namespace Internal
 
 } // namespace Dali
index ff4138d..6e05ffe 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_FIXED_SIZE_MEMORY_POOL_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -97,6 +97,13 @@ public:
    */
   void FreeThreadSafe(void* memory);
 
+  /**
+   * Get the current capacity of the memory pool
+   *
+   * @note in release mode, this returns 0, as the block size isn't defined.
+   */
+  uint32_t GetCapacity() const;
+
 private:
   // Undefined
   FixedSizeMemoryPool(const FixedSizeMemoryPool& fixedSizeMemoryPool);
index 7b6ab96..554ce9a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_MEMORY_POOL_OBJECT_ALLOCATOR_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -154,6 +154,14 @@ public:
     mPool = new FixedSizeMemoryPool(TypeSizeWithAlignment<T>::size);
   }
 
+  /**
+   * @brief Get the capacity of the memory pool
+   */
+  uint32_t GetCapacity() const
+  {
+    return mPool->GetCapacity();
+  }
+
 private:
   // Undefined
   MemoryPoolObjectAllocator(const MemoryPoolObjectAllocator& memoryPoolObjectAllocator);
index 622f867..745896a 100644 (file)
 // CLASS HEADER
 #include <dali/internal/event/images/pixel-data-impl.h>
 
+#include <dali/integration-api/debug.h>
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gPixelDataLogFilter = Debug::Filter::New(Debug::NoLogging, false, "DALI_LOG_PIXEL_DATA_SIZE");
+#endif
+
 namespace Dali
 {
 namespace Internal
 {
+#if defined(DEBUG_ENABLED)
+// Only track data allocation if debug is enabled
+uint32_t PixelData::gPixelDataAllocationTotal{0};
+#endif
+
 PixelData::PixelData(uint8_t*                         buffer,
                      uint32_t                         bufferSize,
                      uint32_t                         width,
@@ -37,6 +48,10 @@ PixelData::PixelData(uint8_t*                         buffer,
   mPixelFormat(pixelFormat),
   mReleaseFunction(releaseFunction)
 {
+  DALI_LOG_INFO(gPixelDataLogFilter, Debug::Concise, "Allocated PixelData of size %u\n", bufferSize);
+#if defined(DEBUG_ENABLED)
+  gPixelDataAllocationTotal += mBufferSize;
+#endif
 }
 
 PixelData::~PixelData()
@@ -51,6 +66,9 @@ PixelData::~PixelData()
     {
       delete[] mBuffer;
     }
+#if defined(DEBUG_ENABLED)
+    gPixelDataAllocationTotal -= mBufferSize;
+#endif
   }
 }
 
index 5667496..746d347 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/images/pixel-data-devel.h>
+#include <dali/integration-api/debug.h>
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/object/base-object.h>
 
@@ -121,6 +122,18 @@ public:
    */
   uint32_t GetStride() const;
 
+  /**
+   * Class method to get the total currently allocated size of pixel buffers
+   */
+  static uint32_t GetTotalAllocatedSize()
+  {
+#if defined(DEBUG_ENABLED)
+    return gPixelDataAllocationTotal;
+#else
+    return 0;
+#endif
+  }
+
 private:
   /*
    * Undefined copy constructor.
@@ -140,6 +153,10 @@ private:
   uint32_t                         mStride;          ///< Buffer stride in pixels, 0 means the buffer is tightly packed
   Pixel::Format                    mPixelFormat;     ///< Pixel format
   Dali::PixelData::ReleaseFunction mReleaseFunction; ///< Function for releasing memory
+
+#if defined(DEBUG_ENABLED)
+  static uint32_t gPixelDataAllocationTotal;
+#endif
 };
 
 } // namespace Internal
index 1589d94..dd0f98d 100644 (file)
@@ -500,6 +500,11 @@ void RelayoutController::FindAndZero(const RawActorList& list, const Dali::RefOb
   }
 }
 
+uint32_t RelayoutController::GetMemoryPoolCapacity()
+{
+  return mRelayoutInfoAllocator.GetCapacity();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 85cb31a..29809ea 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -124,6 +124,12 @@ public:
    */
   void SetProcessingCoreEvents(bool processingEvents);
 
+  /**
+   * Get the capacity of the memory pool containing relayout info
+   * (It Should be regularly purged!)
+   */
+  uint32_t GetMemoryPoolCapacity();
+
 public: // CALLBACKS
   /**
    * @brief Callback raised after the application creates the scene
index 6ae3c5b..37900ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -62,6 +62,17 @@ void RenderInstructionContainer::PushBack(BufferIndex bufferIndex, RenderInstruc
   mInstructions.push_back(renderInstruction);
 }
 
+std::size_t RenderInstructionContainer::GetCapacity() const
+{
+  std::size_t capacity{0};
+  for(auto& el : mInstructions)
+  {
+    capacity += el->GetCapacity();
+  }
+  capacity += mInstructions.size() * sizeof(RenderInstruction*);
+  return capacity;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 9417afe..f2292c7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_CONTAINER_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -22,6 +22,7 @@
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/internal/common/buffer-index.h>
 #include <dali/public-api/common/vector-wrapper.h>
+#include <cstddef>
 
 namespace Dali
 {
@@ -75,6 +76,11 @@ public:
    */
   void PushBack(BufferIndex index, RenderInstruction* renderInstruction);
 
+  /**
+   * Get the total memory used by all the render instructions
+   */
+  std::size_t GetCapacity() const;
+
 private:
   std::vector<RenderInstruction*> mInstructions;
 };
index acde57b..f42041f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -125,6 +125,20 @@ void RenderInstruction::Reset(Camera*              camera,
   }
 }
 
+std::size_t RenderInstruction::GetCapacity()
+{
+  std::size_t                        capacity{0u};
+  RenderListContainer::Iterator      iter = mRenderLists.Begin();
+  RenderListContainer::ConstIterator end  = mRenderLists.End();
+  for(; iter != end; ++iter)
+  {
+    capacity += ((*iter)->GetCachedItemCount() * (sizeof(RenderItem) + sizeof(RenderItem*)));
+    capacity += sizeof(RenderList);
+  }
+  capacity += sizeof(RenderInstruction);
+  return capacity;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 52e7e68..f8d24aa 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -129,6 +129,11 @@ public:
     return mCamera;
   }
 
+  /**
+   * Get the total memory usage of the render instruction
+   */
+  std::size_t GetCapacity();
+
 public:                                  // Data
   Render::RenderTracker* mRenderTracker; ///< Pointer to an optional tracker object (not owned)
 
index fabaccc..1aafa37 100644 (file)
@@ -167,6 +167,11 @@ void RenderItem::operator delete(void* ptr)
   gRenderItemPool.Free(static_cast<RenderItem*>(ptr));
 }
 
+uint32_t RenderItem::GetMemoryPoolCapacity()
+{
+  return gRenderItemPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 2fe74bd..0a82320 100644 (file)
@@ -99,6 +99,11 @@ struct RenderItem
   bool              mIsOpaque : 1;
   bool              mIsUpdated : 1;
 
+  /**
+   * Get the capacity of the global pool.
+   */
+  static uint32_t GetMemoryPoolCapacity();
+
 private:
   /**
    * Private constructor. See RenderItem::New
index 49cd12f..ca582ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -80,6 +80,9 @@ uint32_t* RenderQueue::ReserveMessageSlot(BufferIndex updateBufferIndex, std::si
 
 void RenderQueue::ProcessMessages(BufferIndex bufferIndex)
 {
+  std::size_t capacity = container0->GetCapacity() + container1->GetCapacity();
+  mCapacity            = capacity; // write is atomic.
+
   MessageBuffer* container = GetCurrentContainer(bufferIndex);
 
   for(MessageBuffer::Iterator iter = container->Begin(); iter.IsValid(); iter.Next())
index 4739889..0df8060 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_QUEUE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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,6 +21,8 @@
 // INTERNAL INCLUDES
 #include <dali/internal/common/buffer-index.h>
 #include <dali/internal/common/message-buffer.h>
+#include <atomic>
+#include <cstddef>
 
 namespace Dali
 {
@@ -63,6 +65,14 @@ public:
    */
   void ProcessMessages(BufferIndex bufferIndex);
 
+  /**
+   * Return the current capacity total of both buffers.
+   */
+  std::size_t GetCapacity() const
+  {
+    return mCapacity;
+  }
+
 private:
   /**
    * Helper to retrieve the current container.
@@ -87,6 +97,8 @@ private:
 private:
   MessageBuffer* container0; ///< Messages are queued here when the update buffer index == 0
   MessageBuffer* container1; ///< Messages are queued here when the update buffer index == 1
+
+  std::atomic<std::size_t> mCapacity{0u}; // Current total capacity of both buffers.
 };
 
 } // namespace SceneGraph
index 49268b6..d75199a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -484,6 +484,11 @@ void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animati
   }
 }
 
+uint32_t Animation::GetMemoryPoolCapacity()
+{
+  return gAnimationMemoryPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index cebcb2e..4119c15 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -292,6 +292,8 @@ public:
    */
   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached);
 
+  static uint32_t GetMemoryPoolCapacity();
+
 protected:
   /**
    * Protected constructor. See New()
index 1b5c1a3..2873011 100644 (file)
@@ -112,7 +112,8 @@ inline void EraseUsingDiscardQueue(OwnerContainer<T*>& container, T* object, Dis
 void SortSiblingNodesRecursively(Node& node)
 {
   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(); });
 
   // Descend tree and sort as well
   for(auto&& iter : container)
@@ -136,11 +137,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
@@ -288,11 +289,11 @@ struct UpdateManager::Impl
 
   OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
 
-  float             keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
-  NodePropertyFlags nodeDirtyFlags;       ///< cumulative node dirty flags from previous frame
-  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
+  std::atomic<std::size_t> renderInstructionCapacity{0u};
+  float                    keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
+  NodePropertyFlags        nodeDirtyFlags;       ///< cumulative node dirty flags from previous frame
+  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
 
   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)
@@ -338,9 +339,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);
@@ -690,6 +690,21 @@ uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene)
   return mImpl->messageQueue.ReserveMessageSlot(size, updateScene);
 }
 
+std::size_t UpdateManager::GetUpdateMessageQueueCapacity() const
+{
+  return mImpl->messageQueue.GetCapacity();
+}
+
+std::size_t UpdateManager::GetRenderMessageQueueCapacity() const
+{
+  return mImpl->renderQueue.GetCapacity();
+}
+
+std::size_t UpdateManager::GetRenderInstructionCapacity() const
+{
+  return mImpl->renderInstructionCapacity;
+}
+
 void UpdateManager::EventProcessingStarted()
 {
   mImpl->messageQueue.EventProcessingStarted();
@@ -817,7 +832,7 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
 
 void UpdateManager::ConstrainCustomObjects(BufferIndex bufferIndex)
 {
-  //Constrain custom objects (in construction order)
+  // Constrain custom objects (in construction order)
   for(auto&& object : mImpl->customObjects)
   {
     ConstrainPropertyOwner(*object, bufferIndex);
@@ -890,7 +905,7 @@ void UpdateManager::UpdateRenderers(BufferIndex bufferIndex)
 {
   for(auto&& renderer : mImpl->renderers)
   {
-    //Apply constraints
+    // Apply constraints
     ConstrainPropertyOwner(*renderer, bufferIndex);
 
     mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired;
@@ -934,12 +949,12 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
 {
   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
 
-  //Clear nodes/resources which were previously discarded
+  // Clear nodes/resources which were previously discarded
   mImpl->discardQueue.Clear(bufferIndex);
 
   bool isAnimationRunning = IsAnimationRunning();
 
-  //Process Touches & Gestures
+  // Process Touches & Gestures
   const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds);
 
   bool updateScene =                                   // The scene-graph requires an update if..
@@ -956,7 +971,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   // values if the scene was updated in the previous frame.
   if(updateScene || mImpl->previousUpdateScene)
   {
-    //Reset properties from the previous update
+    // Reset properties from the previous update
     ResetProperties(bufferIndex);
     mImpl->transformManager.ResetToBaseValue();
   }
@@ -966,7 +981,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   // be set again
   updateScene |= mImpl->messageQueue.ProcessMessages(bufferIndex);
 
-  //Forward compiled shader programs to event thread for saving
+  // Forward compiled shader programs to event thread for saving
   ForwardCompiledShadersToEventThread();
 
   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
@@ -974,13 +989,13 @@ 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)
   {
-    //Animate
+    // Animate
     bool animationActive = Animate(bufferIndex, elapsedSeconds);
 
-    //Constraint custom objects
+    // Constraint custom objects
     ConstrainCustomObjects(bufferIndex);
 
-    //Clear the lists of renderers from the previous update
+    // Clear the lists of renderers from the previous update
     for(auto&& scene : mImpl->scenes)
     {
       if(scene)
@@ -1001,36 +1016,36 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
     }
 
-    //Update node hierarchy, apply constraints,
+    // Update node hierarchy, apply constraints,
     UpdateNodes(bufferIndex);
 
-    //Apply constraints to RenderTasks, shaders
+    // Apply constraints to RenderTasks, shaders
     ConstrainRenderTasks(bufferIndex);
     ConstrainShaders(bufferIndex);
 
-    //Update renderers and apply constraints
+    // Update renderers and apply constraints
     UpdateRenderers(bufferIndex);
 
-    //Update the transformations of all the nodes
+    // Update the transformations of all the nodes
     if(mImpl->transformManager.Update())
     {
       mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
     }
 
-    //Initialise layer renderable reuse
+    // Initialise layer renderable reuse
     UpdateLayers(bufferIndex);
 
-    //Process Property Notifications
+    // Process Property Notifications
     ProcessPropertyNotifications(bufferIndex);
 
-    //Update cameras
+    // Update cameras
     for(auto&& cameraIterator : mImpl->cameras)
     {
       cameraIterator->Update(bufferIndex);
     }
 
-    //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
-    //reset the update buffer index and make sure there is enough room in the instruction container
+    // Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
+    // reset the update buffer index and make sure there is enough room in the instruction container
     if(mImpl->renderersAdded)
     {
       // Calculate how many render tasks we have in total
@@ -1044,6 +1059,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       }
 
       std::size_t numberOfRenderInstructions = 0;
+      mImpl->renderInstructionCapacity       = 0u;
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->root && scene->taskList && scene->scene)
@@ -1063,6 +1079,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
                                                                         renderToFboEnabled,
                                                                         isRenderingToFbo);
 
+            mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
             scene->scene->SetSkipRendering(false);
           }
           else
index 3065d34..a8a6683 100644 (file)
@@ -47,6 +47,9 @@
 #include <dali/internal/update/rendering/scene-graph-renderer.h>    // for OwnerPointer< Renderer >
 #include <dali/internal/update/rendering/scene-graph-texture-set.h> // for OwnerPointer< TextureSet >
 
+// EXTERNAL INCLUDES
+#include <cstddef>
+
 namespace Dali
 {
 class FrameCallbackInterface;
@@ -660,6 +663,21 @@ public:
    */
   void RemoveFrameCallback(FrameCallbackInterface* frameCallback);
 
+  /**
+   * Get the update message queue capacity (mutex locked)
+   */
+  std::size_t GetUpdateMessageQueueCapacity() const;
+
+  /**
+   * Get the render message queue capacity
+   */
+  std::size_t GetRenderMessageQueueCapacity() const;
+
+  /**
+   * Get the render instruction capacity
+   */
+  std::size_t GetRenderInstructionCapacity() const;
+
 private:
   // Undefined
   UpdateManager(const UpdateManager&);
index 4291f47..87b4603 100644 (file)
@@ -334,6 +334,11 @@ void Node::RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex)
   }
 }
 
+uint32_t Node::GetMemoryPoolCapacity()
+{
+  return gNodeMemoryPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index e845ce9..be26b7a 100644 (file)
@@ -852,6 +852,14 @@ public:
   }
 
   /**
+   * @brief Get the total capacity of the memory pools
+   * @return The capacity of the memory pools
+   *
+   * @note This is different to the node count.
+   */
+  static uint32_t GetMemoryPoolCapacity();
+
+  /**
    * @brief Returns partial rendering data associated with the node.
    * @return The partial rendering data
    */
index 83883a7..8b80412 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -287,6 +287,28 @@ bool MessageQueue::IsSceneUpdateRequired() const
   return mImpl->sceneUpdate;
 }
 
+std::size_t MessageQueue::GetCapacity() const
+{
+  MessageQueueMutex::ScopedLock lock(mImpl->queueMutex);
+
+  uint32_t          capacity = 0u;
+  MessageBufferIter endIter  = mImpl->freeQueue.end();
+  for(MessageBufferIter iter = mImpl->freeQueue.begin(); iter != endIter; ++iter)
+  {
+    capacity += (*iter)->GetCapacity();
+  }
+  endIter = mImpl->processQueue.end();
+  for(MessageBufferIter iter = mImpl->processQueue.begin(); iter != endIter; ++iter)
+  {
+    capacity += (*iter)->GetCapacity();
+  }
+  if(mImpl->currentMessageBuffer != nullptr)
+  {
+    capacity += mImpl->currentMessageBuffer->GetCapacity();
+  }
+  return capacity;
+}
+
 } // namespace Update
 
 } // namespace Internal
index 6fd1c47..cfc47ba 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_UPDATE_MESSAGE_QUEUE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -22,6 +22,9 @@
 #include <dali/internal/common/buffer-index.h>
 #include <dali/internal/update/common/scene-graph-buffers.h>
 
+// EXTERNAL INCLUDES
+#include <cstddef>
+
 namespace Dali
 {
 namespace Integration
@@ -99,6 +102,11 @@ public:
    */
   bool IsSceneUpdateRequired() const;
 
+  /**
+   * Query for the capacity of the current message queue
+   */
+  std::size_t GetCapacity() const;
+
 private:
   /**
    * Helper to call Process and destructor on each queued message
@@ -108,8 +116,8 @@ private:
 
 private:
   // Not copyable:
-  MessageQueue()                        = delete;
-  MessageQueue(const MessageQueue& rhs) = delete;
+  MessageQueue()                                   = delete;
+  MessageQueue(const MessageQueue& rhs)            = delete;
   MessageQueue& operator=(const MessageQueue& rhs) = delete;
 
 private:
index 8139c2b..03c39fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -107,6 +107,11 @@ CompleteNotificationInterface* RenderTaskList::GetCompleteNotificationInterface(
   return mNotificationObject;
 }
 
+uint32_t RenderTaskList::GetMemoryPoolCapacity()
+{
+  return gRenderTaskListMemoryPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index c985491..84058fc 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_LIST_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -107,6 +107,11 @@ public:
    */
   CompleteNotificationInterface* GetCompleteNotificationInterface();
 
+  /**
+   * Get the capacity of the memory pools
+   */
+  static uint32_t GetMemoryPoolCapacity();
+
 protected:
   /**
    * Protected constructor. See New()
index 6f4b485..1e03ce8 100644 (file)
@@ -734,6 +734,11 @@ void Renderer::ResetDirtyFlag()
   SetUpdated(false);
 }
 
+uint32_t Renderer::GetMemoryPoolCapacity()
+{
+  return gRendererMemoryPool.GetCapacity();
+}
+
 void Renderer::UniformMappingsChanged(const UniformMap& mappings)
 {
   // The mappings are either from PropertyOwner base class, or the Shader
index f2a84d6..f49f2fb 100644 (file)
@@ -435,6 +435,12 @@ public:
    */
   void ResetDirtyFlag();
 
+  /**
+   * Get the capacity of the memory pools
+   * @return the capacity of the memory pools
+   */
+  static uint32_t GetMemoryPoolCapacity();
+
 public: // UniformMap::Observer
   /**
    * @copydoc UniformMap::Observer::UniformMappingsChanged
index 0269286..1e95d3b 100644 (file)
@@ -113,6 +113,11 @@ bool TextureSet::HasAlpha() const
   return mHasAlpha;
 }
 
+uint32_t TextureSet::GetMemoryPoolCapacity()
+{
+  return gTextureSetMemoryPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 683296a..5e00716 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_TEXTURE_SET_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -91,6 +91,12 @@ public:
     return mSamplers;
   }
 
+  /**
+   * Get the capacity of the memory pools
+   * @return the capacity of the memory pools
+   */
+  static uint32_t GetMemoryPoolCapacity();
+
 private:
   /**
    * Protected constructor; See also TextureSet::New()
index 2356c4b..c05363a 100644 (file)
@@ -83,4 +83,9 @@ uint32_t PixelData::GetStride() const
   return GetImplementation(*this).GetStride();
 }
 
+uint32_t PixelData::GetTotalAllocatedSize()
+{
+  return Internal::PixelData::GetTotalAllocatedSize();
+}
+
 } // namespace Dali
index b7778d5..70e80da 100644 (file)
@@ -177,6 +177,11 @@ public:
    */
   uint32_t GetStride() const;
 
+  /**
+   * Class method to get the total currently allocated size of pixel buffers
+   */
+  static uint32_t GetTotalAllocatedSize();
+
 public:
   /**
    * @brief The constructor.
@@ -190,6 +195,6 @@ public:
 /**
  * @}
  */
-} //namespace Dali
+} // namespace Dali
 
 #endif // DALI_PIXEL_DATA_H