Merge "Added rotation support to frame-callback" into 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) 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    * Get the render target created for the scene
244    *
245    * @return the render target
246    */
247   [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
248   {
249     return mRenderTarget.get();
250   }
251
252   /**
253    * Get the graphics render pass created for the scene
254    *
255    * @return the graphics render pass
256    */
257   [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const
258   {
259     if(loadOp == Graphics::AttachmentLoadOp::CLEAR)
260     {
261       return mRenderPass.get();
262     }
263     else
264     {
265       return mRenderPassNoClear.get();
266     }
267   }
268
269   /**
270    * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
271    *
272    * @return the array of clear values
273    */
274   [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
275   {
276     return mClearValues;
277   }
278
279   /**
280    * @brief Set a root of the Scene
281    *
282    * @param layer The root layer
283    */
284   void SetRoot(SceneGraph::Layer* layer)
285   {
286     mRoot = layer;
287   }
288
289   /**
290    * @brief Get a root of the Scene
291    *
292    * @return The root layer
293    */
294   SceneGraph::Layer* GetRoot() const
295   {
296     return mRoot;
297   }
298
299   /**
300    * @brief Get ItemsDirtyRects
301    *
302    * @return the ItemsDirtyRects
303    */
304   ItemsDirtyRectsContainer& GetItemsDirtyRects();
305
306 private:
307   // Render instructions describe what should be rendered during RenderManager::RenderScene()
308   // Update manager updates instructions for the next frame while we render the current one
309
310   RenderInstructionContainer mInstructions; ///< Render instructions for the scene
311
312   Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
313
314   Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks;  ///< Frame rendered callbacks
315   Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
316
317   bool mSkipRendering; ///< A flag to skip rendering
318
319   Rect<int32_t> mSurfaceRect;                      ///< The rectangle of surface which is related ot this scene.
320   int32_t       mSurfaceOrientation;               ///< The orientation of surface which is related of this scene
321   int32_t       mScreenOrientation;                ///< The orientation of screen
322   bool          mSurfaceRectChanged;               ///< The flag of surface's rectangle is changed when is resized or moved.
323   bool          mRotationCompletedAcknowledgement; ///< The flag of sending the acknowledgement to complete window rotation.
324
325   // Render pass and render target
326
327   Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
328
329   /**
330    * Render pass is created on fly depending on Load and Store operations
331    * The default render pass (most likely to be used) is the load = CLEAR
332    * and store = STORE for color attachment.
333    */
334   Graphics::UniquePtr<Graphics::RenderPass>   mRenderPass{nullptr};        ///< The render pass created to render the surface
335   Graphics::UniquePtr<Graphics::RenderPass>   mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color
336   Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};      ///< This is created in Update/Render thread when surface is created/resized/replaced
337
338   SceneGraph::Layer* mRoot{nullptr}; ///< Root node
339
340   std::vector<Graphics::ClearValue> mClearValues{};     ///< Clear colors
341   ItemsDirtyRectsContainer          mItemsDirtyRects{}; ///< Dirty rect list
342 };
343
344 /// Messages
345 inline void AddFrameRenderedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
346 {
347   using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
348
349   // Reserve some memory inside the message queue
350   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
351
352   // Construct message in the message queue memory; note that delete should not be called on the return value
353   new(slot) LocalType(&scene, &Scene::AddFrameRenderedCallback, const_cast<CallbackBase*>(callback), frameId);
354 }
355
356 inline void AddFramePresentedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
357 {
358   using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
359
360   // Reserve some memory inside the message queue
361   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
362
363   // Construct message in the message queue memory; note that delete should not be called on the return value
364   new(slot) LocalType(&scene, &Scene::AddFramePresentedCallback, const_cast<CallbackBase*>(callback), frameId);
365 }
366
367 inline void SetSurfaceRectMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Rect<int32_t>& rect)
368 {
369   using LocalType = MessageValue1<Scene, Rect<int32_t> >;
370
371   // Reserve some memory inside the message queue
372   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
373
374   // Construct message in the message queue memory; note that delete should not be called on the return value
375   new(slot) LocalType(&scene, &Scene::SetSurfaceRect, rect);
376 }
377
378 inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
379 {
380   using LocalType = MessageValue2<Scene, int32_t, int32_t>;
381
382   // Reserve some memory inside the message queue
383   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
384
385   // Construct message in the message queue memory; note that delete should not be called on the return value
386   new(slot) LocalType(&scene, &Scene::SetSurfaceOrientations, windowOrientation, screenOrientation);
387 }
388
389 inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
390 {
391   using LocalType = Message<Scene>;
392
393   // Reserve some memory inside the message queue
394   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
395
396   // Construct message in the message queue memory; note that delete should not be called on the return value
397   new(slot) LocalType(&scene, &Scene::SetRotationCompletedAcknowledgement);
398 }
399
400 inline void SetSurfaceRenderTargetCreateInfoMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
401 {
402   using LocalType = MessageValue1<Scene, Graphics::RenderTargetCreateInfo>;
403
404   // Reserve some memory inside the message queue
405   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
406
407   // Construct message in the message queue memory; note that delete should not be called on the return value
408   new(slot) LocalType(&scene, &Scene::SetSurfaceRenderTargetCreateInfo, renderTargetCreateInfo);
409 }
410
411 } // namespace SceneGraph
412
413 } // namespace Internal
414
415 } // namespace Dali
416
417 #endif // DALI_INTERNAL_SCENE_GRAPH_SCENE_H