[dali_2.3.25] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / common / scene-graph-scene.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_SCENE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_SCENE_H
3
4 /*
5  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDE
21 #include <cstddef>
22 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
23 #include <dali/devel-api/common/map-wrapper.h>
24 #else
25 #include <unordered_map>
26 #endif
27
28 // INTERNAL INCLUDES
29 #include <dali/graphics-api/graphics-controller.h>
30 #include <dali/integration-api/core.h>
31 #include <dali/integration-api/scene.h>
32 #include <dali/internal/common/message.h>
33 #include <dali/internal/event/common/event-thread-services.h>
34 #include <dali/internal/render/common/render-instruction-container.h>
35 #include <dali/internal/render/renderers/render-renderer.h> // RendererKey
36 #include <dali/internal/update/nodes/scene-graph-layer.h>
37 #include <dali/public-api/common/vector-wrapper.h>
38 #include <dali/public-api/math/compile-time-math.h>
39
40 namespace Dali
41 {
42 namespace Internal
43 {
44 namespace SceneGraph
45 {
46 class RenderInstructionContainer;
47 class Node;
48
49 struct DirtyRectKey
50 {
51   DirtyRectKey(Node* node, Render::RendererKey renderer)
52   : node(node),
53     renderer(renderer)
54   {
55   }
56
57   DirtyRectKey() = default;
58
59   bool operator==(const DirtyRectKey& rhs) const
60   {
61     return node == rhs.node && renderer == rhs.renderer;
62   }
63
64 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
65   struct DirtyRectKeyCompareLess
66   {
67     bool operator()(const DirtyRectKey& lhs, const DirtyRectKey& rhs) const noexcept
68     {
69       return (lhs.node < rhs.node) || ((lhs.node == rhs.node) && lhs.renderer.Value() < rhs.renderer.Value());
70     }
71   };
72 #else
73   struct DirtyRectKeyHash
74   {
75     // Reference by : https://stackoverflow.com/a/21062236
76     std::size_t operator()(DirtyRectKey const& key) const noexcept
77     {
78       constexpr std::size_t nodeShift     = Dali::Log<1 + sizeof(Node)>::value;
79       constexpr std::size_t rendererShift = Dali::Log<1 + sizeof(Render::Renderer)>::value;
80
81       constexpr std::size_t zitterShift = sizeof(std::size_t) * 4; // zitter shift to avoid hash collision
82
83       return ((reinterpret_cast<std::size_t>(key.node) >> nodeShift) << zitterShift) ^
84              (key.renderer.Value() >> rendererShift);
85     }
86   };
87 #endif
88
89   Node*               node{nullptr};
90   Render::RendererKey renderer{};
91 };
92
93 struct DirtyRectValue
94 {
95   DirtyRectValue(Rect<int>& rect)
96   : rect(rect),
97     visited(true)
98   {
99   }
100
101   DirtyRectValue() = default;
102
103   Rect<int32_t> rect{};
104   bool          visited{true};
105 };
106
107 class Scene
108 {
109 public:
110 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
111   using ItemsDirtyRectsContainer = std::map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyCompareLess>;
112 #else
113   using ItemsDirtyRectsContainer = std::unordered_map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyHash>;
114 #endif
115
116   /**
117    * Constructor
118    * @param[in] surface The render surface
119    */
120   Scene();
121
122   /**
123    * Destructor
124    */
125   virtual ~Scene();
126
127   /**
128    * Creates a scene object in the GPU.
129    * @param[in] graphicsController The graphics controller
130    * @param[in] depthBufferAvailable True if there is a depth buffer
131    * @param[in] stencilBufferAvailable True if there is a stencil buffer
132    */
133   void Initialize(Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable);
134
135   /**
136    * Gets the render instructions for the scene
137    * @return the render instructions
138    */
139   RenderInstructionContainer& GetRenderInstructions();
140
141   /**
142    * @brief Adds a callback that is called when the frame rendering is done by the graphics driver.
143    *
144    * @param[in] callback The function to call
145    * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
146    *
147    * @note A callback of the following type may be used:
148    * @code
149    *   void MyFunction( int frameId );
150    * @endcode
151    * This callback will be deleted once it is called.
152    *
153    * @note Ownership of the callback is passed onto this class.
154    */
155   void AddFrameRenderedCallback(CallbackBase* callback, int32_t frameId);
156
157   /**
158    * @brief Adds a callback that is called when the frame is displayed on the display.
159    *
160    * @param[in] callback The function to call
161    * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
162    *
163    * @note A callback of the following type may be used:
164    * @code
165    *   void MyFunction( int frameId );
166    * @endcode
167    * This callback will be deleted once it is called.
168    *
169    * @note Ownership of the callback is passed onto this class.
170    */
171   void AddFramePresentedCallback(CallbackBase* callback, int32_t frameId);
172
173   /**
174    * @brief Gets the callback list that is called when the frame rendering is done by the graphics driver.
175    *
176    * @param[out] callbacks The callback list
177    */
178   void GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
179
180   /**
181    * @brief Gets the callback list that is called when the frame is displayed on the display.
182    *
183    * @param[out] callbacks The callback list
184    */
185   void GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
186
187   /**
188    * @brief Sets whether rendering should be skipped or not.
189    * @param[in] skip true if rendering should be skipped.
190    */
191   void SetSkipRendering(bool skip);
192
193   /**
194    * @brief Query whether rendering should be skipped or not.
195    * @return true if rendering should be skipped, false otherwise.
196    */
197   bool IsRenderingSkipped() const;
198
199   /**
200    * Set the surface rectangle when surface is resized.
201    *
202    * @param[in] scene The resized scene.
203    * @param[in] rect The retangle representing the surface.
204    */
205   void SetSurfaceRect(const Rect<int32_t>& rect);
206
207   /**
208    * Get the surface rectangle.
209    *
210    * @return the current surface rectangle
211    */
212   const Rect<int32_t>& GetSurfaceRect() const;
213
214   /**
215    * Set the surface orientations when surface or screen is rotated.
216    *
217    * @param[in] windowOrientation The orientations value representing surface.
218    * @param[in] screenOrienation The orientations value representing screen.
219    */
220   void SetSurfaceOrientations(int32_t windowOrientation, int32_t screenOrienation);
221
222   /**
223    * Get the surface orientation.
224    *
225    * @return the current surface orientation
226    */
227   int32_t GetSurfaceOrientation() const;
228
229   /**
230    * Get the screen orientation.
231    *
232    * @return the current screen orientation
233    */
234   int32_t GetScreenOrientation() const;
235
236   /**
237    * Query how many times the surface rect changed.
238    * @note It will reset surface rect changed count.
239    * @return The count of the surface rect changed.
240    */
241   uint32_t GetSurfaceRectChangedCount();
242
243   /**
244    * @brief Set the internal flag to acknowledge surface rotation.
245    */
246   void SetRotationCompletedAcknowledgement();
247
248   /**
249    * @brief Query wheter is set to acknowledge for completing surface rotation.
250    * @return true it should be acknowledged.
251    */
252   bool IsRotationCompletedAcknowledgementSet();
253
254   /**
255    * Set the render target of the surface
256    *
257    * @param[in] renderTarget The render target.
258    */
259   void SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo);
260
261   /**
262    * @brief Keep rendering for at least the given amount of time.
263    *
264    * @param[in] durationSeconds Time to keep rendering, 0 means render at least one more frame
265    */
266   void KeepRendering(float durationSeconds);
267
268   /**
269    * @brief Check whether rendering should keep going.
270    *
271    * @param[in] elapsedSeconds The time in seconds since the previous update.
272    * @return True if rendering should keep going.
273    */
274   bool KeepRenderingCheck(float elapsedSeconds);
275
276   /**
277    * @brief Sets whether the scene will update partial area or full area.
278    *
279    * @param[in] enabled True if the scene should update partial area
280    * @note This doesn't change the global value which is set by the environment variable.
281    * This works when partial update is enabled by the environment variable. If the partial update is disabled by the environment variable, it changes nothing.
282    */
283   void SetPartialUpdateEnabled(bool enabled);
284
285   /**
286    * @brief Queries whether the scene will update partial area.
287    *
288    * @return True if the scene should update partial area
289    */
290   bool IsPartialUpdateEnabled() const;
291
292   /**
293    * @brief Query if the scene needs full update
294    * @return True if the scene needs full update
295    */
296   bool IsNeededFullUpdate() const
297   {
298     return mNeedFullUpdate;
299   }
300
301   /**
302    * Get the render target created for the scene
303    *
304    * @return the render target
305    */
306   [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
307   {
308     return mRenderTarget.get();
309   }
310
311   /**
312    * Remove the render target of the surface
313    */
314   void RemoveSurfaceRenderTarget()
315   {
316     mRenderTarget.reset();
317   }
318
319   /**
320    * Get the graphics render pass created for the scene
321    *
322    * @return the graphics render pass
323    */
324   [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const
325   {
326     if(loadOp == Graphics::AttachmentLoadOp::CLEAR)
327     {
328       return mRenderPass.get();
329     }
330     else
331     {
332       return mRenderPassNoClear.get();
333     }
334   }
335
336   /**
337    * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
338    *
339    * @return the array of clear values
340    */
341   [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
342   {
343     return mClearValues;
344   }
345
346   /**
347    * @brief Set a root of the Scene
348    *
349    * @param layer The root layer
350    */
351   void SetRoot(SceneGraph::Layer* layer)
352   {
353     mRoot = layer;
354   }
355
356   /**
357    * @brief Get a root of the Scene
358    *
359    * @return The root layer
360    */
361   SceneGraph::Layer* GetRoot() const
362   {
363     return mRoot;
364   }
365
366   /**
367    * @brief Get ItemsDirtyRects
368    *
369    * @return the ItemsDirtyRects
370    */
371   ItemsDirtyRectsContainer& GetItemsDirtyRects();
372
373 private:
374   // Render instructions describe what should be rendered during RenderManager::RenderScene()
375   // Update manager updates instructions for the next frame while we render the current one
376
377   RenderInstructionContainer mInstructions; ///< Render instructions for the scene
378
379   Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
380
381   Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks;  ///< Frame rendered callbacks
382   Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
383
384   Rect<int32_t> mSurfaceRect;        ///< The rectangle of surface which is related ot this scene.
385   int32_t       mSurfaceOrientation; ///< The orientation of surface which is related of this scene
386   int32_t       mScreenOrientation;  ///< The orientation of screen
387
388   uint32_t mSurfaceRectChangedCount; ///< The numbero of surface's rectangle is changed when is resized or moved.
389
390   float mKeepRenderingSeconds{0.0f}; ///< Time to keep rendering
391
392   bool mRotationCompletedAcknowledgement; ///< The flag of sending the acknowledgement to complete window rotation.
393   bool mSkipRendering;                    ///< A flag to skip rendering
394   bool mNeedFullUpdate;                   ///< A flag to update full area
395   bool mPartialUpdateEnabled;             ///< True if the partial update is enabled
396
397   // Render pass and render target
398
399   Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
400
401   /**
402    * Render pass is created on fly depending on Load and Store operations
403    * The default render pass (most likely to be used) is the load = CLEAR
404    * and store = STORE for color attachment.
405    */
406   Graphics::UniquePtr<Graphics::RenderPass>   mRenderPass{nullptr};        ///< The render pass created to render the surface
407   Graphics::UniquePtr<Graphics::RenderPass>   mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color
408   Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};      ///< This is created in Update/Render thread when surface is created/resized/replaced
409
410   SceneGraph::Layer* mRoot{nullptr}; ///< Root node
411
412   std::vector<Graphics::ClearValue> mClearValues{};     ///< Clear colors
413   ItemsDirtyRectsContainer          mItemsDirtyRects{}; ///< Dirty rect list
414 };
415
416 /// Messages
417 inline void AddFrameRenderedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
418 {
419   using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
420
421   // Reserve some memory inside the message queue
422   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
423
424   // Construct message in the message queue memory; note that delete should not be called on the return value
425   new(slot) LocalType(&scene, &Scene::AddFrameRenderedCallback, const_cast<CallbackBase*>(callback), frameId);
426 }
427
428 inline void AddFramePresentedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
429 {
430   using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
431
432   // Reserve some memory inside the message queue
433   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
434
435   // Construct message in the message queue memory; note that delete should not be called on the return value
436   new(slot) LocalType(&scene, &Scene::AddFramePresentedCallback, const_cast<CallbackBase*>(callback), frameId);
437 }
438
439 inline void SetSurfaceRectMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Rect<int32_t>& rect)
440 {
441   using LocalType = MessageValue1<Scene, Rect<int32_t> >;
442
443   // Reserve some memory inside the message queue
444   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
445
446   // Construct message in the message queue memory; note that delete should not be called on the return value
447   new(slot) LocalType(&scene, &Scene::SetSurfaceRect, rect);
448 }
449
450 inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
451 {
452   using LocalType = MessageValue2<Scene, int32_t, int32_t>;
453
454   // Reserve some memory inside the message queue
455   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
456
457   // Construct message in the message queue memory; note that delete should not be called on the return value
458   new(slot) LocalType(&scene, &Scene::SetSurfaceOrientations, windowOrientation, screenOrientation);
459 }
460
461 inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
462 {
463   using LocalType = Message<Scene>;
464
465   // Reserve some memory inside the message queue
466   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
467
468   // Construct message in the message queue memory; note that delete should not be called on the return value
469   new(slot) LocalType(&scene, &Scene::SetRotationCompletedAcknowledgement);
470 }
471
472 inline void SetSurfaceRenderTargetCreateInfoMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
473 {
474   using LocalType = MessageValue1<Scene, Graphics::RenderTargetCreateInfo>;
475
476   // Reserve some memory inside the message queue
477   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
478
479   // Construct message in the message queue memory; note that delete should not be called on the return value
480   new(slot) LocalType(&scene, &Scene::SetSurfaceRenderTargetCreateInfo, renderTargetCreateInfo);
481 }
482
483 inline void KeepRenderingMessage(EventThreadServices& eventThreadServices, const Scene& scene, float durationSeconds)
484 {
485   using LocalType = MessageValue1<Scene, float>;
486
487   // Reserve some memory inside the message queue
488   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
489
490   // Construct message in the message queue memory; note that delete should not be called on the return value
491   new(slot) LocalType(&scene, &Scene::KeepRendering, durationSeconds);
492 }
493
494 inline void SetPartialUpdateEnabledMessage(EventThreadServices& eventThreadServices, const Scene& scene, bool enabled)
495 {
496   using LocalType = MessageValue1<Scene, bool>;
497
498   // Reserve some memory inside the message queue
499   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
500
501   // Construct message in the message queue memory; note that delete should not be called on the return value
502   new(slot) LocalType(&scene, &Scene::SetPartialUpdateEnabled, enabled);
503 }
504
505 } // namespace SceneGraph
506
507 } // namespace Internal
508
509 } // namespace Dali
510
511 #endif // DALI_INTERNAL_SCENE_GRAPH_SCENE_H