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