[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_NODE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_NODE_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/internal/common/message.h>
24 #include <dali/internal/event/common/event-thread-services.h>
25 #include <dali/internal/render/data-providers/node-data-provider.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/common/inherited-property.h>
28 #include <dali/internal/update/common/property-owner.h>
29 #include <dali/internal/update/common/scene-graph-buffers.h>
30 #include <dali/internal/update/manager/transform-manager-property.h>
31 #include <dali/internal/update/manager/transform-manager.h>
32 #include <dali/internal/update/nodes/node-declarations.h>
33 #include <dali/internal/update/nodes/node-helper.h>
34 #include <dali/internal/update/nodes/partial-rendering-data.h>
35 #include <dali/internal/update/rendering/scene-graph-renderer.h>
36 #include <dali/public-api/actors/actor-enumerations.h>
37 #include <dali/public-api/actors/draw-mode.h>
38 #include <dali/public-api/math/math-utils.h>
39 #include <dali/public-api/math/quaternion.h>
40 #include <dali/public-api/math/vector3.h>
41
42 namespace Dali
43 {
44 namespace Internal
45 {
46 // Value types used by messages.
47 template<>
48 struct ParameterType<ColorMode> : public BasicType<ColorMode>
49 {
50 };
51 template<>
52 struct ParameterType<ClippingMode::Type> : public BasicType<ClippingMode::Type>
53 {
54 };
55
56 namespace SceneGraph
57 {
58 class Layer;
59 class RenderTask;
60 class UpdateManager;
61 class ResetterManager;
62 class Node;
63
64 // Flags which require the scene renderable lists to be updated
65 static NodePropertyFlags RenderableUpdateFlags = NodePropertyFlags::TRANSFORM | NodePropertyFlags::CHILD_DELETED;
66
67 /**
68  * Node is the base class for all nodes in the Scene Graph.
69  *
70  * Each node provides a transformation which applies to the node and
71  * its children.  Node data is double-buffered. This allows an update
72  * thread to modify node data, without interferring with another
73  * thread reading the values from the previous update traversal.
74  */
75 class Node : public PropertyOwner, public NodeDataProvider
76 {
77 public:
78   using RenderTaskContainer = std::vector<RenderTask*>;
79
80   // Defaults
81   static const ColorMode DEFAULT_COLOR_MODE;
82
83   // Creation methods
84
85   /**
86    * Construct a new Node.
87    */
88   static Node* New();
89
90   /**
91    * Deletes a Node.
92    */
93   static void Delete(Node* node);
94
95   /**
96    * Called during UpdateManager::DestroyNode shortly before Node is destroyed.
97    */
98   void OnDestroy();
99
100   /**
101    * @return the unique ID of the node
102    */
103   uint32_t GetId() const;
104
105   // Layer interface
106
107   /**
108    * Query whether the node is a layer.
109    * @return True if the node is a layer.
110    */
111   bool IsLayer() const
112   {
113     return mIsLayer;
114   }
115
116   /**
117    * Convert a node to a layer.
118    * @return A pointer to the layer, or NULL.
119    */
120   virtual Layer* GetLayer()
121   {
122     return nullptr;
123   }
124
125   // Camera interface
126
127   /**
128    * Query whether the node is a camera.
129    * @return True if the node is a camera.
130    */
131   bool IsCamera() const
132   {
133     return mIsCamera;
134   }
135
136   /**
137    * Mark an node and its sub tree according to the updated flag.
138    * @param[in] updated The updated flag
139    * (used for partial rendering to mark an animating sub tree for example).
140    */
141   void SetUpdatedTree(bool updated)
142   {
143     mUpdated = updated;
144
145     for(Node* child : mChildren)
146     {
147       child->SetUpdatedTree(updated);
148     }
149   }
150
151   /**
152    * This method sets clipping information on the node based on its hierarchy in the scene-graph.
153    * A value is calculated that can be used during sorting to increase sort speed.
154    * @param[in] clippingId The Clipping ID of the node to set
155    * @param[in] clippingDepth The Clipping Depth of the node to set
156    * @param[in] scissorDepth The Scissor Clipping Depth of the node to set
157    */
158   void SetClippingInformation(const uint32_t clippingId, const uint32_t clippingDepth, const uint32_t scissorDepth)
159   {
160     // We only set up the sort value if we have a stencil clipping depth, IE. At least 1 clipping node has been hit.
161     // If not, if we traverse down a clipping tree and back up, and there is another
162     // node on the parent, this will have a non-zero clipping ID that must be ignored
163     if(clippingDepth > 0u)
164     {
165       mClippingDepth = clippingDepth;
166
167       // Calculate the sort value here on write, as when read (during sort) it may be accessed several times.
168       // The items must be sorted by Clipping ID first (so the ID is kept in the most-significant bits).
169       // For the same ID, the clipping nodes must be first, so we negate the
170       // clipping enabled flag and set it as the least significant bit.
171       mClippingSortModifier = (clippingId << 1u) | (mClippingMode == ClippingMode::DISABLED ? 1u : 0u);
172     }
173     else
174     {
175       // If we do not have a clipping depth, then set this to 0 so we do not have a Clipping ID either.
176       mClippingSortModifier = 0u;
177     }
178
179     // The scissor depth does not modify the clipping sort modifier (as scissor clips are 2D only).
180     // For this reason we can always update the member variable.
181     mScissorDepth = scissorDepth;
182   }
183
184   /**
185    * Gets the Clipping ID for this node.
186    * @return The Clipping ID for this node.
187    */
188   uint32_t GetClippingId() const
189   {
190     return mClippingSortModifier >> 1u;
191   }
192
193   /**
194    * Gets the Clipping Depth for this node.
195    * @return The Clipping Depth for this node.
196    */
197   uint32_t GetClippingDepth() const
198   {
199     return mClippingDepth;
200   }
201
202   /**
203    * Gets the Scissor Clipping Depth for this node.
204    * @return The Scissor Clipping Depth for this node.
205    */
206   uint32_t GetScissorDepth() const
207   {
208     return mScissorDepth;
209   }
210
211   /**
212    * Sets the clipping mode for this node.
213    * @param[in] clippingMode The ClippingMode to set
214    */
215   void SetClippingMode(const ClippingMode::Type clippingMode)
216   {
217     mClippingMode = clippingMode;
218     SetDirtyFlag(NodePropertyFlags::TRANSFORM);
219   }
220
221   /**
222    * Gets the Clipping Mode for this node.
223    * @return The ClippingMode of this node
224    */
225   ClippingMode::Type GetClippingMode() const
226   {
227     return mClippingMode;
228   }
229
230   /**
231    * Add a renderer to the node
232    * @param[in] renderer The renderer to add to the node
233    */
234   void AddRenderer(const RendererKey& renderer);
235
236   /**
237    * Remove a renderer from the node
238    * @param[in] renderer The renderer to be removed
239    */
240   void RemoveRenderer(const RendererKey& renderer);
241
242   /*
243    * Get the renderer at the given index
244    * @param[in] index The index of the renderer in the node's renderer container
245    */
246   RendererKey GetRendererAt(uint32_t index) const
247   {
248     return mRenderers[index];
249   }
250
251   /**
252    * Retrieve the number of renderers for the node
253    */
254   uint32_t GetRendererCount() const
255   {
256     return static_cast<uint32_t>(mRenderers.Size());
257   }
258
259   // Containment methods
260
261   /**
262    * Query whether a node is the root node. Root nodes cannot have a parent node.
263    * A node becomes a root node, when it is installed by UpdateManager.
264    * @return True if the node is a root node.
265    */
266   bool IsRoot() const
267   {
268     return mIsRoot;
269   }
270
271   /**
272    * Set whether a node is the root node. Root nodes cannot have a parent node.
273    * This method should only be called by UpdateManager.
274    * @pre When isRoot is true, the node must not have a parent.
275    * @param[in] isRoot Whether the node is now a root node.
276    */
277   void SetRoot(bool isRoot);
278
279   /**
280    * Retrieve the parent of a Node.
281    * @return The parent node, or NULL if the Node has not been added to the scene-graph.
282    */
283   Node* GetParent()
284   {
285     return mParent;
286   }
287
288   /**
289    * Retrieve the parent of a Node.
290    * @return The parent node, or NULL if the Node has not been added to the scene-graph.
291    */
292   const Node* GetParent() const
293   {
294     return mParent;
295   }
296
297   /**
298    * @return true if the node is connected to SceneGraph
299    */
300   bool ConnectedToScene()
301   {
302     return IsRoot() || GetParent();
303   }
304
305   /**
306    * Connect a node to the scene-graph.
307    * @pre A node cannot be added to itself.
308    * @pre The parent node is connected to the scene-graph.
309    * @pre The childNode does not already have a parent.
310    * @pre The childNode is not a root node.
311    * @param[in] childNode The child to add.
312    */
313   void ConnectChild(Node* childNode);
314
315   /**
316    * Disconnect a child (& its children) from the scene-graph.
317    * @pre childNode is a child of this Node.
318    * @param[in] updateBufferIndex The current update buffer index.
319    * @param[in] childNode The node to disconnect.
320    */
321   void DisconnectChild(BufferIndex updateBufferIndex, Node& childNode);
322
323   /**
324    * Retrieve the children a Node.
325    * @return The container of children.
326    */
327   const NodeContainer& GetChildren() const
328   {
329     return mChildren;
330   }
331
332   /**
333    * Retrieve the children a Node.
334    * @return The container of children.
335    */
336   NodeContainer& GetChildren()
337   {
338     return mChildren;
339   }
340
341   // Update methods
342
343   /**
344    * Flag that one of the node values has changed in the current frame.
345    * @param[in] flag The flag to set.
346    */
347   void SetDirtyFlag(NodePropertyFlags flag)
348   {
349     mDirtyFlags |= flag;
350   }
351
352   /**
353    * Flag that all of the node values are dirty.
354    */
355   void SetAllDirtyFlags()
356   {
357     mDirtyFlags = NodePropertyFlags::ALL;
358   }
359
360   /**
361    * Query whether a node is dirty.
362    * @return The dirty flags
363    */
364   NodePropertyFlags GetDirtyFlags() const;
365
366   /**
367    * Query inherited dirty flags.
368    *
369    * @param The parentFlags to or with
370    * @return The inherited dirty flags
371    */
372   NodePropertyFlags GetInheritedDirtyFlags(NodePropertyFlags parentFlags) const;
373
374   /**
375    * Retrieve the parent-origin of the node.
376    * @return The parent-origin.
377    */
378   const Vector3& GetParentOrigin() const
379   {
380     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
381     {
382       return mParentOrigin.Get(0);
383     }
384
385     return Vector3::ZERO;
386   }
387
388   /**
389    * Sets both the local & base parent-origins of the node.
390    * @param[in] origin The new local & base parent-origins.
391    */
392   void SetParentOrigin(const Vector3& origin)
393   {
394     mParentOrigin.Set(0, origin);
395   }
396
397   /**
398    * Retrieve the anchor-point of the node.
399    * @return The anchor-point.
400    */
401   const Vector3& GetAnchorPoint() const
402   {
403     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
404     {
405       return mAnchorPoint.Get(0);
406     }
407
408     return Vector3::ZERO;
409   }
410
411   /**
412    * Sets both the local & base anchor-points of the node.
413    * @param[in] anchor The new local & base anchor-points.
414    */
415   void SetAnchorPoint(const Vector3& anchor)
416   {
417     mAnchorPoint.Set(0, anchor);
418   }
419
420   /**
421    * Retrieve the local position of the node, relative to its parent.
422    * @param[in] bufferIndex The buffer to read from.
423    * @return The local position.
424    */
425   const Vector3& GetPosition(BufferIndex bufferIndex) const
426   {
427     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
428     {
429       return mPosition.Get(bufferIndex);
430     }
431
432     return Vector3::ZERO;
433   }
434
435   /**
436    * Retrieve the position of the node derived from the position of all its parents.
437    * @return The world position.
438    */
439   const Vector3& GetWorldPosition(BufferIndex bufferIndex) const
440   {
441     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
442     {
443       return mWorldPosition.Get(bufferIndex);
444     }
445     return Vector3::ZERO;
446   }
447
448   /**
449    * Set whether the Node inherits position.
450    * @param[in] inherit True if the parent position is inherited.
451    */
452   void SetInheritPosition(bool inherit)
453   {
454     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
455     {
456       mTransformManagerData.Manager()->SetInheritPosition(mTransformManagerData.Id(), inherit);
457     }
458   }
459
460   /**
461    * Retrieve the local orientation of the node, relative to its parent.
462    * @param[in] bufferIndex The buffer to read from.
463    * @return The local orientation.
464    */
465   const Quaternion& GetOrientation(BufferIndex bufferIndex) const
466   {
467     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
468     {
469       return mOrientation.Get(0);
470     }
471
472     return Quaternion::IDENTITY;
473   }
474
475   /**
476    * Retrieve the orientation of the node derived from the rotation of all its parents.
477    * @param[in] bufferIndex The buffer to read from.
478    * @return The world rotation.
479    */
480   const Quaternion& GetWorldOrientation(BufferIndex bufferIndex) const
481   {
482     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
483     {
484       return mWorldOrientation.Get(0);
485     }
486     return Quaternion::IDENTITY;
487   }
488
489   /**
490    * Set whether the Node inherits orientation.
491    * @param[in] inherit True if the parent orientation is inherited.
492    */
493   void SetInheritOrientation(bool inherit)
494   {
495     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
496     {
497       mTransformManagerData.Manager()->SetInheritOrientation(mTransformManagerData.Id(), inherit);
498     }
499   }
500
501   /**
502    * Retrieve the local scale of the node, relative to its parent.
503    * @param[in] bufferIndex The buffer to read from.
504    * @return The local scale.
505    */
506   const Vector3& GetScale(BufferIndex bufferIndex) const
507   {
508     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
509     {
510       return mScale.Get(0);
511     }
512
513     return Vector3::ONE;
514   }
515
516   /**
517    * Retrieve the scale of the node derived from the scale of all its parents.
518    * @param[in] bufferIndex The buffer to read from.
519    * @return The world scale.
520    */
521   const Vector3& GetWorldScale(BufferIndex bufferIndex) const
522   {
523     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
524     {
525       return mWorldScale.Get(0);
526     }
527     return Vector3::ONE;
528   }
529
530   /**
531    * Set whether the Node inherits scale.
532    * @param inherit True if the Node inherits scale.
533    */
534   void SetInheritScale(bool inherit)
535   {
536     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
537     {
538       mTransformManagerData.Manager()->SetInheritScale(mTransformManagerData.Id(), inherit);
539     }
540   }
541
542   /**
543    * Retrieve the visibility of the node.
544    * @param[in] bufferIndex The buffer to read from.
545    * @return True if the node is visible.
546    */
547   bool IsVisible(BufferIndex bufferIndex) const
548   {
549     return mVisible[bufferIndex];
550   }
551
552   /**
553    * Retrieve the opacity of the node.
554    * @param[in] bufferIndex The buffer to read from.
555    * @return The opacity.
556    */
557   float GetOpacity(BufferIndex bufferIndex) const
558   {
559     return mColor[bufferIndex].a;
560   }
561
562   /**
563    * Retrieve the color of the node.
564    * @param[in] bufferIndex The buffer to read from.
565    * @return The color.
566    */
567   const Vector4& GetColor(BufferIndex bufferIndex) const
568   {
569     return mColor[bufferIndex];
570   }
571
572   /**
573    * Sets the color of the node derived from the color of all its parents.
574    * @param[in] color The world color.
575    * @param[in] updateBufferIndex The current update buffer index.
576    */
577   void SetWorldColor(const Vector4& color, BufferIndex updateBufferIndex)
578   {
579     mWorldColor.Set(updateBufferIndex, color);
580   }
581
582   /**
583    * Sets the color of the node derived from the color of all its parents.
584    * This method should only be called when the parents world color is up-to-date.
585    * @pre The node has a parent.
586    * @param[in] updateBufferIndex The current update buffer index.
587    */
588   void InheritWorldColor(BufferIndex updateBufferIndex)
589   {
590     DALI_ASSERT_DEBUG(mParent != NULL);
591
592     // default first
593     if(mColorMode == USE_OWN_MULTIPLY_PARENT_ALPHA)
594     {
595       const Vector4& ownColor = mColor[updateBufferIndex];
596       mWorldColor.Set(updateBufferIndex, ownColor.r, ownColor.g, ownColor.b, ownColor.a * mParent->GetWorldColor(updateBufferIndex).a);
597     }
598     else if(mColorMode == USE_OWN_MULTIPLY_PARENT_COLOR)
599     {
600       mWorldColor.Set(updateBufferIndex, mParent->GetWorldColor(updateBufferIndex) * mColor[updateBufferIndex]);
601     }
602     else if(mColorMode == USE_PARENT_COLOR)
603     {
604       mWorldColor.Set(updateBufferIndex, mParent->GetWorldColor(updateBufferIndex));
605     }
606     else // USE_OWN_COLOR
607     {
608       mWorldColor.Set(updateBufferIndex, mColor[updateBufferIndex]);
609     }
610   }
611
612   /**
613    * Copies the previous inherited scale, if this changed in the previous frame.
614    * This method should be called instead of InheritWorldScale i.e. if the inherited scale
615    * does not need to be recalculated in the current frame.
616    * @param[in] updateBufferIndex The current update buffer index.
617    */
618   void CopyPreviousWorldColor(BufferIndex updateBufferIndex)
619   {
620     mWorldColor.CopyPrevious(updateBufferIndex);
621   }
622
623   /**
624    * Retrieve the color of the node, possibly derived from the color
625    * of all its parents, depending on the value of mColorMode.
626    * @param[in] bufferIndex The buffer to read from.
627    * @return The world color.
628    */
629   const Vector4& GetWorldColor(BufferIndex bufferIndex) const
630   {
631     return mWorldColor[bufferIndex];
632   }
633
634   /**
635    * Set the color mode. This specifies whether the Node uses its own color,
636    * or inherits its parent color.
637    * @param[in] colorMode The new color mode.
638    */
639   void SetColorMode(ColorMode colorMode)
640   {
641     mColorMode = colorMode;
642
643     SetDirtyFlag(NodePropertyFlags::COLOR);
644   }
645
646   /**
647    * Retrieve the color mode.
648    * @return The color mode.
649    */
650   ColorMode GetColorMode() const
651   {
652     return mColorMode;
653   }
654
655   /**
656    * Retrieve the size of the node.
657    * @param[in] bufferIndex The buffer to read from.
658    * @return The size.
659    */
660   const Vector3& GetSize(BufferIndex bufferIndex) const
661   {
662     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
663     {
664       return mSize.Get(0);
665     }
666
667     return Vector3::ZERO;
668   }
669
670   /**
671    * Set the update area hint of the node.
672    * @param[in] updateAreaHint The update area hint.
673    */
674   void SetUpdateAreaHint(const Vector4& updateAreaHint)
675   {
676     if(mUpdateAreaChanged)
677     {
678       // Merge area if the update area is dirty
679       float x         = std::min(updateAreaHint.x - updateAreaHint.z / 2.0f, mUpdateAreaHint.x - mUpdateAreaHint.z / 2.0f);
680       float y         = std::min(updateAreaHint.y - updateAreaHint.w / 2.0f, mUpdateAreaHint.y - mUpdateAreaHint.w / 2.0f);
681       float width     = std::max(updateAreaHint.x + updateAreaHint.z / 2.0f, mUpdateAreaHint.x + mUpdateAreaHint.z / 2.0f) - x;
682       float height    = std::max(updateAreaHint.y + updateAreaHint.w / 2.0f, mUpdateAreaHint.y + mUpdateAreaHint.w / 2.0f) - y;
683       mUpdateAreaHint = Vector4(x + width / 2, y + height / 2, width, height);
684     }
685     else
686     {
687       mUpdateAreaHint    = updateAreaHint;
688       mUpdateAreaChanged = true;
689     }
690     mDirtyFlags |= NodePropertyFlags::TRANSFORM;
691   }
692
693   /**
694    * Retrieve the update area hint of the node.
695    * @return The update area hint.
696    */
697   const Vector4& GetUpdateAreaHint() const
698   {
699     return mUpdateAreaHint;
700   }
701
702   void UseTextureUpdateArea(bool useTextureUpdateArea)
703   {
704     mUseTextureUpdateArea = useTextureUpdateArea;
705   }
706
707   bool IsTextureUpdateAreaUsed() const
708   {
709     return mUseTextureUpdateArea;
710   }
711
712   /**
713    * Retrieve the bounding sphere of the node
714    * @return A vector4 describing the bounding sphere. XYZ is the center and W is the radius
715    */
716   const Vector4& GetBoundingSphere() const
717   {
718     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
719     {
720       return mTransformManagerData.Manager()->GetBoundingSphere(mTransformManagerData.Id());
721     }
722
723     return Vector4::ZERO;
724   }
725
726   /**
727    * Retrieve world matrix and size of the node
728    * @param[out] The local to world matrix of the node
729    * @param[out] size The current size of the node
730    */
731   void GetWorldMatrixAndSize(Matrix& worldMatrix, Vector3& size) const
732   {
733     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
734     {
735       mTransformManagerData.Manager()->GetWorldMatrixAndSize(mTransformManagerData.Id(), worldMatrix, size);
736     }
737   }
738
739   /**
740    * Checks if local matrix has changed since last update
741    * @return true if local matrix has changed, false otherwise
742    */
743   bool IsLocalMatrixDirty() const
744   {
745     return (mTransformManagerData.Id() != INVALID_TRANSFORM_ID) &&
746            (mTransformManagerData.Manager()->IsLocalMatrixDirty(mTransformManagerData.Id()));
747   }
748
749   /**
750    * Retrieve the cached world-matrix of a node.
751    * @param[in] bufferIndex The buffer to read from.
752    * @return The world-matrix.
753    */
754   const Matrix& GetWorldMatrix(BufferIndex bufferIndex) const
755   {
756     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
757     {
758       return mWorldMatrix.Get(bufferIndex);
759     }
760
761     return Matrix::IDENTITY;
762   }
763
764   /**
765    * Add RenderTask that will exclusively render this node.
766    * @param[in] renderTask The render-task to render this node exclusively.
767    */
768   void AddExclusiveRenderTask(RenderTask* renderTask)
769   {
770     auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
771     if(found == mExclusiveRenderTasks.end())
772     {
773       mExclusiveRenderTasks.push_back(renderTask);
774     }
775   }
776
777   /**
778    * Remove a RenderTask from exclusive render task queue.
779    * The RenderTask cannot render this node if this node is exclusive to other RenderTasks.
780    * @param[in] renderTask The render-task to be removed from exclusive render task queue.
781    */
782   void RemoveExclusiveRenderTask(RenderTask* renderTask)
783   {
784     auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
785     if(found != mExclusiveRenderTasks.end())
786     {
787       mExclusiveRenderTasks.erase(found);
788     }
789   }
790
791   /**
792    * Retrieves the number of exclusive RenderTask for this node.
793    * @return The number of exclusive RenderTask.
794    */
795   uint32_t GetExclusiveRenderTaskCount()
796   {
797     return mExclusiveRenderTasks.size();
798   }
799
800   /**
801    * Query whether the node is exclusive to the renderTask.
802    * @return true if this node is exclusive to the renderTask.
803    */
804   bool IsExclusiveRenderTask(const RenderTask* renderTask) const
805   {
806     auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
807     if(found != mExclusiveRenderTasks.end())
808     {
809       return true;
810     }
811     return false;
812   }
813
814   /**
815    * Set how the Node and its children should be drawn; see Dali::Actor::SetDrawMode() for more details.
816    * @param[in] drawMode The new draw-mode to use.
817    */
818   void SetDrawMode(const DrawMode::Type& drawMode)
819   {
820     mDrawMode = drawMode;
821   }
822
823   /**
824    * Returns whether node is an overlay or not.
825    * @return True if node is an overlay, false otherwise.
826    */
827   DrawMode::Type GetDrawMode() const
828   {
829     return mDrawMode;
830   }
831
832   void SetTransparent(bool transparent)
833   {
834     mTransparent = transparent;
835   }
836
837   bool IsTransparent() const
838   {
839     return mTransparent;
840   }
841
842   /*
843    * Returns the transform id of the node
844    * @return The transform component id of the node
845    */
846   TransformId GetTransformId() const
847   {
848     return mTransformManagerData.Id();
849   }
850
851   /**
852    * Equality operator, checks for identity, not values.
853    * @param[in]
854    */
855   bool operator==(const Node* rhs) const
856   {
857     return (this == rhs);
858   }
859
860   /**
861    * @brief Sets the sibling order of the node
862    * @param[in] order The new order
863    */
864   void SetDepthIndex(uint32_t depthIndex)
865   {
866     if(depthIndex != mDepthIndex)
867     {
868       if(mParent)
869       {
870         // Send CHILDREN_REORDER dirty flag only if my depth index changed.
871         mParent->SetDirtyFlag(NodePropertyFlags::CHILDREN_REORDER);
872       }
873       SetUpdated(true);
874       mDepthIndex = depthIndex;
875     }
876   }
877
878   /**
879    * @brief Get the depth index of the node
880    * @return Current depth index
881    */
882   uint32_t GetDepthIndex() const
883   {
884     return mDepthIndex;
885   }
886
887   /**
888    * @brief Get whether children sibiling order need to be changed. s.t. child's depth index changed.
889    * @note It will be reset when mDirtyFlag reseted.
890    * @return True if children sibiling order need to be changed.
891    */
892   bool IsChildrenReorderRequired() const
893   {
894     return mDirtyFlags & NodePropertyFlags::CHILDREN_REORDER;
895   }
896
897   /**
898    * @brief Get whether descendent hierarchy was changed.
899    * @pre The flag will be propagate at UpdateManager::SetDepthIndices().
900    * @note It will be reset when mDirtyFlag reseted.
901    * @return True if children sibiling order need to be changed.
902    */
903   bool IsDescendentHierarchyChanged() const
904   {
905     return mDirtyFlags & NodePropertyFlags::DESCENDENT_HIERARCHY_CHANGED;
906   }
907
908   /**
909    * @brief Propagate the heirarchy changeness flag to it's parent node.
910    */
911   void PropagateDescendentFlags()
912   {
913     if(IsDescendentHierarchyChanged() && mParent)
914     {
915       mParent->SetDirtyFlag(NodePropertyFlags::DESCENDENT_HIERARCHY_CHANGED);
916     }
917   }
918
919   /**
920    * @brief Sets the boolean which states whether the position should use the anchor-point.
921    * @param[in] positionUsesAnchorPoint True if the position should use the anchor-point
922    */
923   void SetPositionUsesAnchorPoint(bool positionUsesAnchorPoint)
924   {
925     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID && mPositionUsesAnchorPoint != positionUsesAnchorPoint)
926     {
927       mPositionUsesAnchorPoint = positionUsesAnchorPoint;
928       mTransformManagerData.Manager()->SetPositionUsesAnchorPoint(mTransformManagerData.Id(), mPositionUsesAnchorPoint);
929     }
930   }
931
932   /**
933    * @brief Sets whether the node is culled or not.
934    * @param[in] bufferIndex The buffer to read from.
935    * @param[in] culled True if the node is culled.
936    */
937   void SetCulled(BufferIndex bufferIndex, bool culled)
938   {
939     mCulled[bufferIndex] = culled;
940   }
941
942   /**
943    * @brief Retrieves whether the node is culled or not.
944    * @param[in] bufferIndex The buffer to read from.
945    * @return True if the node is culled.
946    */
947   bool IsCulled(BufferIndex bufferIndex) const
948   {
949     return mCulled[bufferIndex];
950   }
951
952   /**
953    * @brief Get the total capacity of the memory pools
954    * @return The capacity of the memory pools
955    *
956    * @note This is different to the node count.
957    */
958   static uint32_t GetMemoryPoolCapacity();
959
960   /**
961    * @brief Returns partial rendering data associated with the node.
962    * @return The partial rendering data
963    */
964   PartialRenderingData& GetPartialRenderingData()
965   {
966     return mPartialRenderingData;
967   }
968
969 public:
970   /**
971    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::IsAnimationPossible
972    */
973   bool IsAnimationPossible() const override;
974
975   /**
976    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::AddInitializeResetter
977    */
978   void AddInitializeResetter(ResetterManager& manager) const override;
979
980   /**
981    * Called by UpdateManager when the node is added.
982    * Creates a new transform component in the transform manager and initialize all the properties
983    * related to the transformation
984    * @param[in] transformManager A pointer to the trnasform manager (Owned by UpdateManager)
985    */
986   void CreateTransform(SceneGraph::TransformManager* transformManager);
987
988   /**
989    * Reset dirty flags
990    */
991   void ResetDirtyFlags(BufferIndex updateBufferIndex);
992
993 protected:
994   /**
995    * Set the parent of a Node.
996    * @param[in] parentNode the new parent.
997    */
998   void SetParent(Node& parentNode);
999
1000 protected:
1001   /**
1002    * Protected constructor; See also Node::New()
1003    */
1004   Node();
1005
1006   /**
1007    * Protected virtual destructor; See also Node::Delete( Node* )
1008    * Kept protected to allow destructor chaining from layer
1009    */
1010   ~Node() override;
1011
1012 private: // from NodeDataProvider
1013   /**
1014    * @copydoc NodeDataProvider::GetRenderColor
1015    */
1016   const Vector4& GetRenderColor(BufferIndex bufferIndex) const override
1017   {
1018     return GetWorldColor(bufferIndex);
1019   }
1020
1021   /**
1022    * @copydoc NodeDataProvider::GetNodeUniformMap
1023    */
1024   const UniformMap& GetNodeUniformMap() const override
1025   {
1026     return GetUniformMap();
1027   }
1028
1029 private:
1030   // Delete copy and move
1031   Node(const Node&) = delete;
1032   Node(Node&&)      = delete;
1033   Node& operator=(const Node& rhs) = delete;
1034   Node& operator=(Node&& rhs) = delete;
1035
1036   /**
1037    * Recursive helper to disconnect a Node and its children.
1038    * Disconnected Nodes have no parent or children.
1039    * @param[in] updateBufferIndex The current update buffer index.
1040    */
1041   void RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex);
1042
1043 public: // Default properties
1044   // Define a base offset for the following wrappers. The wrapper macros calculate offsets from the previous
1045   // element such that each wrapper type generates a compile time offset to the transform manager data.
1046   BASE(TransformManagerData, mTransformManagerData);
1047   PROPERTY_WRAPPER(mTransformManagerData, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_PARENT_ORIGIN,
1048                    mParentOrigin); // Local transform; the position is relative to this. Sets the Transform flag dirty when changed
1049
1050   PROPERTY_WRAPPER(mParentOrigin, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_ANCHOR_POINT,
1051                    mAnchorPoint); // Local transform; local center of rotation. Sets the Transform flag dirty when changed
1052
1053   PROPERTY_WRAPPER(mAnchorPoint, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SIZE,
1054                    mSize); // Size is provided for layouting
1055
1056   PROPERTY_WRAPPER(mSize, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_POSITION,
1057                    mPosition); // Local transform; distance between parent-origin & anchor-point
1058   PROPERTY_WRAPPER(mPosition, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SCALE,
1059                    mScale); // Local transform; scale relative to parent node
1060
1061   TEMPLATE_WRAPPER(mScale, TransformManagerPropertyQuaternion,
1062                    mOrientation); // Local transform; rotation relative to parent node
1063
1064   // Inherited properties; read-only from public API
1065   TEMPLATE_WRAPPER(mOrientation, TransformManagerVector3Input, mWorldPosition);      // Full inherited position
1066   TEMPLATE_WRAPPER(mWorldPosition, TransformManagerVector3Input, mWorldScale);       // Full inherited scale
1067   TEMPLATE_WRAPPER(mWorldScale, TransformManagerQuaternionInput, mWorldOrientation); // Full inherited orientation
1068   TEMPLATE_WRAPPER(mWorldOrientation, TransformManagerMatrixInput, mWorldMatrix);    // Full inherited world matrix
1069
1070   AnimatableProperty<bool>    mVisible;        ///< Visibility can be inherited from the Node hierachy
1071   AnimatableProperty<bool>    mCulled;         ///< True if the node is culled. This is not animatable. It is just double-buffered.
1072   AnimatableProperty<Vector4> mColor;          ///< Color can be inherited from the Node hierarchy
1073   InheritedColor              mWorldColor;     ///< Full inherited color
1074   Vector4                     mUpdateAreaHint; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
1075
1076   uint32_t       mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
1077   const uint32_t mId;                   ///< The Unique ID of the node.
1078
1079 protected:
1080   static uint32_t mNodeCounter; ///< count of total nodes, used for unique ids
1081
1082   PartialRenderingData mPartialRenderingData; ///< Cache to determine if this should be rendered again
1083
1084   Node*               mParent;               ///< Pointer to parent node (a child is owned by its parent)
1085   RenderTaskContainer mExclusiveRenderTasks; ///< Nodes can be marked as exclusive to multiple RenderTasks
1086
1087   RendererContainer mRenderers; ///< Container of renderers; not owned
1088
1089   NodeContainer mChildren; ///< Container of children; not owned
1090
1091   uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
1092   uint32_t mScissorDepth;  ///< The number of scissor clipping nodes deep this node is
1093   uint32_t mDepthIndex;    ///< Depth index of the node
1094
1095   // flags, compressed to bitfield
1096   NodePropertyFlags  mDirtyFlags;                  ///< Dirty flags for each of the Node properties
1097   DrawMode::Type     mDrawMode : 3;                ///< How the Node and its children should be drawn
1098   ColorMode          mColorMode : 3;               ///< Determines whether mWorldColor is inherited, 2 bits is enough
1099   ClippingMode::Type mClippingMode : 3;            ///< The clipping mode of this node
1100   bool               mIsRoot : 1;                  ///< True if the node cannot have a parent
1101   bool               mIsLayer : 1;                 ///< True if the node is a layer
1102   bool               mIsCamera : 1;                ///< True if the node is a camera
1103   bool               mPositionUsesAnchorPoint : 1; ///< True if the node should use the anchor-point when calculating the position
1104   bool               mTransparent : 1;             ///< True if this node is transparent. This value do not affect children.
1105   bool               mUpdateAreaChanged : 1;       ///< True if the update area of the node is changed.
1106   bool               mUseTextureUpdateArea : 1;    ///< Whether the actor uses the update area of the texture instead of its own.
1107
1108   // Changes scope, should be at end of class
1109   DALI_LOG_OBJECT_STRING_DECLARATION;
1110 };
1111
1112 // Messages for Node
1113
1114 inline void SetInheritOrientationMessage(EventThreadServices& eventThreadServices, const Node& node, bool inherit)
1115 {
1116   using LocalType = MessageValue1<Node, bool>;
1117
1118   // Reserve some memory inside the message queue
1119   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1120
1121   // Construct message in the message queue memory; note that delete should not be called on the return value
1122   new(slot) LocalType(&node, &Node::SetInheritOrientation, inherit);
1123 }
1124
1125 inline void SetParentOriginMessage(EventThreadServices& eventThreadServices, const Node& node, const Vector3& origin)
1126 {
1127   using LocalType = MessageValue1<Node, Vector3>;
1128
1129   // Reserve some memory inside the message queue
1130   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1131
1132   // Construct message in the message queue memory; note that delete should not be called on the return value
1133   new(slot) LocalType(&node, &Node::SetParentOrigin, origin);
1134 }
1135
1136 inline void SetAnchorPointMessage(EventThreadServices& eventThreadServices, const Node& node, const Vector3& anchor)
1137 {
1138   using LocalType = MessageValue1<Node, Vector3>;
1139
1140   // Reserve some memory inside the message queue
1141   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1142
1143   // Construct message in the message queue memory; note that delete should not be called on the return value
1144   new(slot) LocalType(&node, &Node::SetAnchorPoint, anchor);
1145 }
1146
1147 inline void SetInheritPositionMessage(EventThreadServices& eventThreadServices, const Node& node, bool inherit)
1148 {
1149   using LocalType = MessageValue1<Node, bool>;
1150
1151   // Reserve some memory inside the message queue
1152   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1153
1154   // Construct message in the message queue memory; note that delete should not be called on the return value
1155   new(slot) LocalType(&node, &Node::SetInheritPosition, inherit);
1156 }
1157
1158 inline void SetInheritScaleMessage(EventThreadServices& eventThreadServices, const Node& node, bool inherit)
1159 {
1160   using LocalType = MessageValue1<Node, bool>;
1161
1162   // Reserve some memory inside the message queue
1163   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1164
1165   // Construct message in the message queue memory; note that delete should not be called on the return value
1166   new(slot) LocalType(&node, &Node::SetInheritScale, inherit);
1167 }
1168
1169 inline void SetColorModeMessage(EventThreadServices& eventThreadServices, const Node& node, ColorMode colorMode)
1170 {
1171   using LocalType = MessageValue1<Node, ColorMode>;
1172
1173   // Reserve some memory inside the message queue
1174   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1175
1176   // Construct message in the message queue memory; note that delete should not be called on the return value
1177   new(slot) LocalType(&node, &Node::SetColorMode, colorMode);
1178 }
1179
1180 inline void SetDrawModeMessage(EventThreadServices& eventThreadServices, const Node& node, DrawMode::Type drawMode)
1181 {
1182   using LocalType = MessageValue1<Node, DrawMode::Type>;
1183
1184   // Reserve some memory inside the message queue
1185   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1186
1187   // Construct message in the message queue memory; note that delete should not be called on the return value
1188   new(slot) LocalType(&node, &Node::SetDrawMode, drawMode);
1189 }
1190
1191 inline void SetTransparentMessage(EventThreadServices& eventThreadServices, const Node& node, bool transparent)
1192 {
1193   using LocalType = MessageValue1<Node, bool>;
1194
1195   // Reserve some memory inside the message queue
1196   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1197
1198   // Construct message in the message queue memory; note that delete should not be called on the return value
1199   new(slot) LocalType(&node, &Node::SetTransparent, transparent);
1200 }
1201
1202 inline void DetachRendererMessage(EventThreadServices& eventThreadServices, const Node& node, const Renderer& renderer)
1203 {
1204   using LocalType = MessageValue1<Node, RendererKey>;
1205
1206   // Reserve some memory inside the message queue
1207   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1208
1209   // Construct message in the message queue memory; note that delete should not be called on the return value
1210   new(slot) LocalType(&node, &Node::RemoveRenderer, Renderer::GetKey(renderer));
1211 }
1212
1213 inline void SetDepthIndexMessage(EventThreadServices& eventThreadServices, const Node& node, uint32_t depthIndex)
1214 {
1215   using LocalType = MessageValue1<Node, uint32_t>;
1216
1217   // Reserve some memory inside the message queue
1218   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1219
1220   // Construct message in the message queue memory; note that delete should not be called on the return value
1221   new(slot) LocalType(&node, &Node::SetDepthIndex, depthIndex);
1222 }
1223
1224 inline void SetClippingModeMessage(EventThreadServices& eventThreadServices, const Node& node, ClippingMode::Type clippingMode)
1225 {
1226   using LocalType = MessageValue1<Node, ClippingMode::Type>;
1227
1228   // Reserve some memory inside the message queue
1229   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1230
1231   // Construct message in the message queue memory; note that delete should not be called on the return value
1232   new(slot) LocalType(&node, &Node::SetClippingMode, clippingMode);
1233 }
1234
1235 inline void SetPositionUsesAnchorPointMessage(EventThreadServices& eventThreadServices, const Node& node, bool positionUsesAnchorPoint)
1236 {
1237   using LocalType = MessageValue1<Node, bool>;
1238
1239   // Reserve some memory inside the message queue
1240   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1241
1242   // Construct message in the message queue memory; note that delete should not be called on the return value
1243   new(slot) LocalType(&node, &Node::SetPositionUsesAnchorPoint, positionUsesAnchorPoint);
1244 }
1245
1246 inline void SetUpdateAreaHintMessage(EventThreadServices& eventThreadServices, const Node& node, const Vector4& updateAreaHint)
1247 {
1248   using LocalType = MessageValue1<Node, Vector4>;
1249
1250   // Reserve some memory inside the message queue
1251   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1252
1253   // Construct message in the message queue memory; note that delete should not be called on the return value
1254   new(slot) LocalType(&node, &Node::SetUpdateAreaHint, updateAreaHint);
1255 }
1256
1257 inline void UseTextureUpdateAreaMessage(EventThreadServices& eventThreadServices, const Node& node, bool useTextureUpdateArea)
1258 {
1259   using LocalType = MessageValue1<Node, bool>;
1260
1261   // Reserve some memory inside the message queue
1262   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
1263
1264   // Construct message in the message queue memory; note that delete should not be called on the return value
1265   new(slot) LocalType(&node, &Node::UseTextureUpdateArea, useTextureUpdateArea);
1266 }
1267
1268 } // namespace SceneGraph
1269
1270 // Template specialisation for OwnerPointer<Node>, because delete is protected
1271 template<>
1272 inline void OwnerPointer<Dali::Internal::SceneGraph::Node>::Reset()
1273 {
1274   if(mObject != nullptr)
1275   {
1276     Dali::Internal::SceneGraph::Node::Delete(mObject);
1277     mObject = nullptr;
1278   }
1279 }
1280 } // namespace Internal
1281
1282 // Template specialisations for OwnerContainer<Node*>, because delete is protected
1283 template<>
1284 inline void OwnerContainer<Dali::Internal::SceneGraph::Node*>::Delete(Dali::Internal::SceneGraph::Node* pointer)
1285 {
1286   Dali::Internal::SceneGraph::Node::Delete(pointer);
1287 }
1288 } // namespace Dali
1289
1290 #endif // DALI_INTERNAL_SCENE_GRAPH_NODE_H