1 #ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
2 #define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
5 * Copyright (c) 2021 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 whether the RenderTask has exclusive access to the source nodes.
92 * @param[in] exclusive True if the source nodes will only be rendered by this render-task.
94 void SetExclusive(bool exclusive);
97 * Query whether the RenderTask has exclusive access to the source actors.
98 * @return True if the source actors will only be rendered by this render-task.
100 bool IsExclusive() const;
103 * Set the camera from which the scene is viewed.
104 * @param[in] cameraNode that camera is connected with
105 * @param[in] camera to use.
107 void SetCamera(Node* cameraNode, Camera* camera);
110 * Set the frame-buffer used as a render target.
111 * @param[in] frameBuffer The framebuffer
113 void SetFrameBuffer(Render::FrameBuffer* frameBuffer);
116 * Retrieve the resource ID of the frame-buffer.
117 * @return The resource ID, or zero if not rendering off-screen.
119 Render::FrameBuffer* GetFrameBuffer();
122 * Set the value of property viewportPosition
123 * This value will persist only for the current frame.
124 * @param[in] updateBufferIndex The current update buffer index.
125 * @param[in] value The value of the property
127 void SetViewportPosition(BufferIndex updateBufferIndex, const Vector2& value);
130 * Get the value of property viewportPosition
131 * @warning Should only be called from the Update thread
132 * @param[in] bufferIndex The buffer to read from.
133 * @return the value of the property.
135 const Vector2& GetViewportPosition(BufferIndex bufferIndex) const;
138 * Bake the value of the property viewportPosition
139 * This will also set the base value
140 * @param[in] updateBufferIndex The current update buffer index.
141 * @param[in] value The new value for property.
143 void BakeViewportPosition(BufferIndex updateBufferIndex, const Vector2& value);
146 * Set the value of property viewportSize
147 * This value will persist only for the current frame.
148 * @param[in] updateBufferIndex The current update buffer index.
149 * @param[in] value The value of the property
151 void SetViewportSize(BufferIndex updateBufferIndex, const Vector2& value);
154 * Get the value of property viewportSize
155 * @warning Should only be called from the Update thread
156 * @param[in] bufferIndex The buffer to read from.
157 * @return the value of the property.
159 const Vector2& GetViewportSize(BufferIndex bufferIndex) const;
162 * Bake the value of the property viewportSize
163 * This will also set the base value
164 * @param[in] updateBufferIndex The current update buffer index.
165 * @param[in] value The new value for property.
167 void BakeViewportSize(BufferIndex updateBufferIndex, const Vector2& value);
170 * Get the value of property viewportEnabled
171 * @warning Should only be called from the Update thread
172 * @param[in] bufferIndex The buffer to read from.
173 * @return the value of the property.
175 bool GetViewportEnabled(BufferIndex bufferIndex) const;
178 * Query whether the optional viewport is set.
179 * @param[in] bufferIndex The buffer to read from.
180 * @param[out] viewport The viewport position and size is populated.
181 * @return true if the viewport has been set
183 bool QueryViewport(BufferIndex bufferIndex, Viewport& viewport) const;
186 * Set the value of property clearColor
187 * This value will persist only for the current frame.
188 * @param[in] updateBufferIndex The current update buffer index.
189 * @param[in] value The value of the property
191 void SetClearColor(BufferIndex updateBufferIndex, const Vector4& value);
194 * Get the value of property clearColor
195 * @warning Should only be called from the Update thread
196 * @param[in] bufferIndex The buffer to read from.
197 * @return the value of the property.
199 const Vector4& GetClearColor(BufferIndex bufferIndex) const;
202 * Bake the value of the property clearColor
203 * This will also set the base value
204 * @param[in] updateBufferIndex The current update buffer index.
205 * @param[in] value The new value for property.
207 void BakeClearColor(BufferIndex updateBufferIndex, const Vector4& value);
210 * @copydoc Dali::RenderTask::SetClearEnabled()
212 void SetClearEnabled(bool enabled);
215 * @copydoc Dali::RenderTask::GetClearEnabled()
217 bool GetClearEnabled() const;
220 * @copydoc Dali::RenderTask::SetCullMode()
222 void SetCullMode(bool mode);
225 * @copydoc Dali::RenderTask::GetCullMode()
227 bool GetCullMode() const;
230 * Set the refresh-rate of the RenderTask.
231 * @param[in] refreshRate The new refresh rate.
233 void SetRefreshRate(uint32_t refreshRate);
236 * Retrieve the refresh-rate of the RenderTask.
237 * @return The refresh rate.
239 uint32_t GetRefreshRate() const;
242 * Check if the render task is ready for rendering.
243 * @param[in] updateBufferIndex The current update buffer index.
244 * @return True if the render-task is ready for rendering.
246 bool ReadyToRender(BufferIndex updateBufferIndex);
249 * True if a render is required. If the current state is RENDER_CONTINUOUSLY, then
250 * 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.
251 * @return true if a render is required
253 bool IsRenderRequired();
256 * Process a frame. This method is called each frame for every ready render task, regardless
257 * of whether it needs to render (so that the frame counter can be updated).
262 * Return true only if currently waiting for the render task to
263 * finish rendering and the update thread should be kept alive.
264 * @return true if waiting to be rendered
266 bool IsWaitingToRender();
269 * Return true when the render task has finished rendering and a notification
270 * needs sending. (Only one notification is sent per render once request)
271 * @return true if notification is required.
276 * @return The number of times we have transited from RENDERED_ONCE to RENDERED_ONCE_AND_NOTIFIED state.
278 uint32_t GetRenderedOnceCounter() const;
281 * Retrieve the view-matrix; this is double buffered for input handling.
282 * @pre GetCameraNode() returns a node with valid Camera.
283 * @param[in] bufferIndex The buffer to read from.
284 * @return The view-matrix.
286 const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
289 * @brief Retrieve the camera.
290 * @pre GetCameraNode() returns a node with valid Camera.
292 * @return The camera.
294 SceneGraph::Camera& GetCamera() const;
297 * Retrieve the projection-matrix; this is double buffered for input handling.
298 * @pre GetCameraNode() returns a node with valid Camera.
299 * @param[in] bufferIndex The buffer to read from.
300 * @return The projection-matrix.
302 const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
305 * Prepares the render-instruction buffer to be populated with instructions.
307 * If the render task is a render-once framebuffer backed by a native image,
308 * then this method will ensure that a GL sync object is created to track
309 * when the rendering has finished.
311 * @param[in] updateBufferIndex The current update buffer index.
312 * @return instruction to prepare
314 RenderInstruction& PrepareRenderInstruction(BufferIndex updateBufferIndex);
317 * @return true if the view matrix has been updated during this or last frame
319 bool ViewMatrixUpdated();
322 * Indicate whether GL sync is required for native render target.
323 * @param[in] requiresSync whether GL sync is required for native render target
325 void SetSyncRequired(bool requiresSync);
328 * Retrieve the render instruction.
329 * @param[in] updateBufferIndex The current update buffer index.
330 * @return The render instruction
332 RenderInstruction& GetRenderInstruction(BufferIndex updateBufferIndex)
334 return mRenderInstruction[updateBufferIndex];
337 private: // from PropertyOwner::Observer
339 * @copydoc PropertyOwner::Observer::PropertyOwnerConnected( PropertyOwner& owner )
341 void PropertyOwnerConnected(PropertyOwner& owner) override;
344 * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected( BufferIndex updateBufferIndex, PropertyOwner& owner )
346 void PropertyOwnerDisconnected(BufferIndex updateBufferIndex, PropertyOwner& owner) override;
349 * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed( PropertyOwner& owner )
351 void PropertyOwnerDestroyed(PropertyOwner& owner) override;
354 void SetActiveStatus();
362 RenderTask(const RenderTask&) = delete;
363 RenderTask& operator=(const RenderTask&) = delete;
365 public: // Animatable Properties
366 AnimatableProperty<Vector2> mViewportPosition; ///< viewportPosition
367 AnimatableProperty<Vector2> mViewportSize; ///< viewportSize
368 AnimatableProperty<Vector4> mClearColor; ///< clearColor
371 RenderMessageDispatcher* mRenderMessageDispatcher;
372 Render::RenderTracker* mRenderSyncTracker;
375 SceneGraph::Camera* mCamera;
376 Render::FrameBuffer* mFrameBuffer;
378 RenderInstruction mRenderInstruction[2]; ///< Owned double buffered render instruction. (Double buffered because this owns render commands for the currently drawn frame)
380 uint32_t mRefreshRate; ///< REFRESH_ONCE, REFRESH_ALWAYS or render every N frames
381 uint32_t mFrameCounter; ///< counter for rendering every N frames
382 uint32_t mRenderedOnceCounter; ///< Incremented whenever state changes to RENDERED_ONCE_AND_NOTIFIED
384 State mState; ///< Render state.
386 bool mRequiresSync : 1; ///< Whether sync is needed to track the render
387 bool mActive : 1; ///< True when the task is active, i.e. has valid source and camera
388 bool mWaitingToRender : 1; ///< True when an render once to FBO is waiting
389 bool mNotifyTrigger : 1; ///< True if a render once render task has finished renderering
390 bool mExclusive : 1; ///< Whether the render task has exclusive access to the source actor (node in the scene graph).
391 bool mClearEnabled : 1; ///< Whether previous results are cleared.
392 bool mCullMode : 1; ///< Whether renderers should be frustum culled
395 // Messages for RenderTask
396 inline void SetFrameBufferMessage(EventThreadServices& eventThreadServices, const RenderTask& task, Render::FrameBuffer* frameBuffer)
398 using LocalType = MessageValue1<RenderTask, Render::FrameBuffer*>;
400 // Reserve some memory inside the message queue
401 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
403 // Construct message in the message queue memory; note that delete should not be called on the return value
404 new(slot) LocalType(&task, &RenderTask::SetFrameBuffer, frameBuffer);
407 inline void SetClearColorMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector4& value)
409 using LocalType = MessageDoubleBuffered1<RenderTask, Vector4>;
411 // Reserve some memory inside the message queue
412 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
414 // Construct message in the message queue memory; note that delete should not be called on the return value
415 new(slot) LocalType(&task, &RenderTask::SetClearColor, value);
418 inline void BakeClearColorMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector4& value)
420 using LocalType = MessageDoubleBuffered1<RenderTask, Vector4>;
422 // Reserve some memory inside the message queue
423 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
425 // Construct message in the message queue memory; note that delete should not be called on the return value
426 new(slot) LocalType(&task, &RenderTask::BakeClearColor, value);
429 inline void SetClearEnabledMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool enabled)
431 using LocalType = MessageValue1<RenderTask, bool>;
433 // Reserve some memory inside the message queue
434 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
436 // Construct message in the message queue memory; note that delete should not be called on the return value
437 new(slot) LocalType(&task, &RenderTask::SetClearEnabled, enabled);
440 inline void SetCullModeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool mode)
442 using LocalType = MessageValue1<RenderTask, bool>;
444 // Reserve some memory inside the message queue
445 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
447 // Construct message in the message queue memory; note that delete should not be called on the return value
448 new(slot) LocalType(&task, &RenderTask::SetCullMode, mode);
451 inline void SetRefreshRateMessage(EventThreadServices& eventThreadServices, const RenderTask& task, uint32_t refreshRate)
453 using LocalType = MessageValue1<RenderTask, uint32_t>;
455 // Reserve some memory inside the message queue
456 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
458 // Construct message in the message queue memory; note that delete should not be called on the return value
459 new(slot) LocalType(&task, &RenderTask::SetRefreshRate, refreshRate);
462 inline void SetSourceNodeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode)
464 // Scene graph thread can destroy this object.
465 Node* node = const_cast<Node*>(constNode);
467 using LocalType = MessageValue1<RenderTask, Node*>;
469 // Reserve some memory inside the message queue
470 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
472 // Construct message in the message queue memory; note that delete should not be called on the return value
473 new(slot) LocalType(&task, &RenderTask::SetSourceNode, node);
476 inline void SetCameraMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode, const Camera* constCamera)
478 using LocalType = MessageValue2<RenderTask, Node*, Camera*>;
480 Node* node = const_cast<Node*>(constNode);
481 Camera* camera = const_cast<Camera*>(constCamera);
482 // Reserve memory inside the message queue
483 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
485 // Construct message in the message queue memory; note that delete should not be called on the return value
486 new(slot) LocalType(&task, &RenderTask::SetCamera, node, camera);
489 inline void SetExclusiveMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool exclusive)
491 using LocalType = MessageValue1<RenderTask, bool>;
493 // Reserve some memory inside the message queue
494 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
496 // Construct message in the message queue memory; note that delete should not be called on the return value
497 new(slot) LocalType(&task, &RenderTask::SetExclusive, exclusive);
500 inline void SetSyncRequiredMessage(EventThreadServices& eventThreadServices, const RenderTask& task, bool requiresSync)
502 using LocalType = MessageValue1<RenderTask, bool>;
504 // Reserve some memory inside the message queue
505 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
507 // Construct message in the message queue memory; note that delete should not be called on the return value
508 new(slot) LocalType(&task, &RenderTask::SetSyncRequired, requiresSync);
511 inline void BakeViewportPositionMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector2& value)
513 using LocalType = MessageDoubleBuffered1<RenderTask, Vector2>;
515 // Reserve some memory inside the message queue
516 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
518 // Construct message in the message queue memory; note that delete should not be called on the return value
519 new(slot) LocalType(&task, &RenderTask::BakeViewportPosition, value);
522 inline void BakeViewportSizeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Vector2& value)
524 using LocalType = MessageDoubleBuffered1<RenderTask, Vector2>;
526 // Reserve some memory inside the message queue
527 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
529 // Construct message in the message queue memory; note that delete should not be called on the return value
530 new(slot) LocalType(&task, &RenderTask::BakeViewportSize, value);
533 } // namespace SceneGraph
535 } // namespace Internal
539 #endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H