Merge "Sync UTC harness" into devel/master
authorDavid Steele <david.steele@samsung.com>
Mon, 19 Dec 2022 18:55:26 +0000 (18:55 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 19 Dec 2022 18:55:26 +0000 (18:55 +0000)
55 files changed:
automated-tests/src/dali-internal/utc-Dali-Internal-TransformManagerProperty.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Core.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/integration-api/debug.cpp
dali/integration-api/debug.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/actors/actor-coords.cpp
dali/internal/event/common/thread-local-storage.cpp
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-debug.cpp
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/common/render-manager.cpp
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/common/property-owner.h
dali/internal/update/manager/frame-callback-processor.cpp
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/manager/transform-manager-property.h
dali/internal/update/manager/transform-manager.cpp
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/nodes/node-helper.h [new file with mode: 0644]
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/internal/update/nodes/partial-rendering-data.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/dali-core-version.cpp
dali/public-api/images/pixel-data.cpp
dali/public-api/images/pixel-data.h
packaging/dali.spec

index d00cea6..0b6a440 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.
 
 // Internal headers are allowed here
 
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Verbose, true, "LOG_UTC_TRANSFORM_MANAGER_PROPERTY");
+#endif
+} // namespace
+
 void utc_dali_internal_transform_manager_property_startup()
 {
   test_return_value = TET_UNDEF;
@@ -36,16 +43,48 @@ int UtcTransformManagerPropertyGetFloatComponentN(void)
 {
   TestApplication application;
 
-  Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion property;
+  // For coverage
+  DALI_LOG_TRACE_METHOD(gLogFilter);
+
+  struct S
+  {
+    Dali::Internal::SceneGraph::TransformManagerData                                  txMgrData;
+    Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion<sizeof(txMgrData)> property;
+  } s;
 
   try
   {
-    property.GetFloatComponent(0u);
+    // There is no float component getter in derived class, only in base class.
+    s.property.GetFloatComponent(0u);
   }
-  catch(...)
+  catch(Dali::DaliException& e)
   {
-    DALI_TEST_CHECK(true);
+    DALI_TEST_ASSERT(e, "0 && \"Invalid call\"", TEST_LOCATION);
   }
 
+  // For coverage
+  DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Test End\n");
+
+  END_TEST;
+}
+
+int UtcTransformManagerPropertyUninitializedMgrData(void)
+{
+  TestApplication application;
+
+  struct S
+  {
+    const Vector3 input{1.0f, 2.0f, 3.0f};
+
+    Dali::Internal::SceneGraph::TransformManagerData                            txMgrData;
+    Dali::Internal::SceneGraph::TransformManagerVector3Input<sizeof(txMgrData)> property{Dali::Internal::SceneGraph::TRANSFORM_PROPERTY_POSITION, input};
+  } s;
+
+  Vector3 output = s.property.GetVector3(0);
+
+  tet_infoline("Test that if input property's transform manager data is not initialized, that getting a value returns the initial value of the property.");
+
+  DALI_TEST_EQUALS(s.input, output, 0.001f, TEST_LOCATION);
+
   END_TEST;
 }
index 873b7b3..e4c6078 100644 (file)
@@ -117,13 +117,16 @@ void TestApplication::LogMessage(Dali::Integration::Log::DebugPriority level, st
   {
     switch(level)
     {
-      case Dali::Integration::Log::DebugInfo:
+      case Dali::Integration::Log::DEBUG:
+        fprintf(stderr, "DEBUG: %s", message.c_str());
+        break;
+      case Dali::Integration::Log::INFO:
         fprintf(stderr, "INFO: %s", message.c_str());
         break;
-      case Dali::Integration::Log::DebugWarning:
+      case Dali::Integration::Log::WARNING:
         fprintf(stderr, "WARN: %s", message.c_str());
         break;
-      case Dali::Integration::Log::DebugError:
+      case Dali::Integration::Log::ERROR:
         fprintf(stderr, "ERROR: %s", message.c_str());
         break;
       default:
index a4264a4..a528eb3 100644 (file)
@@ -9353,7 +9353,7 @@ int utcDaliActorPartialUpdateChangeVisibility(void)
   DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
 
   // Aligned by 16
-  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
   DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
   DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
@@ -9365,10 +9365,6 @@ int utcDaliActorPartialUpdateChangeVisibility(void)
   application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
 
-  damagedRects.clear();
-  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
-  application.RenderWithPartialUpdate(damagedRects, clippingRect);
-
   // Ensure the damaged rect is empty
   DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
 
@@ -11666,6 +11662,76 @@ int UtcDaliActorCalculateWorldTransform07(void)
   END_TEST;
 }
 
+int UtcDaliActorCalculateWorldTransform08(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test that actor inheritance of scale produces right transform matrix");
+
+  Vector3 solutions[] = {Vector3(250, 0, 0), Vector3(0, 250, 0), Vector3(650, 0, 0), Vector3(0, 250, 0), Vector3(650, 0, 0), Vector3(400, 250, 0), Vector3(200, -50, 0), Vector3(500, 200, 0)};
+
+  struct TestCase
+  {
+    bool translation;
+    bool rotation;
+    bool scaling;
+  };
+  TestCase testCases[] = {
+    {false, false, true},
+    {false, true, false},
+    {true, false, false},
+    {false, true, true},
+    {true, false, true},
+    {true, true, false},
+    {false, false, false},
+    {true, true, true},
+  };
+
+  Actor rootActor = Actor::New();
+  Actor leafActor = Actor::New();
+
+  rootActor[Actor::Property::POSITION]      = Vector3(0.0f, 0.0f, 0.0f);
+  rootActor[Actor::Property::SCALE]         = Vector3(1.0f, 2.0f, 1.0f);
+  rootActor[Actor::Property::ORIENTATION]   = AngleAxis(Degree(90.0f), Vector3::ZAXIS);
+  rootActor[Actor::Property::SIZE]          = Vector2(200, 400);
+  rootActor[Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
+  rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+
+  leafActor[Actor::Property::POSITION]                   = Vector3(0.0f, -50.0f, 0.0f);
+  leafActor[Actor::Property::SCALE]                      = Vector3(1.0f, 1.0f, 1.0f);
+  leafActor[Actor::Property::ORIENTATION]                = AngleAxis(Degree(90.0f), Vector3::ZAXIS);
+  leafActor[Actor::Property::SIZE]                       = Vector2(200, 400);
+  leafActor[Actor::Property::ANCHOR_POINT]               = AnchorPoint::BOTTOM_CENTER;
+  leafActor[Actor::Property::PARENT_ORIGIN]              = ParentOrigin::TOP_CENTER;
+  leafActor[Actor::Property::POSITION_USES_ANCHOR_POINT] = true;
+
+  application.GetScene().Add(rootActor);
+  rootActor.Add(leafActor);
+
+  for(uint32_t i = 0; i< 8; ++i)
+  {
+    leafActor[Actor::Property::INHERIT_POSITION]    = testCases[i].translation;
+    leafActor[Actor::Property::INHERIT_ORIENTATION] = testCases[i].rotation;
+    leafActor[Actor::Property::INHERIT_SCALE]       = testCases[i].scaling;
+
+    application.SendNotification();
+    application.Render(0);
+    application.SendNotification();
+    application.Render(0);
+
+    Matrix m            = DevelActor::GetWorldTransform(leafActor);
+    Matrix actualMatrix = leafActor.GetCurrentProperty<Matrix>(Actor::Property::WORLD_MATRIX);
+
+    Vector3 worldPosition1 = Vector3(m.GetTranslation());
+    Vector3 worldPosition2 = Vector3(actualMatrix.GetTranslation());
+
+    DALI_TEST_EQUALS(solutions[i], worldPosition1, 0.001f, TEST_LOCATION);
+    DALI_TEST_EQUALS(solutions[i], worldPosition2, 0.001f, TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
 int UtcDaliActorCalculateWorldColor01(void)
 {
   TestApplication application;
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 e3857dc..af93507 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.
@@ -3668,14 +3668,15 @@ int UtcDaliRenderTaskViewportGuideActor02(void)
 
   application.GetScene().SurfaceRotated(static_cast<float>(TestApplication::DEFAULT_SURFACE_HEIGHT),
                                         static_cast<float>(TestApplication::DEFAULT_SURFACE_WIDTH),
-                                        90, 0);
+                                        90,
+                                        0);
 
   // Render and notify
   application.SendNotification();
   application.Render(16);
 
   std::string viewportParams1("50, 100, 300, 400"); // to match newSize
-  std::string viewportParams2("0, 0, 480, 800"); // to match newSize
+  std::string viewportParams2("0, 0, 480, 800");    // to match newSize
 
   // Check that the viewport is handled properly
   DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams1) >= 0);
@@ -3683,3 +3684,135 @@ int UtcDaliRenderTaskViewportGuideActor02(void)
 
   END_TEST;
 }
+
+int UtcDaliRenderTaskSetPartialUpdate(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  tet_infoline("Check the damaged rects with render task");
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  Actor rootActor = CreateRenderableActor();
+  rootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  rootActor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  rootActor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  rootActor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(rootActor);
+
+  CameraActor cameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT));
+  cameraActor.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  cameraActor.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  application.GetScene().Add(cameraActor);
+
+  Texture     frameBufferTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, 16, 16);
+  FrameBuffer frameBuffer        = FrameBuffer::New(frameBufferTexture.GetWidth(), frameBufferTexture.GetHeight());
+  frameBuffer.AttachColorTexture(frameBufferTexture);
+
+  // Create a RenderTask and set a framebuffer
+  RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+  RenderTask     newTask  = taskList.CreateTask();
+  newTask.SetCameraActor(cameraActor);
+  newTask.SetSourceActor(rootActor);
+  newTask.SetInputEnabled(false);
+  newTask.SetClearColor(Vector4(0.f, 0.f, 0.f, 0.f));
+  newTask.SetClearEnabled(true);
+  newTask.SetExclusive(true);
+  newTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
+  newTask.SetFrameBuffer(frameBuffer);
+
+  application.SendNotification();
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  // Full update if there is off-screen rendering
+  clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  // Remove framebuffer
+  newTask.SetFrameBuffer(FrameBuffer());
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  // Full update
+  clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Set invalid viewport of the render task
+  newTask.SetViewportSize(Vector2(-100.0f, -100.0f));
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  // Full update because the camera orientation is changed
+  clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  newTask.SetViewportSize(Vector2(0.0f, 0.0f));
+
+  // Change orientation of offscreen camera
+  cameraActor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.0f), Vector3::XAXIS));
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  // Full update because the camera orientation is changed
+  clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Change camera target
+  cameraActor.SetTargetPosition(Vector3(10.0f, 10.0f, 0.0f));
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  // Full update because the camera is moved
+  clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  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 ebbc339..858b4d8 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.
@@ -166,14 +166,14 @@ void Filter::Log(LogLevel level, const char* format, ...)
       if(numChars >= 0) // No error
       {
         std::string message = ArgListToString(buffer, arg);
-        LogMessage(DebugInfo, message.c_str());
+        LogMessage(INFO, message.c_str());
         free(buffer);
       }
     }
     else
     {
       std::string message = ArgListToString(format, arg);
-      LogMessage(DebugInfo, message.c_str());
+      LogMessage(INFO, message.c_str());
     }
     va_end(arg);
   }
@@ -189,7 +189,7 @@ TraceObj::TraceObj(Filter* filter, const char* format, ...)
     mMessage = ArgListToString(format, arg);
     va_end(arg);
 
-    LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
+    LogMessage(INFO, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
     ++mFilter->mNesting;
   }
 }
@@ -202,7 +202,7 @@ TraceObj::~TraceObj()
     {
       --mFilter->mNesting;
     }
-    LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
+    LogMessage(INFO, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str());
   }
 }
 
index 7daa433..8533270 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTEGRATION_DEBUG_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.
 
 // EXTERNAL INCLUDES
 #include <stdint.h>
+#include <cstring>
 #include <iostream>
 #include <list>
 #include <sstream>
 #include <string>
-#include <cstring>
 
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/property-map.h>
@@ -79,9 +79,10 @@ namespace Log
 {
 enum DebugPriority
 {
-  DebugInfo,
-  DebugWarning,
-  DebugError
+  DEBUG,
+  INFO,
+  WARNING,
+  ERROR
 };
 
 /**
@@ -100,7 +101,7 @@ DALI_CORE_API void LogMessage(enum DebugPriority level, const char* format, ...)
 #define __MODULE__ (std::strrchr(__FILE__, '/') ? std::strrchr(__FILE__, '/') + 1 : __FILE__)
 #endif
 #define DALI_LOG_FORMAT_PREFIX "%s: %s(%d) > "
-#define DALI_LOG_FORMAT_PREFIX_ARGS __MODULE__,__func__,__LINE__
+#define DALI_LOG_FORMAT_PREFIX_ARGS __MODULE__, __func__, __LINE__
 #endif
 
 /**
@@ -108,11 +109,11 @@ DALI_CORE_API void LogMessage(enum DebugPriority level, const char* format, ...)
  * @param level debug level
  * @param format string format
  */
-#define LogMessageWithFunctionLine(level, format, ...)                 \
-  LogMessage(level,                                                    \
-  (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
-  DALI_LOG_FORMAT_PREFIX_ARGS,                                         \
-  ##__VA_ARGS__)
+#define LogMessageWithFunctionLine(level, format, ...)                            \
+  LogMessage(level,                                                               \
+             (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
+             DALI_LOG_FORMAT_PREFIX_ARGS,                                         \
+             ##__VA_ARGS__)
 
 /**
  * typedef for the logging function.
@@ -141,38 +142,43 @@ DALI_CORE_API void UninstallLogFunction();
 /**
  * Provides unfiltered logging for global error level messages
  */
-#define DALI_LOG_ERROR(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugError, format, ##__VA_ARGS__)
+#define DALI_LOG_ERROR(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__)
 
-#define DALI_LOG_ERROR_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ##__VA_ARGS__)
+#define DALI_LOG_ERROR_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__)
 
-#define DALI_LOG_WARNING_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ##__VA_ARGS__)
+#define DALI_LOG_WARNING_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::WARNING, format, ##__VA_ARGS__)
 
 /**
  * Provides unfiltered logging for fps monitor
  */
-#define DALI_LOG_FPS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__)
+#define DALI_LOG_FPS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
 
 /**
  * Provides unfiltered logging for update status
  */
-#define DALI_LOG_UPDATE_STATUS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__)
+#define DALI_LOG_UPDATE_STATUS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
 
 /**
  * Provides unfiltered logging for render information
  */
-#define DALI_LOG_RENDER_INFO(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__)
+#define DALI_LOG_RENDER_INFO(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
 
 /**
  * Provides unfiltered logging for release
  */
-#define DALI_LOG_RELEASE_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__)
+#define DALI_LOG_RELEASE_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
+
+/**
+ * Provides unfiltered logging for debuf information
+ */
+#define DALI_LOG_DEBUG_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DEBUG, format, ##__VA_ARGS__)
 
 #ifdef DEBUG_ENABLED
 
 /**
  * Provides unfiltered logging for global warning level messages
  */
-#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugWarning, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__)
+#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::WARNING, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__)
 
 #else // DEBUG_ENABLED
 
@@ -363,13 +369,13 @@ public:
 
 #ifdef DEBUG_ENABLED
 
-#define DALI_LOG_INFO(filter, level, format, ...)                        \
-  if(filter && filter->IsEnabledFor(level))                              \
-  {                                                                      \
-    filter->Log(level,                                                   \
-    (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
-    DALI_LOG_FORMAT_PREFIX_ARGS,                                         \
-    ##__VA_ARGS__);                                                      \
+#define DALI_LOG_INFO(filter, level, format, ...)                                    \
+  if(filter && filter->IsEnabledFor(level))                                          \
+  {                                                                                  \
+    filter->Log(level,                                                               \
+                (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
+                DALI_LOG_FORMAT_PREFIX_ARGS,                                         \
+                ##__VA_ARGS__);                                                      \
   }
 
 #define DALI_LOG_STREAM(filter, level, stream) \
@@ -393,7 +399,7 @@ public:
 
 /*
  * These macros allow the instrumentation of methods. These translate into calls
- * to LogMessage(DebugInfo).
+ * to LogMessage(INFO).
  */
 
 #ifdef DEBUG_ENABLED
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 d1a70db..9f1fefe 100644 (file)
@@ -533,39 +533,60 @@ Matrix CalculateActorWorldTransform(const Actor& actor)
       }
       else
       {
-        Vector3    parentPosition, parentScale;
-        Quaternion parentOrientation;
-        worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
-
+        // Get Parent information.
+        Vector3       parentPosition, parentScale;
+        Quaternion    parentOrientation;
+        const Matrix& parentMatrix = worldMatrix;
+        parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
+
+        // Compute intermediate Local information
+        centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation);
+        Vector3 intermediateLocalPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
+        Matrix intermediateLocalMatrix;
+        intermediateLocalMatrix.SetTransformComponents(localScale, localOrientation, intermediateLocalPosition);
+
+        // Compute intermediate world information
+        Matrix intermediateWorldMatrix;
+        MatrixUtils::Multiply(intermediateWorldMatrix, intermediateLocalMatrix, parentMatrix);
+
+        Vector3       intermediateWorldPosition, intermediateWorldScale;
+        Quaternion    intermediateWorldOrientation;
+        intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale);
+
+        // Compute final world information
+        Vector3    finalWorldPosition    = intermediateWorldPosition;
+        Vector3    finalWorldScale       = intermediateWorldScale;
+        Quaternion finalWorldOrientation = intermediateWorldOrientation;
+        // worldScale includes the influence of local scale, local rotation, and parent scale.
+        // So, for the final world matrix, if this node inherits its parent scale, use worldScale.
+        // If not, use local scale for the final world matrix.
         if((inheritanceModeList[i] & INHERIT_SCALE) == 0)
         {
-          //Don't inherit scale
-          localScale /= parentScale;
+          finalWorldScale = localScale;
         }
 
+        // For the final world matrix, if this node inherits its parent orientation, use worldOrientation.
+        // If not, use local orientation for the final world matrix.
         if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0)
         {
-          //Don't inherit orientation
-          parentOrientation.Invert();
-          localOrientation = parentOrientation * localOrientation;
+          finalWorldOrientation = localOrientation;
         }
 
-        if((inheritanceModeList[i] & INHERIT_POSITION) == 0)
-        {
-          localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
-          Matrix tempMatrix;
-          MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix);
-          worldMatrix = tempMatrix;
-          worldMatrix.SetTranslation(actorPosition + centerPosition);
-        }
-        else
+        // The final world position of this node is computed as a sum of
+        // parent origin position in world space and relative position of center from parent origin.
+        // If this node doesn't inherit its parent position, simply use the relative position as a final world position.
+        Vector3 localCenterPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, finalWorldScale, finalWorldOrientation);
+        finalWorldPosition = actorPosition * finalWorldScale;
+        finalWorldPosition *= finalWorldOrientation;
+        finalWorldPosition += localCenterPosition;
+        if((inheritanceModeList[i] & INHERIT_POSITION) != 0)
         {
-          localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
-          localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
-          Matrix tempMatrix;
-          MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix);
-          worldMatrix = tempMatrix;
+          Vector4 parentOriginPosition((parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize);
+          parentOriginPosition.w = 1.0f;
+          finalWorldPosition += Vector3(parentMatrix * parentOriginPosition);
         }
+
+        worldMatrix.SetTransformComponents(finalWorldScale, finalWorldOrientation, finalWorldPosition);
       }
     }
     else
index aca21f4..6ebfc68 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.
@@ -34,7 +34,7 @@ Debug::Filter* gSingletonServiceLogFilter = Debug::Filter::New(Debug::NoLogging,
   if(gSingletonServiceLogFilter && gSingletonServiceLogFilter->IsEnabledFor(level)) \
   {                                                                                 \
     std::string string(message);                                                    \
-    Dali::TizenPlatform::LogMessage(Debug::DebugInfo, string);                      \
+    Dali::TizenPlatform::LogMessage(Debug::INFO, string);                           \
   }
 
 #define DALI_LOG_SINGLETON_SERVICE(level, format, ...) DALI_LOG_INFO(gSingletonServiceLogFilter, level, format, ##__VA_ARGS__)
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 d4080e5..aa463ac 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.
@@ -99,7 +99,7 @@ void PrintRendererCount(unsigned int frameCount, unsigned int rendererCount)
 {
   if(frameCount % 120 == 30) // Print every 2 seconds reg
   {
-    Debug::LogMessage(Debug::DebugInfo, "Renderer Total # renderers: %u\n", rendererCount);
+    Debug::LogMessage(Debug::INFO, "Renderer Total # renderers: %u\n", rendererCount);
   }
 }
 
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 9b3ba8c..1aafa37 100644 (file)
@@ -42,7 +42,6 @@ RenderItem* RenderItem::New()
 RenderItem::RenderItem()
 : mModelMatrix(false),
   mModelViewMatrix(false),
-  mColor(Vector4::ZERO),
   mSize(),
   mRenderer(nullptr),
   mNode(nullptr),
@@ -168,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 d1ca0f4..0a82320 100644 (file)
@@ -90,7 +90,6 @@ struct RenderItem
 
   Matrix            mModelMatrix;
   Matrix            mModelViewMatrix;
-  Vector4           mColor;
   Vector3           mSize;
   Vector4           mUpdateArea; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
   Render::Renderer* mRenderer;
@@ -100,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 c7b88c1..fff4fe8 100644 (file)
@@ -543,7 +543,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
 
     if(instruction.mFrameBuffer)
     {
-      return; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
+      cleanDamagedRect = true;
+      continue; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
     }
 
     const Camera* camera = instruction.GetCamera();
@@ -564,12 +565,14 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
          orientationAngle != ANGLE_180 ||
          scale != Vector3(1.0f, 1.0f, 1.0f))
       {
-        return;
+        cleanDamagedRect = true;
+        continue;
       }
     }
     else
     {
-      return;
+      cleanDamagedRect = true;
+      continue;
     }
 
     Rect<int32_t> viewportRect;
@@ -579,7 +582,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
       viewportRect.Set(instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height);
       if(viewportRect.IsEmpty() || !viewportRect.IsValid())
       {
-        return; // just skip funny use cases for now, empty viewport means it is set somewhere else
+        cleanDamagedRect = true;
+        continue; // just skip funny use cases for now, empty viewport means it is set somewhere else
       }
     }
     else
@@ -682,7 +686,9 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
                 else
                 {
                   // The item is not in the list for some reason. Add it!
+                  dirtyRect.rect = surfaceRect;
                   itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
+                  cleanDamagedRect = true; // And make full update at this frame
                 }
               }
             }
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 1d3fee7..f4329fa 100644 (file)
@@ -162,7 +162,7 @@ public:
    * Mark an property owner with the updated flag.
    * @param[in] updated The updated flag
    */
-  virtual void SetUpdated(bool updated)
+  void SetUpdated(bool updated)
   {
     mUpdated = updated;
   }
index 1f54b89..10e7d8d 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.
 // INTERNAL INCLUDES
 #include <dali/devel-api/update/frame-callback-interface.h>
 #include <dali/devel-api/update/update-proxy.h>
+#include <dali/integration-api/trace.h>
+
+namespace
+{
+DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
+} // namespace
 
 namespace Dali
 {
@@ -59,12 +65,19 @@ void FrameCallbackProcessor::RemoveFrameCallback(FrameCallbackInterface* frameCa
 
 void FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSeconds)
 {
-  // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed.
-  auto iter = std::remove_if(
-    mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer<FrameCallback>& frameCallback) {
-      return !frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged);
-    });
-  mFrameCallbacks.erase(iter, mFrameCallbacks.end());
+  if(!mFrameCallbacks.empty())
+  {
+    DALI_TRACE_BEGIN(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE");
+
+    // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed.
+    auto iter = std::remove_if(
+      mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer<FrameCallback>& frameCallback) {
+        return !frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged);
+      });
+    mFrameCallbacks.erase(iter, mFrameCallbacks.end());
+
+    DALI_TRACE_END(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE");
+  }
 
   mNodeHierarchyChanged = false;
 }
index 50bdc0e..e15862a 100644 (file)
@@ -260,15 +260,9 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
       // Get the next free RenderItem.
       RenderItem& item = renderList.GetNextFreeItem();
 
-      item.mNode     = node;
-      item.mIsOpaque = isOpaque;
-      item.mColor    = node->GetColor(updateBufferIndex);
-
-      item.mDepthIndex = 0;
-      if(!isLayer3d)
-      {
-        item.mDepthIndex = node->GetDepthIndex();
-      }
+      item.mNode       = node;
+      item.mIsOpaque   = isOpaque;
+      item.mDepthIndex = isLayer3d ? 0 : node->GetDepthIndex();
 
       if(DALI_LIKELY(renderable.mRenderer))
       {
@@ -300,7 +294,6 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
 
       PartialRenderingData partialRenderingData;
       partialRenderingData.color               = node->GetWorldColor(updateBufferIndex);
-      partialRenderingData.depthIndex          = node->GetDepthIndex();
       partialRenderingData.matrix              = item.mModelViewMatrix;
       partialRenderingData.updatedPositionSize = item.mUpdateArea;
       partialRenderingData.size                = item.mSize;
index 619abee..3c11242 100644 (file)
@@ -2,7 +2,7 @@
 #define TRANSFORM_MANAGER_PROPERTY_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.
@@ -148,30 +148,32 @@ struct TransformManagerPropertyHandler : public AnimatablePropertyBase
   }
 
   /**
-   * Initializes the property
-   * @param[in] transformManager Pointer to the transform manager
-   * @param[in] Id of the transformation the property is associated with
-   */
-  void Initialize(TransformManagerData* data)
-  {
-    DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
-    mTxManagerData = data;
-  }
-
-  /**
    * @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
    */
   bool IsTransformManagerProperty() const override
   {
     return true;
   }
-
-  TransformManagerData* mTxManagerData{nullptr};
 };
 
-template<TransformManagerProperty PropertyT>
+template<TransformManagerProperty PropertyT, size_t TxMgrDataOffset>
 struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHandler<Vector3>
 {
+  enum
+  {
+    TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+  };
+  TransformManagerData* GetTxManagerData()
+  {
+    return reinterpret_cast<TransformManagerData*>(
+      reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+  const TransformManagerData* GetTxManagerData() const
+  {
+    return reinterpret_cast<const TransformManagerData*>(
+      reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+
   TransformManagerPropertyVector3() = default;
 
   Dali::Property::Type GetType() const override
@@ -181,12 +183,12 @@ struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHa
 
   Vector3& Get(BufferIndex bufferIndex) override
   {
-    return mTxManagerData->Manager()->GetVector3PropertyValue(mTxManagerData->Id(), PropertyT);
+    return GetTxManagerData()->Manager()->GetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT);
   }
 
   const Vector3& Get(BufferIndex bufferIndex) const override
   {
-    return mTxManagerData->Manager()->GetVector3PropertyValue(mTxManagerData->Id(), PropertyT);
+    return GetTxManagerData()->Manager()->GetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT);
   }
 
   const Vector3& GetVector3(BufferIndex bufferIndex) const override
@@ -196,68 +198,84 @@ struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHa
 
   const float& GetFloatComponent(uint32_t component) const override
   {
-    return mTxManagerData->Manager()->GetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, component);
+    return GetTxManagerData()->Manager()->GetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, component);
   }
 
   void Set(BufferIndex bufferIndex, const Vector3& value) override
   {
-    mTxManagerData->Manager()->SetVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->SetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void SetComponent(BufferIndex bufferIndex, float value, uint32_t component)
   {
-    mTxManagerData->Manager()->SetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+    GetTxManagerData()->Manager()->SetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
   }
 
   void BakeComponent(BufferIndex bufferIndex, float value, uint32_t component)
   {
-    mTxManagerData->Manager()->BakeVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+    GetTxManagerData()->Manager()->BakeVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
   }
 
   void Bake(BufferIndex bufferIndex, const Vector3& value) override
   {
-    mTxManagerData->Manager()->BakeVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void BakeX(BufferIndex bufferIndex, float value) override
   {
-    mTxManagerData->Manager()->BakeXVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeXVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void BakeY(BufferIndex bufferIndex, float value) override
   {
-    mTxManagerData->Manager()->BakeYVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeYVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void BakeZ(BufferIndex bufferIndex, float value) override
   {
-    mTxManagerData->Manager()->BakeZVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeZVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void SetFloatComponent(float value, uint32_t component) override
   {
-    mTxManagerData->Manager()->SetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+    GetTxManagerData()->Manager()->SetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
   }
 
   void BakeFloatComponent(float value, uint32_t component) override
   {
-    mTxManagerData->Manager()->BakeVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+    GetTxManagerData()->Manager()->BakeVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
   }
 
   void BakeRelative(BufferIndex bufferIndex, const Vector3& value) override
   {
-    mTxManagerData->Manager()->BakeRelativeVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeRelativeVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 
   void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& value) override
   {
-    mTxManagerData->Manager()->BakeMultiplyVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+    GetTxManagerData()->Manager()->BakeMultiplyVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
   }
 };
 
+template<size_t TxMgrDataOffset>
 class TransformManagerPropertyQuaternion final : public TransformManagerPropertyHandler<Quaternion>
 {
 public:
+  enum
+  {
+    TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+  };
+  TransformManagerData* GetTxManagerData()
+  {
+    return reinterpret_cast<TransformManagerData*>(
+      reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+  const TransformManagerData* GetTxManagerData() const
+  {
+    return reinterpret_cast<const TransformManagerData*>(
+      reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+
   TransformManagerPropertyQuaternion() = default;
 
   Dali::Property::Type GetType() const override
@@ -267,27 +285,27 @@ public:
 
   Quaternion& Get(BufferIndex bufferIndex) override
   {
-    return mTxManagerData->Manager()->GetQuaternionPropertyValue(mTxManagerData->Id());
+    return GetTxManagerData()->Manager()->GetQuaternionPropertyValue(GetTxManagerData()->Id());
   }
 
   const Quaternion& Get(BufferIndex bufferIndex) const override
   {
-    return mTxManagerData->Manager()->GetQuaternionPropertyValue(mTxManagerData->Id());
+    return GetTxManagerData()->Manager()->GetQuaternionPropertyValue(GetTxManagerData()->Id());
   }
 
   void Set(BufferIndex bufferIndex, const Quaternion& value) override
   {
-    return mTxManagerData->Manager()->SetQuaternionPropertyValue(mTxManagerData->Id(), value);
+    return GetTxManagerData()->Manager()->SetQuaternionPropertyValue(GetTxManagerData()->Id(), value);
   }
 
   void Bake(BufferIndex bufferIndex, const Quaternion& value) override
   {
-    return mTxManagerData->Manager()->BakeQuaternionPropertyValue(mTxManagerData->Id(), value);
+    return GetTxManagerData()->Manager()->BakeQuaternionPropertyValue(GetTxManagerData()->Id(), value);
   }
 
   void BakeRelative(BufferIndex bufferIndex, const Quaternion& value) override
   {
-    return mTxManagerData->Manager()->BakeRelativeQuaternionPropertyValue(mTxManagerData->Id(), value);
+    return GetTxManagerData()->Manager()->BakeRelativeQuaternionPropertyValue(GetTxManagerData()->Id(), value);
   }
 
   const Quaternion& GetQuaternion(BufferIndex bufferIndex) const override
@@ -299,9 +317,25 @@ public:
 /**
  * A Vector3 property used as input.
  */
+template<size_t TxMgrDataOffset>
 class TransformManagerVector3Input : public PropertyInputImpl
 {
 public:
+  enum
+  {
+    TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+  };
+  TransformManagerData* GetTxManagerData()
+  {
+    return reinterpret_cast<TransformManagerData*>(
+      reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+  const TransformManagerData* GetTxManagerData() const
+  {
+    return reinterpret_cast<const TransformManagerData*>(
+      reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+
   /**
    * Create an TransformManagerVector3Input
    */
@@ -355,10 +389,11 @@ public:
    */
   void ComputeTransformComponent() const
   {
-    if(mTxManagerData)
+    auto transformManagerData = GetTxManagerData();
+    auto id                   = transformManagerData->Id();
+    if(id != INVALID_TRANSFORM_ID)
     {
-      const Matrix& worldMatrix = mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
-
+      const Matrix& worldMatrix = transformManagerData->Manager()->GetWorldMatrix(id);
       if(mProperty == TRANSFORM_PROPERTY_WORLD_POSITION)
       {
         mValue = worldMatrix.GetTranslation3();
@@ -420,17 +455,6 @@ public:
   }
 
   /**
-   * Initializes the property
-   * @param[in] transformManager Pointer to the transform manager
-   * @param[in] Id of the transformation the property is associated with
-   */
-  void Initialize(TransformManagerData* data)
-  {
-    DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
-    mTxManagerData = data;
-  }
-
-  /**
    * @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
    */
   bool IsTransformManagerProperty() const override
@@ -439,14 +463,10 @@ public:
   }
 
 private:
-  // Undefined
-  TransformManagerVector3Input(const TransformManagerVector3Input& property);
-
-  // Undefined
-  TransformManagerVector3Input& operator=(const TransformManagerVector3Input& rhs);
+  TransformManagerVector3Input(const TransformManagerVector3Input& property)       = delete;
+  TransformManagerVector3Input& operator=(const TransformManagerVector3Input& rhs) = delete;
 
 public:
-  TransformManagerData*    mTxManagerData{nullptr};
   TransformManagerProperty mProperty;
   mutable Vector3          mValue;
 };
@@ -454,9 +474,25 @@ public:
 /**
  * A Quaternion property used as input.
  */
+template<size_t TxMgrDataOffset>
 class TransformManagerQuaternionInput final : public PropertyInputImpl
 {
 public:
+  enum
+  {
+    TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+  };
+  TransformManagerData* GetTxManagerData()
+  {
+    return reinterpret_cast<TransformManagerData*>(
+      reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+  const TransformManagerData* GetTxManagerData() const
+  {
+    return reinterpret_cast<const TransformManagerData*>(
+      reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+
   /**
    * Constructor
    */
@@ -501,9 +537,11 @@ public:
    */
   void ComputeTransformComponent() const
   {
-    if(mTxManagerData)
+    auto transformManagerData = GetTxManagerData();
+    auto id                   = transformManagerData->Id();
+    if(id != INVALID_TRANSFORM_ID)
     {
-      const Matrix& worldMatrix = mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+      const Matrix& worldMatrix = transformManagerData->Manager()->GetWorldMatrix(id);
       Vector3       position, scale;
       worldMatrix.GetTransformComponents(position, mValue, scale);
     }
@@ -557,17 +595,6 @@ public:
   }
 
   /**
-   * Initializes the property
-   * @param[in] transformManager Pointer to the transform manager
-   * @param[in] Id of the transformation the property is associated with
-   */
-  void Initialize(TransformManagerData* data)
-  {
-    DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
-    mTxManagerData = data;
-  }
-
-  /**
    * @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
    */
   bool IsTransformManagerProperty() const override
@@ -576,23 +603,35 @@ public:
   }
 
 private:
-  // Undefined
-  TransformManagerQuaternionInput(const TransformManagerQuaternionInput& property);
-
-  // Undefined
-  TransformManagerQuaternionInput& operator=(const TransformManagerQuaternionInput& rhs);
+  TransformManagerQuaternionInput(const TransformManagerQuaternionInput& property)       = delete;
+  TransformManagerQuaternionInput& operator=(const TransformManagerQuaternionInput& rhs) = delete;
 
 public:
-  TransformManagerData* mTxManagerData{nullptr};
-  mutable Quaternion    mValue;
+  mutable Quaternion mValue;
 };
 
 /**
  * A Matrix property used as input.
  */
+template<size_t TxMgrDataOffset>
 class TransformManagerMatrixInput final : public PropertyInputImpl
 {
 public:
+  enum
+  {
+    TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+  };
+  TransformManagerData* GetTxManagerData()
+  {
+    return reinterpret_cast<TransformManagerData*>(
+      reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+  const TransformManagerData* GetTxManagerData() const
+  {
+    return reinterpret_cast<const TransformManagerData*>(
+      reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+  }
+
   /**
    * Constructor
    */
@@ -636,11 +675,12 @@ public:
    */
   const Matrix& GetMatrix(BufferIndex bufferIndex) const override
   {
-    if(mTxManagerData)
+    auto transformManagerData = GetTxManagerData();
+    auto id                   = transformManagerData->Id();
+    if(id != INVALID_TRANSFORM_ID)
     {
-      return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+      return transformManagerData->Manager()->GetWorldMatrix(id);
     }
-
     return Matrix::IDENTITY;
   }
 
@@ -649,11 +689,12 @@ public:
    */
   const Matrix& GetConstraintInputMatrix(BufferIndex bufferIndex) const override
   {
-    if(mTxManagerData)
+    auto transformManagerData = GetTxManagerData();
+    auto id                   = transformManagerData->Id();
+    if(id != INVALID_TRANSFORM_ID)
     {
-      return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+      return transformManagerData->Manager()->GetWorldMatrix(id);
     }
-
     return Matrix::IDENTITY;
   }
 
@@ -662,8 +703,10 @@ public:
    */
   Matrix& Get(BufferIndex bufferIndex)
   {
-    DALI_ASSERT_ALWAYS(mTxManagerData != nullptr);
-    return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+    auto transformManagerData = GetTxManagerData();
+    auto id                   = transformManagerData->Id();
+    DALI_ASSERT_ALWAYS(id != INVALID_TRANSFORM_ID);
+    return transformManagerData->Manager()->GetWorldMatrix(id);
   }
 
   /**
@@ -684,12 +727,6 @@ public:
     return GetMatrix(bufferIndex);
   }
 
-  void Initialize(TransformManagerData* data)
-  {
-    DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
-    mTxManagerData = data;
-  }
-
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
    */
@@ -699,18 +736,12 @@ public:
   }
 
 private:
-  // Undefined
-  TransformManagerMatrixInput(const TransformManagerMatrixInput& property);
-
-  // Undefined
-  TransformManagerMatrixInput& operator=(const TransformManagerMatrixInput& rhs);
-
-public:
-  TransformManagerData* mTxManagerData{nullptr};
+  TransformManagerMatrixInput(const TransformManagerMatrixInput& property)       = delete;
+  TransformManagerMatrixInput& operator=(const TransformManagerMatrixInput& rhs) = delete;
 };
 
-} //namespace SceneGraph
-} //namespace Internal
-} //namespace Dali
+} // namespace SceneGraph
+} // namespace Internal
+} // namespace Dali
 
 #endif // TRANSFORM_MANAGER_PROPERTY_H_
index 342d820..452d272 100644 (file)
@@ -28,6 +28,8 @@
 #include <dali/internal/common/matrix-utils.h>
 #include <dali/public-api/common/constants.h>
 
+#include <dali/integration-api/debug.h>
+
 namespace Dali
 {
 namespace Internal
@@ -49,22 +51,24 @@ static_assert(sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformCo
  * @brief Calculates the center position for the transform component
  * @param[out] centerPosition The calculated center-position of the transform component
  * @param[in] transformComponentStatic A const reference to the static component transform struct
- * @param[in] transformComponentAnimatable A const reference to the animatable component transform struct
+ * @param[in] scale scale factor to be applied to the center position.
+ * @param[in] orientation orientation factor to be applied to the center position.
  * @param[in] size The size of the current transform component
  * @param[in] half Halfway point of the transform
  * @param[in] topLeft The top-left coords of the transform
  */
 inline void CalculateCenterPosition(
-  Vector3&                            centerPosition,
-  const TransformComponentStatic&     transformComponentStatic,
-  const TransformComponentAnimatable& transformComponentAnimatable,
-  const Vector3&                      size,
-  const Vector3&                      half,
-  const Vector3&                      topLeft)
+  Vector3&                        centerPosition,
+  const TransformComponentStatic& transformComponentStatic,
+  const Vector3&                  scale,
+  const Quaternion&               orientation,
+  const Vector3&                  size,
+  const Vector3&                  half,
+  const Vector3&                  topLeft)
 {
   // Calculate the center-point by applying the scale and rotation on the anchor point.
-  centerPosition = (half - transformComponentStatic.mAnchorPoint) * size * transformComponentAnimatable.mScale;
-  centerPosition *= transformComponentAnimatable.mOrientation;
+  centerPosition = (half - transformComponentStatic.mAnchorPoint) * size * scale;
+  centerPosition *= orientation;
 
   // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position.
   if(!transformComponentStatic.mPositionUsesAnchorPoint)
@@ -255,7 +259,7 @@ bool TransformManager::Update()
         {
           //Full transform inherited
           mLocalMatrixDirty[i] = true;
-          CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
+          CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft);
           localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex];
           mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition);
         }
@@ -265,52 +269,76 @@ bool TransformManager::Update()
       }
       else
       {
-        //Some components are not inherited
+        // Keep previous localMatrix for comparison.
+        Matrix previousLocalMatrix = mLocal[i];
+
+        // Get Parent information.
         Vector3       parentPosition, parentScale;
         Quaternion    parentOrientation;
         const Matrix& parentMatrix = mWorld[parentIndex];
         parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
 
-        Vector3 localScale = mTxComponentAnimatable[i].mScale;
+        // Compute intermediate Local information
+        CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft);
+        Vector3 intermediateLocalPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex];
+        Matrix intermediateLocalMatrix;
+        intermediateLocalMatrix.SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, intermediateLocalPosition);
+
+        // Compute intermediate world information
+        Matrix intermediateWorldMatrix;
+        MatrixUtils::Multiply(intermediateWorldMatrix, intermediateLocalMatrix, mWorld[parentIndex]);
+
+        Vector3       intermediateWorldPosition, intermediateWorldScale;
+        Quaternion    intermediateWorldOrientation;
+        intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale);
+
+        // Compute final world information
+        Vector3    finalWorldPosition    = intermediateWorldPosition;
+        Vector3    finalWorldScale       = intermediateWorldScale;
+        Quaternion finalWorldOrientation = intermediateWorldOrientation;
+        // worldScale includes the influence of local scale, local rotation, and parent scale.
+        // So, for the final world matrix, if this node inherits its parent scale, use worldScale.
+        // If not, use local scale for the final world matrix.
         if((mInheritanceMode[i] & INHERIT_SCALE) == 0)
         {
-          //Don't inherit scale
-          localScale /= parentScale;
+          finalWorldScale = mTxComponentAnimatable[i].mScale;
         }
 
-        Quaternion localOrientation(mTxComponentAnimatable[i].mOrientation);
+        // For the final world matrix, if this node inherits its parent orientation, use worldOrientation.
+        // If not, use local orientation for the final world matrix.
         if((mInheritanceMode[i] & INHERIT_ORIENTATION) == 0)
         {
-          //Don't inherit orientation
-          parentOrientation.Invert();
-          localOrientation = parentOrientation * mTxComponentAnimatable[i].mOrientation;
+          finalWorldOrientation = mTxComponentAnimatable[i].mOrientation;
         }
 
-        Matrix localMatrix = mLocal[i];
-
-        if((mInheritanceMode[i] & INHERIT_POSITION) == 0)
-        {
-          //Don't inherit position
-          CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
-          mLocal[i].SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
-          MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix);
-          mWorld[i].SetTranslation(mTxComponentAnimatable[i].mPosition + centerPosition);
-        }
-        else
+        // The final world position of this node is computed as a sum of
+        // parent origin position in world space and relative position of center from parent origin.
+        // If this node doesn't inherit its parent position, simply use the relative position as a final world position.
+        Vector3 localCenterPosition;
+        CalculateCenterPosition(localCenterPosition, mTxComponentStatic[i], finalWorldScale, finalWorldOrientation, mSize[i], half, topLeft);
+        finalWorldPosition = mTxComponentAnimatable[i].mPosition * finalWorldScale;
+        finalWorldPosition *= finalWorldOrientation;
+        finalWorldPosition += localCenterPosition;
+        if((mInheritanceMode[i] & INHERIT_POSITION) != 0)
         {
-          CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
-          localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex];
-          mLocal[i].SetTransformComponents(localScale, localOrientation, localPosition);
-          MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix);
+          Vector4 parentOriginPosition((mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]);
+          parentOriginPosition.w = 1.0f;
+          finalWorldPosition += Vector3(parentMatrix * parentOriginPosition);
         }
 
-        mLocalMatrixDirty[i] = mComponentDirty[i] || (localMatrix != mLocal[i]);
+        mWorld[i].SetTransformComponents(finalWorldScale, finalWorldOrientation, finalWorldPosition);
+
+        Matrix inverseParentMatrix;
+        inverseParentMatrix.SetInverseTransformComponents(parentScale, parentOrientation, parentPosition);
+        mLocal[i] = inverseParentMatrix * mWorld[i];
+
+        mLocalMatrixDirty[i] = mComponentDirty[i] || (previousLocalMatrix != mLocal[i]);
       }
     }
     else //Component has no parent or doesn't inherit transform
     {
       Matrix localMatrix = mLocal[i];
-      CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
+      CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft);
       localPosition = mTxComponentAnimatable[i].mPosition + centerPosition;
       mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition);
       mWorld[i]            = mLocal[i];
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&);
diff --git a/dali/internal/update/nodes/node-helper.h b/dali/internal/update/nodes/node-helper.h
new file mode 100644 (file)
index 0000000..4997868
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
+#define DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Defines the given value, and adds an enumeration that contains it's
+ * size.  The enumeration can be used by the wrapper templated types
+ * below during structure definition. ("offsetof" requires the
+ * structure to be completely defined before use, so cannot be
+ * utilized here).
+ */
+#define BASE(_TYPE, _X)         \
+  _TYPE _X;                     \
+  enum                          \
+  {                             \
+    OFFSET_##_X = sizeof(_TYPE) \
+  };
+
+/*
+ * Create a property template instance, passing in the previously
+ * stored element, which utilizes that element's OFFSET enumeration to
+ * compute the offset of the BASE element.
+ *
+ * It is expected that _TEMPLATE is a TransformManagerPropertyVector3
+ * which takes a TransformManagerProperty enumeration and an offset
+ * to the BASE TransformManagerData.
+ *
+ * It is assumed that successive elements are aligned, and that no padding
+ * is inserted by the compiler.
+ */
+#define PROPERTY_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _PROPERTY, _ELEMENT)       \
+  using _TEMPLATE##_PROPERTY = _TEMPLATE<_PROPERTY, OFFSET_##_BASE_ELEMENT>;  \
+  _TEMPLATE##_PROPERTY _ELEMENT;                                              \
+  enum                                                                        \
+  {                                                                           \
+    OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_PROPERTY) + OFFSET_##_BASE_ELEMENT \
+  };
+
+/*
+ * Create a template instance, passing in the previously stored
+ * element, utilizing that element's OFFSET enumeration to compute the offset
+ * of the BASE element.
+ *
+ * It is expected that _TEMPLATE is a TransformManagerPropertyNNNN template
+ * which takes an offset to the BASE TransformManagerData.
+ *
+ * It is assumed that successive elements are aligned, and that no padding
+ * is inserted by the compiler.
+ */
+#define TEMPLATE_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _ELEMENT)                 \
+  using _TEMPLATE##_ELEMENT = _TEMPLATE<OFFSET_##_BASE_ELEMENT>;             \
+  _TEMPLATE##_ELEMENT _ELEMENT;                                              \
+  enum                                                                       \
+  {                                                                          \
+    OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_ELEMENT) + OFFSET_##_BASE_ELEMENT \
+  };
+
+#endif // DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
index f0f4943..87b4603 100644 (file)
@@ -27,8 +27,8 @@
 
 namespace
 {
-//Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
-// or DALI library is unloaded
+// Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
+//  or DALI library is unloaded
 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
 #ifdef DEBUG_ENABLED
 // keep track of nodes alive, to ensure we have 0 when the process exits or DALi library is unloaded
@@ -76,16 +76,16 @@ void Node::Delete(Node* node)
 }
 
 Node::Node()
-: mOrientation(), // Initialized to identity by default
-  mVisible(true),
-  mCulled(false),
-  mColor(Color::WHITE),
-  mUpdateAreaHint(Vector4::ZERO),
+: mOrientation(),                                                               // Initialized to identity by default
   mWorldPosition(TRANSFORM_PROPERTY_WORLD_POSITION, Vector3(0.0f, 0.0f, 0.0f)), // Zero initialized by default
   mWorldScale(TRANSFORM_PROPERTY_WORLD_SCALE, Vector3(1.0f, 1.0f, 1.0f)),
   mWorldOrientation(), // Initialized to identity by default
   mWorldMatrix(),
+  mVisible(true),
+  mCulled(false),
+  mColor(Color::WHITE),
   mWorldColor(Color::WHITE),
+  mUpdateAreaHint(Vector4::ZERO),
   mClippingSortModifier(0u),
   mId(++mNodeCounter),
   mParent(nullptr),
@@ -134,28 +134,14 @@ uint32_t Node::GetId() const
 
 void Node::CreateTransform(SceneGraph::TransformManager* transformManager)
 {
-  //Create a new transform
+  // Create a new transform
   mTransformManagerData.mManager = transformManager;
   TransformId createdTransformId = transformManager->CreateTransform();
 
-  //Initialize all the animatable properties
-  mPosition.Initialize(&mTransformManagerData);
-  mScale.Initialize(&mTransformManagerData);
-  mOrientation.Initialize(&mTransformManagerData);
-  mSize.Initialize(&mTransformManagerData);
-  mParentOrigin.Initialize(&mTransformManagerData);
-  mAnchorPoint.Initialize(&mTransformManagerData);
-
-  //Initialize all the input properties
-  mWorldPosition.Initialize(&mTransformManagerData);
-  mWorldScale.Initialize(&mTransformManagerData);
-  mWorldOrientation.Initialize(&mTransformManagerData);
-  mWorldMatrix.Initialize(&mTransformManagerData);
-
-  //Set whether the position should use the anchor point
+  // Set whether the position should use the anchor point
   transformManager->SetPositionUsesAnchorPoint(createdTransformId, mPositionUsesAnchorPoint);
 
-  //Set TransformId after initialize done.
+  // Set TransformId after initialize done.
   mTransformManagerData.mId = createdTransformId;
 }
 
@@ -348,6 +334,11 @@ void Node::RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex)
   }
 }
 
+uint32_t Node::GetMemoryPoolCapacity()
+{
+  return gNodeMemoryPool.GetCapacity();
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 3e28d7b..be26b7a 100644 (file)
@@ -30,6 +30,7 @@
 #include <dali/internal/update/manager/transform-manager-property.h>
 #include <dali/internal/update/manager/transform-manager.h>
 #include <dali/internal/update/nodes/node-declarations.h>
+#include <dali/internal/update/nodes/node-helper.h>
 #include <dali/internal/update/nodes/partial-rendering-data.h>
 #include <dali/internal/update/rendering/scene-graph-renderer.h>
 #include <dali/public-api/actors/actor-enumerations.h>
@@ -803,6 +804,7 @@ public:
     if(depthIndex != mDepthIndex)
     {
       SetDirtyFlag(NodePropertyFlags::DEPTH_INDEX);
+      SetUpdated(true);
       mDepthIndex = depthIndex;
     }
   }
@@ -850,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
    */
@@ -921,10 +931,10 @@ private: // from NodeDataProvider
 
 private:
   // Delete copy and move
-  Node(const Node&) = delete;
-  Node(Node&&)      = delete;
+  Node(const Node&)                = delete;
+  Node(Node&&)                     = delete;
   Node& operator=(const Node& rhs) = delete;
-  Node& operator=(Node&& rhs) = delete;
+  Node& operator=(Node&& rhs)      = delete;
 
   /**
    * Recursive helper to disconnect a Node and its children.
@@ -934,34 +944,39 @@ private:
   void RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex);
 
 public: // Default properties
-  using TransformManagerParentsOrigin = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_PARENT_ORIGIN>;
-  using TransformManagerAnchorPoint   = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_ANCHOR_POINT>;
-  using TransformManagerSize          = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_SIZE>;
-  using TransformManagerPosition      = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_POSITION>;
-  using TransformManagerScale         = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_SCALE>;
-
-  TransformManagerData               mTransformManagerData;
-  TransformManagerParentsOrigin      mParentOrigin; ///< Local transform; the position is relative to this. Sets the Transform flag dirty when changed
-  TransformManagerAnchorPoint        mAnchorPoint;  ///< Local transform; local center of rotation. Sets the Transform flag dirty when changed
-  TransformManagerSize               mSize;         ///< Size is provided for layouting
-  TransformManagerPosition           mPosition;     ///< Local transform; distance between parent-origin & anchor-point
-  TransformManagerScale              mScale;        ///< Local transform; scale relative to parent node
-  TransformManagerPropertyQuaternion mOrientation;  ///< Local transform; rotation relative to parent node
+  // Define a base offset for the following wrappers. The wrapper macros calculate offsets from the previous
+  // element such that each wrapper type generates a compile time offset to the transform manager data.
+  BASE(TransformManagerData, mTransformManagerData);
+  PROPERTY_WRAPPER(mTransformManagerData, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_PARENT_ORIGIN,
+                   mParentOrigin); // Local transform; the position is relative to this. Sets the Transform flag dirty when changed
+
+  PROPERTY_WRAPPER(mParentOrigin, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_ANCHOR_POINT,
+                   mAnchorPoint); // Local transform; local center of rotation. Sets the Transform flag dirty when changed
+
+  PROPERTY_WRAPPER(mAnchorPoint, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SIZE,
+                   mSize); // Size is provided for layouting
+
+  PROPERTY_WRAPPER(mSize, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_POSITION,
+                   mPosition); // Local transform; distance between parent-origin & anchor-point
+  PROPERTY_WRAPPER(mPosition, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SCALE,
+                   mScale); // Local transform; scale relative to parent node
+
+  TEMPLATE_WRAPPER(mScale, TransformManagerPropertyQuaternion,
+                   mOrientation); // Local transform; rotation relative to parent node
+
+  // Inherited properties; read-only from public API
+  TEMPLATE_WRAPPER(mOrientation, TransformManagerVector3Input, mWorldPosition);      // Full inherited position
+  TEMPLATE_WRAPPER(mWorldPosition, TransformManagerVector3Input, mWorldScale);       // Full inherited scale
+  TEMPLATE_WRAPPER(mWorldScale, TransformManagerQuaternionInput, mWorldOrientation); // Full inherited orientation
+  TEMPLATE_WRAPPER(mWorldOrientation, TransformManagerMatrixInput, mWorldMatrix);    // Full inherited world matrix
 
   AnimatableProperty<bool>    mVisible;        ///< Visibility can be inherited from the Node hierachy
   AnimatableProperty<bool>    mCulled;         ///< True if the node is culled. This is not animatable. It is just double-buffered.
   AnimatableProperty<Vector4> mColor;          ///< Color can be inherited from the Node hierarchy
+  InheritedColor              mWorldColor;     ///< Full inherited color
   AnimatableProperty<Vector4> mUpdateAreaHint; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
                                                ///< This is not animatable. It is just double-buffered. (Because all these bloody properties are).
 
-  // Inherited properties; read-only from public API
-
-  TransformManagerVector3Input    mWorldPosition; ///< Full inherited position
-  TransformManagerVector3Input    mWorldScale;
-  TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation
-  TransformManagerMatrixInput     mWorldMatrix;      ///< Full inherited world matrix
-  InheritedColor                  mWorldColor;       ///< Full inherited color
-
   uint64_t       mUniformsHash{0u};     ///< Hash of uniform map property values
   uint32_t       mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
   const uint32_t mId;                   ///< The Unique ID of the node.
@@ -980,8 +995,7 @@ protected:
 
   uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
   uint32_t mScissorDepth;  ///< The number of scissor clipping nodes deep this node is
-
-  uint32_t mDepthIndex; ///< Depth index of the node
+  uint32_t mDepthIndex;    ///< Depth index of the node
 
   // flags, compressed to bitfield
   NodePropertyFlags  mDirtyFlags;                  ///< Dirty flags for each of the Node properties
index cd52c50..5d7f943 100644 (file)
@@ -37,8 +37,7 @@ struct PartialRenderingData
   Vector4  color{};               /// Color
   Vector4  updatedPositionSize{}; /// Updated position/size (x, y, width, height)
   Vector3  size{};                /// Size
-  uint32_t depthIndex{0u};        /// Depth index
-  uint32_t hash;                  /// Last frame's hash
+  uint32_t hash{0u};              /// Last frame's hash
 
   bool mVisible{true};   /// Visible state (Not hashed)
   bool mRendered{false}; /// Rendering state (Not hashed)
@@ -53,7 +52,6 @@ struct PartialRenderingData
     AddToHash(hash, &color, sizeof(decltype(color)));
     AddToHash(hash, &updatedPositionSize, sizeof(decltype(updatedPositionSize)));
     AddToHash(hash, &size, sizeof(decltype(size)));
-    AddToHash(hash, &depthIndex, sizeof(decltype(depthIndex)));
   }
 
   /**
@@ -69,7 +67,6 @@ struct PartialRenderingData
            color != frameCache.color ||
            updatedPositionSize != frameCache.updatedPositionSize ||
            size != frameCache.size ||
-           depthIndex != frameCache.depthIndex ||
            !mRendered; // If everything is the same, check if we didn't render last frame.
   }
 
@@ -79,7 +76,6 @@ struct PartialRenderingData
     color               = frameCache.color;
     updatedPositionSize = frameCache.updatedPositionSize;
     size                = frameCache.size;
-    depthIndex          = frameCache.depthIndex;
     hash                = frameCache.hash;
 
     mRendered = true;
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 d30a059..9ad8470 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 2;
-const uint32_t    CORE_MICRO_VERSION = 5;
+const uint32_t    CORE_MICRO_VERSION = 6;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
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
index bdf6375..00c5de2 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.2.5
+Version:    2.2.6
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT