Merge "Added rotation support to frame-callback" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / common / scene-graph-scene.h
index 8d5339e..d004f16 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_SCENE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  */
 
+// EXTERNAL INCLUDE
+#include <cstddef>
+#include <unordered_map>
+
 // INTERNAL INCLUDES
 #include <dali/graphics-api/graphics-controller.h>
 #include <dali/integration-api/core.h>
 #include <dali/internal/common/message.h>
 #include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/render/common/render-instruction-container.h>
+#include <dali/internal/render/renderers/render-renderer.h> // RendererKey
 #include <dali/internal/update/nodes/scene-graph-layer.h>
 #include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/compile-time-math.h>
 
 namespace Dali
 {
 namespace Internal
 {
-namespace Render
-{
-class Renderer;
-}
-
 namespace SceneGraph
 {
 class RenderInstructionContainer;
 class Node;
 
-struct DirtyRect
+struct DirtyRectKey
 {
-  DirtyRect(Node* node, Render::Renderer* renderer, Rect<int>& rect)
+  DirtyRectKey(Node* node, Render::RendererKey renderer)
   : node(node),
-    renderer(renderer),
-    rect(rect),
-    visited(true)
+    renderer(renderer)
   {
   }
 
-  DirtyRect() = default;
+  DirtyRectKey() = default;
 
-  bool operator<(const DirtyRect& rhs) const
+  bool operator==(const DirtyRectKey& rhs) const
   {
-    if(node == rhs.node)
-    {
-      return renderer < rhs.renderer;
-    }
-    else
+    return node == rhs.node && renderer == rhs.renderer;
+  }
+
+  struct DirtyRectKeyHash
+  {
+    // Reference by : https://stackoverflow.com/a/21062236
+    std::size_t operator()(DirtyRectKey const& key) const noexcept
     {
-      return node < rhs.node;
+      constexpr std::size_t nodeShift     = Dali::Log<1 + sizeof(Node)>::value;
+      constexpr std::size_t rendererShift = Dali::Log<1 + sizeof(Render::Renderer)>::value;
+
+      constexpr std::size_t zitterShift = sizeof(std::size_t) * 4; // zitter shift to avoid hash collision
+
+      return ((reinterpret_cast<std::size_t>(key.node) >> nodeShift) << zitterShift) ^
+             (key.renderer.Value() >> rendererShift);
     }
+  };
+
+  Node*               node{nullptr};
+  Render::RendererKey renderer{};
+};
+
+struct DirtyRectValue
+{
+  DirtyRectValue(Rect<int>& rect)
+  : rect(rect),
+    visited(true)
+  {
   }
 
-  Node*             node{nullptr};
-  Render::Renderer* renderer{nullptr};
-  Rect<int32_t>     rect{};
-  bool              visited{true};
+  DirtyRectValue() = default;
+
+  Rect<int32_t> rect{};
+  bool          visited{true};
 };
 
 class Scene
 {
 public:
+  using ItemsDirtyRectsContainer = std::unordered_map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyHash>;
+
   /**
    * Constructor
    * @param[in] surface The render surface
@@ -280,7 +301,7 @@ public:
    *
    * @return the ItemsDirtyRects
    */
-  std::vector<DirtyRect>& GetItemsDirtyRects();
+  ItemsDirtyRectsContainer& GetItemsDirtyRects();
 
 private:
   // Render instructions describe what should be rendered during RenderManager::RenderScene()
@@ -316,8 +337,8 @@ private:
 
   SceneGraph::Layer* mRoot{nullptr}; ///< Root node
 
-  std::vector<Graphics::ClearValue>                  mClearValues{};     ///< Clear colors
-  std::vector<Dali::Internal::SceneGraph::DirtyRect> mItemsDirtyRects{}; ///< Dirty rect list
+  std::vector<Graphics::ClearValue> mClearValues{};     ///< Clear colors
+  ItemsDirtyRectsContainer          mItemsDirtyRects{}; ///< Dirty rect list
 };
 
 /// Messages