1 #ifndef DALI_INTERNAL_SCENE_GRAPH_SCENE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_SCENE_H
5 * Copyright (c) 2023 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 #include <unordered_map>
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>
42 class RenderInstructionContainer;
47 DirtyRectKey(Node* node, Render::RendererKey renderer)
53 DirtyRectKey() = default;
55 bool operator==(const DirtyRectKey& rhs) const
57 return node == rhs.node && renderer == rhs.renderer;
60 struct DirtyRectKeyHash
62 // Reference by : https://stackoverflow.com/a/21062236
63 std::size_t operator()(DirtyRectKey const& key) const noexcept
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;
68 constexpr std::size_t zitterShift = sizeof(std::size_t) * 4; // zitter shift to avoid hash collision
70 return ((reinterpret_cast<std::size_t>(key.node) >> nodeShift) << zitterShift) ^
71 (key.renderer.Value() >> rendererShift);
76 Render::RendererKey renderer{};
81 DirtyRectValue(Rect<int>& rect)
87 DirtyRectValue() = default;
96 using ItemsDirtyRectsContainer = std::unordered_map<DirtyRectKey, DirtyRectValue, DirtyRectKey::DirtyRectKeyHash>;
100 * @param[in] surface The render surface
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
115 void Initialize(Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable);
118 * Gets the render instructions for the scene
119 * @return the render instructions
121 RenderInstructionContainer& GetRenderInstructions();
124 * @brief Adds a callback that is called when the frame rendering is done by the graphics driver.
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.
129 * @note A callback of the following type may be used:
131 * void MyFunction( int frameId );
133 * This callback will be deleted once it is called.
135 * @note Ownership of the callback is passed onto this class.
137 void AddFrameRenderedCallback(CallbackBase* callback, int32_t frameId);
140 * @brief Adds a callback that is called when the frame is displayed on the display.
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.
145 * @note A callback of the following type may be used:
147 * void MyFunction( int frameId );
149 * This callback will be deleted once it is called.
151 * @note Ownership of the callback is passed onto this class.
153 void AddFramePresentedCallback(CallbackBase* callback, int32_t frameId);
156 * @brief Gets the callback list that is called when the frame rendering is done by the graphics driver.
158 * @param[out] callbacks The callback list
160 void GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
163 * @brief Gets the callback list that is called when the frame is displayed on the display.
165 * @param[out] callbacks The callback list
167 void GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks);
170 * @brief Sets whether rendering should be skipped or not.
171 * @param[in] skip true if rendering should be skipped.
173 void SetSkipRendering(bool skip);
176 * @brief Query whether rendering should be skipped or not.
177 * @return true if rendering should be skipped, false otherwise.
179 bool IsRenderingSkipped() const;
182 * Set the surface rectangle when surface is resized.
184 * @param[in] scene The resized scene.
185 * @param[in] rect The retangle representing the surface.
187 void SetSurfaceRect(const Rect<int32_t>& rect);
190 * Get the surface rectangle.
192 * @return the current surface rectangle
194 const Rect<int32_t>& GetSurfaceRect() const;
197 * Set the surface orientations when surface or screen is rotated.
199 * @param[in] windowOrientation The orientations value representing surface.
200 * @param[in] screenOrienation The orientations value representing screen.
202 void SetSurfaceOrientations(int32_t windowOrientation, int32_t screenOrienation);
205 * Get the surface orientation.
207 * @return the current surface orientation
209 int32_t GetSurfaceOrientation() const;
212 * Get the screen orientation.
214 * @return the current screen orientation
216 int32_t GetScreenOrientation() const;
219 * Query wheter the surface rect is changed or not.
220 * @return true if the surface rect is changed.
222 bool IsSurfaceRectChanged();
225 * @brief Set the internal flag to acknowledge surface rotation.
227 void SetRotationCompletedAcknowledgement();
230 * @brief Query wheter is set to acknowledge for completing surface rotation.
231 * @return true it should be acknowledged.
233 bool IsRotationCompletedAcknowledgementSet();
236 * Set the render target of the surface
238 * @param[in] renderTarget The render target.
240 void SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo);
243 * @brief Keep rendering for at least the given amount of time.
245 * @param[in] durationSeconds Time to keep rendering, 0 means render at least one more frame
247 void KeepRendering(float durationSeconds);
250 * @brief Check whether rendering should keep going.
252 * @param[in] elapsedSeconds The time in seconds since the previous update.
253 * @return True if rendering should keep going.
255 bool KeepRenderingCheck(float elapsedSeconds);
258 * @brief Query if the scene needs full update
259 * @return True if the scene needs full update
261 bool IsNeededFullUpdate() const
263 return mNeedFullUpdate;
267 * Get the render target created for the scene
269 * @return the render target
271 [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
273 return mRenderTarget.get();
277 * Remove the render target of the surface
279 void RemoveSurfaceRenderTarget()
281 mRenderTarget.reset();
285 * Get the graphics render pass created for the scene
287 * @return the graphics render pass
289 [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const
291 if(loadOp == Graphics::AttachmentLoadOp::CLEAR)
293 return mRenderPass.get();
297 return mRenderPassNoClear.get();
302 * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
304 * @return the array of clear values
306 [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
312 * @brief Set a root of the Scene
314 * @param layer The root layer
316 void SetRoot(SceneGraph::Layer* layer)
322 * @brief Get a root of the Scene
324 * @return The root layer
326 SceneGraph::Layer* GetRoot() const
332 * @brief Get ItemsDirtyRects
334 * @return the ItemsDirtyRects
336 ItemsDirtyRectsContainer& GetItemsDirtyRects();
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
342 RenderInstructionContainer mInstructions; ///< Render instructions for the scene
344 Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
346 Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks; ///< Frame rendered callbacks
347 Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
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
353 float mKeepRenderingSeconds{0.0f}; ///< Time to keep rendering
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
360 // Render pass and render target
362 Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
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.
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
373 SceneGraph::Layer* mRoot{nullptr}; ///< Root node
375 std::vector<Graphics::ClearValue> mClearValues{}; ///< Clear colors
376 ItemsDirtyRectsContainer mItemsDirtyRects{}; ///< Dirty rect list
380 inline void AddFrameRenderedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
382 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
384 // Reserve some memory inside the message queue
385 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
391 inline void AddFramePresentedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
393 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
395 // Reserve some memory inside the message queue
396 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
402 inline void SetSurfaceRectMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Rect<int32_t>& rect)
404 using LocalType = MessageValue1<Scene, Rect<int32_t> >;
406 // Reserve some memory inside the message queue
407 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
413 inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
415 using LocalType = MessageValue2<Scene, int32_t, int32_t>;
417 // Reserve some memory inside the message queue
418 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
424 inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
426 using LocalType = Message<Scene>;
428 // Reserve some memory inside the message queue
429 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
435 inline void SetSurfaceRenderTargetCreateInfoMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
437 using LocalType = MessageValue1<Scene, Graphics::RenderTargetCreateInfo>;
439 // Reserve some memory inside the message queue
440 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
446 inline void KeepRenderingMessage(EventThreadServices& eventThreadServices, const Scene& scene, float durationSeconds)
448 using LocalType = MessageValue1<Scene, float>;
450 // Reserve some memory inside the message queue
451 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
457 } // namespace SceneGraph
459 } // namespace Internal
463 #endif // DALI_INTERNAL_SCENE_GRAPH_SCENE_H