#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
const Rect<int32_t>& GetSurfaceRect() const;
/**
- * Set the surface orientation when surface is rotated.
+ * Set the surface orientations when surface or screen is rotated.
*
- * @param[in] orientation The orientation value representing the surface.
+ * @param[in] windowOrientation The orientations value representing surface.
+ * @param[in] screenOrienation The orientations value representing screen.
*/
- void SetSurfaceOrientation(int32_t orientation);
+ void SetSurfaceOrientations(int32_t windowOrientation, int32_t screenOrienation);
/**
* Get the surface orientation.
int32_t GetSurfaceOrientation() const;
/**
+ * Get the screen orientation.
+ *
+ * @return the current screen orientation
+ */
+ int32_t GetScreenOrientation() const;
+
+ /**
* Query wheter the surface rect is changed or not.
* @return true if the surface rect is changed.
*/
*
* @return the ItemsDirtyRects
*/
- std::vector<DirtyRect>& GetItemsDirtyRects();
+ ItemsDirtyRectsContainer& GetItemsDirtyRects();
private:
// Render instructions describe what should be rendered during RenderManager::RenderScene()
Rect<int32_t> mSurfaceRect; ///< The rectangle of surface which is related ot this scene.
int32_t mSurfaceOrientation; ///< The orientation of surface which is related of this scene
- bool mSurfaceRectChanged; ///< The flag of surface's rectangle is changed when is resized, moved or rotated.
+ int32_t mScreenOrientation; ///< The orientation of screen
+ bool mSurfaceRectChanged; ///< The flag of surface's rectangle is changed when is resized or moved.
bool mRotationCompletedAcknowledgement; ///< The flag of sending the acknowledgement to complete window rotation.
// Render pass and render target
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
new(slot) LocalType(&scene, &Scene::SetSurfaceRect, rect);
}
-inline void SetSurfaceOrientationMessage(EventThreadServices& eventThreadServices, const Scene& scene, int32_t orientation)
+inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
{
- using LocalType = MessageValue1<Scene, int32_t>;
+ using LocalType = MessageValue2<Scene, int32_t, int32_t>;
// Reserve some memory inside the message queue
uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
// Construct message in the message queue memory; note that delete should not be called on the return value
- new(slot) LocalType(&scene, &Scene::SetSurfaceOrientation, orientation);
+ new(slot) LocalType(&scene, &Scene::SetSurfaceOrientations, windowOrientation, screenOrientation);
}
inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)