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 * Get the render target created for the scene
245 * @return the render target
247 [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
249 return mRenderTarget.get();
253 * Get the graphics render pass created for the scene
255 * @return the graphics render pass
257 [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const
259 if(loadOp == Graphics::AttachmentLoadOp::CLEAR)
261 return mRenderPass.get();
265 return mRenderPassNoClear.get();
270 * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
272 * @return the array of clear values
274 [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
280 * @brief Set a root of the Scene
282 * @param layer The root layer
284 void SetRoot(SceneGraph::Layer* layer)
290 * @brief Get a root of the Scene
292 * @return The root layer
294 SceneGraph::Layer* GetRoot() const
300 * @brief Get ItemsDirtyRects
302 * @return the ItemsDirtyRects
304 ItemsDirtyRectsContainer& GetItemsDirtyRects();
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
310 RenderInstructionContainer mInstructions; ///< Render instructions for the scene
312 Graphics::Controller* mGraphicsController{nullptr}; ///< Graphics controller
314 Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks; ///< Frame rendered callbacks
315 Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
317 bool mSkipRendering; ///< A flag to skip rendering
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.
325 // Render pass and render target
327 Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
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.
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
338 SceneGraph::Layer* mRoot{nullptr}; ///< Root node
340 std::vector<Graphics::ClearValue> mClearValues{}; ///< Clear colors
341 ItemsDirtyRectsContainer mItemsDirtyRects{}; ///< Dirty rect list
345 inline void AddFrameRenderedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
347 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
349 // Reserve some memory inside the message queue
350 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
356 inline void AddFramePresentedCallbackMessage(EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId)
358 using LocalType = MessageValue2<Scene, CallbackBase*, int32_t>;
360 // Reserve some memory inside the message queue
361 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
367 inline void SetSurfaceRectMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Rect<int32_t>& rect)
369 using LocalType = MessageValue1<Scene, Rect<int32_t> >;
371 // Reserve some memory inside the message queue
372 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
378 inline void SetSurfaceOrientationsMessage(EventThreadServices& eventThreadServices, const Scene& scene, const int32_t windowOrientation, const int32_t screenOrientation)
380 using LocalType = MessageValue2<Scene, int32_t, int32_t>;
382 // Reserve some memory inside the message queue
383 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
389 inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
391 using LocalType = Message<Scene>;
393 // Reserve some memory inside the message queue
394 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
400 inline void SetSurfaceRenderTargetCreateInfoMessage(EventThreadServices& eventThreadServices, const Scene& scene, const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
402 using LocalType = MessageValue1<Scene, Graphics::RenderTargetCreateInfo>;
404 // Reserve some memory inside the message queue
405 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
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);
411 } // namespace SceneGraph
413 } // namespace Internal
417 #endif // DALI_INTERNAL_SCENE_GRAPH_SCENE_H