1 #ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
2 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
5 * Copyright (c) 2022 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 <dali/internal/common/buffer-index.h>
23 #include <dali/internal/common/message.h>
24 #include <dali/internal/event/common/event-thread-services.h>
25 #include <dali/internal/render/common/render-instruction.h>
26 #include <dali/internal/render/renderers/render-frame-buffer.h>
27 #include <dali/internal/update/common/animatable-property.h>
28 #include <dali/internal/update/common/property-owner.h>
29 #include <dali/public-api/math/viewport.h>
30 #include <dali/public-api/render-tasks/render-task.h>
45 class RenderInstruction;
46 class RenderMessageDispatcher;
49 * RenderTasks describe how the Dali scene should be rendered.
51 class RenderTask : public PropertyOwner, public PropertyOwner::Observer
56 RENDER_CONTINUOUSLY, ///< mRefreshRate > 0
57 RENDER_ONCE_WAITING_FOR_RESOURCES, ///< mRefreshRate = REFRESH_ONCE
58 RENDERED_ONCE, ///< mRefreshRate = REFRESH_ONCE & rendered
59 RENDERED_ONCE_AND_NOTIFIED ///< mRefreshRate = REFRESH_ONCE & rendered & notified
63 * Create a new RenderTask
65 static RenderTask* New();
70 ~RenderTask() override;
73 * Initialize the render task. Called in update thread
74 * @param[in] renderMessageDispatcher to send messages to render thread
76 void Initialize(RenderMessageDispatcher& renderMessageDispatcher);
79 * Set the nodes to be rendered.
80 * @param[in] node This node and its children will be rendered.
82 void SetSourceNode(Node* node);
85 * Retrieve the source node.
86 * @return This node and its children will be rendered.
88 Node* GetSourceNode() const;
91 * Set the ViewportGuideNode.
92 * @param[in] node This node is used to compute viewport of the render task.
94 void SetViewportGuideNode(Node* node);
97 * Retrieve the ViewportGuideNode.
98 * @return This node is used to compute viewport of the render task.
100 Node* GetViewportGuideNode() const;
103 * Set whether the RenderTask has exclusive access to the source nodes.
104 * @param[in] exclusive True if the source nodes will only be rendered by this render-task.
106 void SetExclusive(bool exclusive);
109 * Query whether the RenderTask has exclusive access to the source actors.
110 * @return True if the source actors will only be rendered by this render-task.
112 bool IsExclusive() const;
115 * Set the camera from which the scene is viewed.
116 * @param[in] cameraNode that camera is connected with
117 * @param[in] camera to use.
119 void SetCamera(Node* cameraNode, Camera* camera);
122 * Set the frame-buffer used as a render target.
123 * @param[in] frameBuffer The framebuffer
125 void SetFrameBuffer(Render::FrameBuffer* frameBuffer);
128 * Retrieve the resource ID of the frame-buffer.
129 * @return The resource ID, or zero if not rendering off-screen.
131 Render::FrameBuffer* GetFrameBuffer();
134 * Update viewport by using viewport guide node
135 * @param[in] updateBufferIndex The current update buffer index.
136 * @param[in] sceneSize The size of scene.
137 * @param[in] cameraPosition The position of default camera of the scene.
139 void UpdateViewport(BufferIndex updateBufferIndex, Vector2 sceneSize, Vector3 cameraPosition);
142 * Set the value of property viewportPosition
143 * This value will persist only for the current frame.
144 * @param[in] updateBufferIndex The current update buffer index.
145 * @param[in] value The value of the property
147 void SetViewportPosition(BufferIndex updateBufferIndex, const Vector2& value);
150 * Get the value of property viewportPosition
151 * @warning Should only be called from the Update thread
152 * @param[in] bufferIndex The buffer to read from.
153 * @return the value of the property.
155 const Vector2& GetViewportPosition(BufferIndex bufferIndex) const;
158 * Bake the value of the property viewportPosition
159 * This will also set the base value
160 * @param[in] updateBufferIndex The current update buffer index.
161 * @param[in] value The new value for property.
163 void BakeViewportPosition(BufferIndex updateBufferIndex, const Vector2& value);
166 * Set the value of property viewportSize
167 * This value will persist only for the current frame.
168 * @param[in] updateBufferIndex The current update buffer index.
169 * @param[in] value The value of the property
171 void SetViewportSize(BufferIndex updateBufferIndex, const Vector2& value);
174 * Get the value of property viewportSize
175 * @warning Should only be called from the Update thread
176 * @param[in] bufferIndex The buffer to read from.
177 * @return the value of the property.
179 const Vector2& GetViewportSize(BufferIndex bufferIndex) const;
182 * Bake the value of the property viewportSize
183 * This will also set the base value
184 * @param[in] updateBufferIndex The current update buffer index.
185 * @param[in] value The new value for property.
187 void BakeViewportSize(BufferIndex updateBufferIndex, const Vector2& value);
190 * Get the value of property viewportEnabled
191 * @warning Should only be called from the Update thread
192 * @param[in] bufferIndex The buffer to read from.
193 * @return the value of the property.
195 bool GetViewportEnabled(BufferIndex bufferIndex) const;
198 * Query whether the optional viewport is set.
199 * @param[in] bufferIndex The buffer to read from.
200 * @param[out] viewport The viewport position and size is populated.
201 * @return true if the viewport has been set
203 bool QueryViewport(BufferIndex bufferIndex, Viewport& viewport) const;
206 * Set the value of property clearColor
207 * This value will persist only for the current frame.
208 * @param[in] updateBufferIndex The current update buffer index.
209 * @param[in] value The value of the property
211 void SetClearColor(BufferIndex updateBufferIndex, const Vector4& value);
214 * Get the value of property clearColor
215 * @warning Should only be called from the Update thread
216 * @param[in] bufferIndex The buffer to read from.
217 * @return the value of the property.
219 const Vector4& GetClearColor(BufferIndex bufferIndex) const;
222 * Bake the value of the property clearColor
223 * This will also set the base value
224 * @param[in] updateBufferIndex The current update buffer index.
225 * @param[in] value The new value for property.
227 void BakeClearColor(BufferIndex updateBufferIndex, const Vector4& value);
230 * @copydoc Dali::RenderTask::SetClearEnabled()
232 void SetClearEnabled(bool enabled);
235 * @copydoc Dali::RenderTask::GetClearEnabled()
237 bool GetClearEnabled() const;
240 * @copydoc Dali::RenderTask::SetCullMode()
242 void SetCullMode(bool mode);
245 * @copydoc Dali::RenderTask::GetCullMode()
247 bool GetCullMode() const;
250 * Set the refresh-rate of the RenderTask.
251 * @param[in] refreshRate The new refresh rate.
253 void SetRefreshRate(uint32_t refreshRate);
256 * Retrieve the refresh-rate of the RenderTask.
257 * @return The refresh rate.
259 uint32_t GetRefreshRate() const;
262 * Check if the render task is ready for rendering.
263 * @param[in] updateBufferIndex The current update buffer index.
264 * @return True if the render-task is ready for rendering.
266 bool ReadyToRender(BufferIndex updateBufferIndex);
269 * True if a render is required. If the current state is RENDER_CONTINUOUSLY, then
270 * this returns true if the frame count is zero. If the current state is RENDER_ONCE_WAITING_FOR_RESOURCES, then it always returns true. In all other states, it returns false.
271 * @return true if a render is required
273 bool IsRenderRequired();
276 * Process a frame. This method is called each frame for every ready render task, regardless
277 * of whether it needs to render (so that the frame counter can be updated).
282 * Return true only if currently waiting for the render task to
283 * finish rendering and the update thread should be kept alive.
284 * @return true if waiting to be rendered
286 bool IsWaitingToRender();
289 * Return true when the render task has finished rendering and a notification
290 * needs sending. (Only one notification is sent per render once request)
291 * @return true if notification is required.
296 * @return The number of times we have transited from RENDERED_ONCE to RENDERED_ONCE_AND_NOTIFIED state.
298 uint32_t GetRenderedOnceCounter() const;
301 * Retrieve the view-matrix; this is double buffered for input handling.
302 * @pre GetCameraNode() returns a node with valid Camera.
303 * @param[in] bufferIndex The buffer to read from.
304 * @return The view-matrix.
306 const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
309 * @brief Retrieve the camera.
310 * @pre GetCameraNode() returns a node with valid Camera.
312 * @return The camera.
314 const SceneGraph::Camera& GetCamera() const;
317 * Retrieve the projection-matrix; this is double buffered for input handling.
318 * @pre GetCameraNode() returns a node with valid Camera.
319 * @param[in] bufferIndex The buffer to read from.
320 * @return The projection-matrix.
322 const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
325 * Prepares the render-instruction buffer to be populated with instructions.
327 * If the render task is a render-once framebuffer backed by a native image,
328 * then this method will ensure that a GL sync object is created to track
329 * when the rendering has finished.
331 * @param[in] updateBufferIndex The current update buffer index.
332 * @return instruction to prepare
334 RenderInstruction& PrepareRenderInstruction(BufferIndex updateBufferIndex);
337 * @return true if the view matrix has been updated during this or last frame
339 bool ViewMatrixUpdated();
342 * Indicate whether GL sync is required for native render target.
343 * @param[in] requiresSync whether GL sync is required for native render target
345 void SetSyncRequired(bool requiresSync);
348 * Retrieve the render instruction.
349 * @param[in] updateBufferIndex The current update buffer index.
350 * @return The render instruction
352 RenderInstruction& GetRenderInstruction(BufferIndex updateBufferIndex)
354 return mRenderInstruction[updateBufferIndex];
357 private: // from PropertyOwner::Observer
359 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected( PropertyOwner& owner )
361 void PropertyOwnerConnected(PropertyOwner& owner) override;
364 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected( BufferIndex updateBufferIndex, PropertyOwner& owner )
366 void PropertyOwnerDisconnected(BufferIndex updateBufferIndex, PropertyOwner& owner) override;
369 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed( PropertyOwner& owner )
371 void PropertyOwnerDestroyed(PropertyOwner& owner) override;
374 void SetActiveStatus();
382 RenderTask(const RenderTask&) = delete;
383 RenderTask& operator=(const RenderTask&) = delete;
385 public: // Animatable Properties
386 AnimatableProperty<Vector2> mViewportPosition; ///< viewportPosition
387 AnimatableProperty<Vector2> mViewportSize; ///< viewportSize
388 AnimatableProperty<Vector4> mClearColor; ///< clearColor
391 RenderMessageDispatcher* mRenderMessageDispatcher;
392 Render::RenderTracker* mRenderSyncTracker;
395 Node* mViewportGuideNode;
396 SceneGraph::Camera* mCamera;
397 Render::FrameBuffer* mFrameBuffer;
399 RenderInstruction mRenderInstruction[2]; ///< Owned double buffered render instruction. (Double buffered because this owns render commands for the currently drawn frame)
401 uint32_t mRefreshRate; ///< REFRESH_ONCE, REFRESH_ALWAYS or render every N frames
402 uint32_t mFrameCounter; ///< counter for rendering every N frames
403 uint32_t mRenderedOnceCounter; ///< Incremented whenever state changes to RENDERED_ONCE_AND_NOTIFIED
405 State mState; ///< Render state.
407 bool mRequiresSync : 1; ///< Whether sync is needed to track the render
408 bool mActive : 1; ///< True when the task is active, i.e. has valid source and camera
409 bool mWaitingToRender : 1; ///< True when an render once to FBO is waiting
410 bool mNotifyTrigger : 1; ///< True if a render once render task has finished renderering
411 bool mExclusive : 1; ///< Whether the render task has exclusive access to the source actor (node in the scene graph).
412 bool mClearEnabled : 1; ///< Whether previous results are cleared.
413 bool mCullMode : 1; ///< Whether renderers should be frustum culled
416 // Messages for RenderTask
417 inline void SetFrameBufferMessage(EventThreadServices& eventThreadServices, const RenderTask& task, Render::FrameBuffer* frameBuffer)
419 using LocalType = MessageValue1<RenderTask, Render::FrameBuffer*>;
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(&task, &RenderTask::SetFrameBuffer, frameBuffer);
428 inline void SetClearColorMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector4& value)
430 using LocalType = MessageDoubleBuffered1<RenderTask, Vector4>;
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(&task, &RenderTask::SetClearColor, value);
439 inline void BakeClearColorMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector4& value)
441 using LocalType = MessageDoubleBuffered1<RenderTask, Vector4>;
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(&task, &RenderTask::BakeClearColor, value);
450 inline void SetClearEnabledMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool enabled)
452 using LocalType = MessageValue1<RenderTask, bool>;
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(&task, &RenderTask::SetClearEnabled, enabled);
461 inline void SetCullModeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool mode)
463 using LocalType = MessageValue1<RenderTask, bool>;
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(&task, &RenderTask::SetCullMode, mode);
472 inline void SetRefreshRateMessage(EventThreadServices& eventThreadServices, const RenderTask& task, uint32_t refreshRate)
474 using LocalType = MessageValue1<RenderTask, uint32_t>;
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(&task, &RenderTask::SetRefreshRate, refreshRate);
483 inline void SetSourceNodeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode)
485 // Scene graph thread can destroy this object.
486 Node* node = const_cast<Node*>(constNode);
488 using LocalType = MessageValue1<RenderTask, Node*>;
490 // Reserve some memory inside the message queue
491 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
493 // Construct message in the message queue memory; note that delete should not be called on the return value
494 new(slot) LocalType(&task, &RenderTask::SetSourceNode, node);
497 inline void SetCameraMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode, const Camera* constCamera)
499 using LocalType = MessageValue2<RenderTask, Node*, Camera*>;
501 Node* node = const_cast<Node*>(constNode);
502 Camera* camera = const_cast<Camera*>(constCamera);
503 // Reserve memory inside the message queue
504 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
506 // Construct message in the message queue memory; note that delete should not be called on the return value
507 new(slot) LocalType(&task, &RenderTask::SetCamera, node, camera);
510 inline void SetViewportGuideNodeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode)
512 // Scene graph thread can destroy this object.
513 Node* node = const_cast<Node*>(constNode);
515 using LocalType = MessageValue1<RenderTask, Node*>;
517 // Reserve some memory inside the message queue
518 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
520 // Construct message in the message queue memory; note that delete should not be called on the return value
521 new(slot) LocalType(&task, &RenderTask::SetViewportGuideNode, node);
524 inline void SetExclusiveMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool exclusive)
526 using LocalType = MessageValue1<RenderTask, bool>;
528 // Reserve some memory inside the message queue
529 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
531 // Construct message in the message queue memory; note that delete should not be called on the return value
532 new(slot) LocalType(&task, &RenderTask::SetExclusive, exclusive);
535 inline void SetSyncRequiredMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool requiresSync)
537 using LocalType = MessageValue1<RenderTask, bool>;
539 // Reserve some memory inside the message queue
540 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
542 // Construct message in the message queue memory; note that delete should not be called on the return value
543 new(slot) LocalType(&task, &RenderTask::SetSyncRequired, requiresSync);
546 inline void BakeViewportPositionMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector2& value)
548 using LocalType = MessageDoubleBuffered1<RenderTask, Vector2>;
550 // Reserve some memory inside the message queue
551 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
553 // Construct message in the message queue memory; note that delete should not be called on the return value
554 new(slot) LocalType(&task, &RenderTask::BakeViewportPosition, value);
557 inline void BakeViewportSizeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector2& value)
559 using LocalType = MessageDoubleBuffered1<RenderTask, Vector2>;
561 // Reserve some memory inside the message queue
562 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
564 // Construct message in the message queue memory; note that delete should not be called on the return value
565 new(slot) LocalType(&task, &RenderTask::BakeViewportSize, value);
568 } // namespace SceneGraph
570 } // namespace Internal
574 #endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H