1 #ifndef DALI_INTERNAL_SCENE_GRAPH_SCENE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_SCENE_H
5 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
23 #include <dali/devel-api/common/map-wrapper.h>
25 #include <unordered_map>
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>
46 class RenderInstructionContainer;
51 DirtyRectKey(Node* node, Render::RendererKey renderer)
57 DirtyRectKey() = default;
59 bool operator==(const DirtyRectKey& rhs) const
61 return node == rhs.node && renderer == rhs.renderer;
64 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
65 struct DirtyRectKeyCompareLess
67 bool operator()(const DirtyRectKey& lhs, const DirtyRectKey& rhs) const noexcept
69 return (lhs.node < rhs.node) || ((lhs.node == rhs.node) && lhs.renderer.Value() < rhs.renderer.Value());
73 struct DirtyRectKeyHash
75 // Reference by : https://stackoverflow.com/a/21062236
76 std::size_t operator()(DirtyRectKey const& key) const noexcept
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;
81 constexpr std::size_t zitterShift = sizeof(std::size_t) * 4; // zitter shift to avoid hash collision
83 return ((reinterpret_cast<std::size_t>(key.node) >> nodeShift) << zitterShift) ^
84 (key.renderer.Value() >> rendererShift);
90 Render::RendererKey renderer{};
95 DirtyRectValue(Rect<int>& rect)
101 DirtyRectValue() = default;
103 Rect<int32_t> rect{};
110 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
111 using ItemsDirtyRectsContainer = std::map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyCompareLess>;
113 using ItemsDirtyRectsContainer = std::unordered_map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyHash>;
118 * @param[in] surface The render surface
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
133 void Initialize(Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable);
136 * Gets the render instructions for the scene
137 * @return the render instructions
139 RenderInstructionContainer& GetRenderInstructions();
142 * @brief Adds a callback that is called when the frame rendering is done by the graphics driver.
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.
147 * @note A callback of the following type may be used:
149 * void MyFunction( int frameId );
151 * This callback will be deleted once it is called.
153 * @note Ownership of the callback is passed onto this class.
155 void AddFrameRenderedCallback(CallbackBase* callback, int32_t frameId);
158 * @brief Adds a callback that is called when the frame is displayed on the display.
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.
163 * @note A callback of the following type may be used:
165 * void MyFunction( int frameId );
167 * This callback will be deleted once it is called.
169 * @note Ownership of the callback is passed onto this class.
171 void AddFramePresentedCallback(CallbackBase* callback, int32_t frameId);
174 * @brief Gets the callback list that is called when the frame rendering is done by the graphics driver.
176 * @param[out] callbacks The callback list
178 void GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
181 * @brief Gets the callback list that is called when the frame is displayed on the display.
183 * @param[out] callbacks The callback list
185 void GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
188 * @brief Sets whether rendering should be skipped or not.
189 * @param[in] skip true if rendering should be skipped.
191 void SetSkipRendering(bool skip);
194 * @brief Query whether rendering should be skipped or not.
195 * @return true if rendering should be skipped, false otherwise.
197 bool IsRenderingSkipped() const;
200 * Set the surface rectangle when surface is resized.
202 * @param[in] scene The resized scene.
203 * @param[in] rect The retangle representing the surface.
205 void SetSurfaceRect(const Rect<int32_t>& rect);
208 * Get the surface rectangle.
210 * @return the current surface rectangle
212 const Rect<int32_t>& GetSurfaceRect() const;
215 * Set the surface orientations when surface or screen is rotated.
217 * @param[in] windowOrientation The orientations value representing surface.
218 * @param[in] screenOrienation The orientations value representing screen.
220 void SetSurfaceOrientations(int32_t windowOrientation, int32_t screenOrienation);
223 * Get the surface orientation.
225 * @return the current surface orientation
227 int32_t GetSurfaceOrientation() const;
230 * Get the screen orientation.
232 * @return the current screen orientation
234 int32_t GetScreenOrientation() const;
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.
241 uint32_t GetSurfaceRectChangedCount();
244 * @brief Set the internal flag to acknowledge surface rotation.
246 void SetRotationCompletedAcknowledgement();
249 * @brief Query wheter is set to acknowledge for completing surface rotation.
250 * @return true it should be acknowledged.
252 bool IsRotationCompletedAcknowledgementSet();
255 * Set the render target of the surface
257 * @param[in] renderTarget The render target.
259 void SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo);
262 * @brief Keep rendering for at least the given amount of time.
264 * @param[in] durationSeconds Time to keep rendering, 0 means render at least one more frame
266 void KeepRendering(float durationSeconds);
269 * @brief Check whether rendering should keep going.
271 * @param[in] elapsedSeconds The time in seconds since the previous update.
272 * @return True if rendering should keep going.
274 bool KeepRenderingCheck(float elapsedSeconds);
277 * @brief Sets whether the scene will update partial area or full area.
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.
283 void SetPartialUpdateEnabled(bool enabled);
286 * @brief Queries whether the scene will update partial area.
288 * @return True if the scene should update partial area
290 bool IsPartialUpdateEnabled() const;
293 * @brief Query if the scene needs full update
294 * @return True if the scene needs full update
296 bool IsNeededFullUpdate() const
298 return mNeedFullUpdate;
302 * Get the render target created for the scene
304 * @return the render target
306 [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
308 return mRenderTarget.get();
312 * Remove the render target of the surface
314 void RemoveSurfaceRenderTarget()
316 mRenderTarget.reset();
320 * Get the graphics render pass created for the scene
322 * @return the graphics render pass
324 [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const
326 if(loadOp == Graphics::AttachmentLoadOp::CLEAR)
328 return mRenderPass.get();
332 return mRenderPassNoClear.get();
337 * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
339 * @return the array of clear values
341 [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
347 * @brief Set a root of the Scene
349 * @param layer The root layer
351 void SetRoot(SceneGraph::Layer* layer)
357 * @brief Get a root of the Scene
359 * @return The root layer
361 SceneGraph::Layer* GetRoot() const
367 * @brief Get ItemsDirtyRects
369 * @return the ItemsDirtyRects
371 ItemsDirtyRectsContainer& GetItemsDirtyRects();
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
377 RenderInstructionContainer mInstructions; ///< Render instructions for the scene
379 Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
381 Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks; ///< Frame rendered callbacks
382 Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
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
388 uint32_t mSurfaceRectChangedCount; ///< The numbero of surface's rectangle is changed when is resized or moved.
390 float mKeepRenderingSeconds{0.0f}; ///< Time to keep rendering
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
397 // Render pass and render target
399 Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
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.
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
410 SceneGraph::Layer* mRoot{nullptr}; ///< Root node
412 std::vector<Graphics::ClearValue> mClearValues{}; ///< Clear colors
413 ItemsDirtyRectsContainer mItemsDirtyRects{}; ///< Dirty rect list
417 inline void AddFrameRenderedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
419 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
421 // Reserve some memory inside the message queue
422 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
428 inline void AddFramePresentedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
430 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
432 // Reserve some memory inside the message queue
433 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
439 inline void SetSurfaceRectMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Rect<int32_t>& rect)
441 using LocalType = MessageValue1<Scene, Rect<int32_t> >;
443 // Reserve some memory inside the message queue
444 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
450 inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
452 using LocalType = MessageValue2<Scene, int32_t, int32_t>;
454 // Reserve some memory inside the message queue
455 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
461 inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
463 using LocalType = Message<Scene>;
465 // Reserve some memory inside the message queue
466 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
472 inline void SetSurfaceRenderTargetCreateInfoMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
474 using LocalType = MessageValue1<Scene, Graphics::RenderTargetCreateInfo>;
476 // Reserve some memory inside the message queue
477 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
483 inline void KeepRenderingMessage(EventThreadServices& eventThreadServices, const Scene& scene, float durationSeconds)
485 using LocalType = MessageValue1<Scene, float>;
487 // Reserve some memory inside the message queue
488 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
494 inline void SetPartialUpdateEnabledMessage(EventThreadServices& eventThreadServices, const Scene& scene, bool enabled)
496 using LocalType = MessageValue1<Scene, bool>;
498 // Reserve some memory inside the message queue
499 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
505 } // namespace SceneGraph
507 } // namespace Internal
511 #endif // DALI_INTERNAL_SCENE_GRAPH_SCENE_H