Ensure to update nodes even though they are invisible
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-algorithms.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/update-algorithms.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/actors/draw-mode.h>
26 #include <dali/public-api/math/matrix.h>
27 #include <dali/public-api/math/vector3.h>
28 #include <dali/internal/update/nodes/node.h>
29 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
30 #include <dali/internal/update/nodes/scene-graph-layer.h>
31 #include <dali/internal/render/renderers/render-renderer.h>
32
33 #include <dali/integration-api/debug.h>
34
35 namespace Dali
36 {
37
38 namespace Internal
39 {
40
41 namespace SceneGraph
42 {
43
44 #if defined(DEBUG_ENABLED)
45 Debug::Filter* gUpdateFilter = Debug::Filter::New(Debug::Concise, false, "LOG_UPDATE_ALGORITHMS");
46 #endif
47
48 /******************************************************************************
49  *********************** Apply Constraints ************************************
50  ******************************************************************************/
51
52
53 /**
54  * Constrain the local properties of the PropertyOwner.
55  * @param propertyOwner to constrain
56  * @param updateBufferIndex buffer index to use
57  */
58 void ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBufferIndex )
59 {
60   ConstraintOwnerContainer& constraints = propertyOwner.GetConstraints();
61
62   const ConstraintIter endIter = constraints.End();
63   for( ConstraintIter iter = constraints.Begin(); iter != endIter; ++iter )
64   {
65     ConstraintBase& constraint = **iter;
66     constraint.Apply( updateBufferIndex );
67   }
68 }
69
70 /******************************************************************************
71  ************************** Update node hierarchy *****************************
72  ******************************************************************************/
73
74 inline void UpdateRootNodeOpacity( Layer& rootNode, NodePropertyFlags nodeDirtyFlags, BufferIndex updateBufferIndex )
75 {
76   if ( nodeDirtyFlags & NodePropertyFlags::COLOR )
77   {
78     rootNode.SetWorldColor( rootNode.GetColor( updateBufferIndex ), updateBufferIndex );
79   }
80   else
81   {
82     // Copy previous value, in case it changed in the previous frame
83     rootNode.CopyPreviousWorldColor( updateBufferIndex );
84   }
85 }
86
87 inline void UpdateNodeOpacity( Node& node, NodePropertyFlags nodeDirtyFlags, BufferIndex updateBufferIndex )
88 {
89   // If opacity needs to be recalculated
90   if ( nodeDirtyFlags & NodePropertyFlags::COLOR )
91   {
92     node.InheritWorldColor( updateBufferIndex );
93   }
94   else
95   {
96     // Copy inherited value, if changed in the previous frame
97     node.CopyPreviousWorldColor( updateBufferIndex );
98   }
99 }
100
101 /**
102  * This is called recursively for all children of the root Node
103  */
104 inline NodePropertyFlags UpdateNodes( Node& node,
105                                       NodePropertyFlags parentFlags,
106                                       BufferIndex updateBufferIndex,
107                                       RenderQueue& renderQueue,
108                                       Layer& currentLayer,
109                                       uint32_t inheritedDrawMode )
110 {
111   // Apply constraints to the node
112   ConstrainPropertyOwner( node, updateBufferIndex );
113
114   // Some dirty flags are inherited from parent
115   NodePropertyFlags nodeDirtyFlags = node.GetInheritedDirtyFlags( parentFlags );
116
117   NodePropertyFlags cumulativeDirtyFlags = nodeDirtyFlags;
118
119   Layer* layer = &currentLayer;
120   Layer* nodeIsLayer( node.GetLayer() );
121   if( nodeIsLayer )
122   {
123     // all childs go to this layer
124     layer = nodeIsLayer;
125
126     // assume layer is clean to begin with
127     layer->SetReuseRenderers( updateBufferIndex, true );
128
129     // Layers do not inherit the DrawMode from their parents
130     inheritedDrawMode = DrawMode::NORMAL;
131   }
132   DALI_ASSERT_DEBUG( NULL != layer );
133
134   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
135
136   // Draw mode inheritance is treated as or-ing the modes together (as they are a bit-mask).
137   inheritedDrawMode |= node.GetDrawMode();
138
139   node.PrepareRender( updateBufferIndex );
140
141   // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
142   // also if node has been deleted, dont reuse old render items
143   if( nodeDirtyFlags & RenderableUpdateFlags )
144   {
145     layer->SetReuseRenderers( updateBufferIndex, false );
146   }
147
148   // recurse children
149   NodeContainer& children = node.GetChildren();
150   const NodeIter endIter = children.End();
151   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
152   {
153     Node& child = **iter;
154     cumulativeDirtyFlags |=UpdateNodes( child,
155                                         nodeDirtyFlags,
156                                         updateBufferIndex,
157                                         renderQueue,
158                                         *layer,
159                                         inheritedDrawMode );
160   }
161
162   return cumulativeDirtyFlags;
163 }
164
165 /**
166  * The root node is treated separately; it cannot inherit values since it has no parent
167  */
168 NodePropertyFlags UpdateNodeTree( Layer& rootNode,
169                                   BufferIndex updateBufferIndex,
170                                   RenderQueue& renderQueue )
171 {
172   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
173
174   // Short-circuit for invisible nodes
175   if ( DALI_UNLIKELY( !rootNode.IsVisible( updateBufferIndex ) ) ) // almost never ever true
176   {
177     return NodePropertyFlags::NOTHING;
178   }
179
180   // If the root node was not previously visible
181   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
182   if ( DALI_UNLIKELY( !rootNode.IsVisible( previousBuffer ) ) ) // almost never ever true
183   {
184     // The node was skipped in the previous update; it must recalculate everything
185     rootNode.SetAllDirtyFlags();
186   }
187
188   NodePropertyFlags nodeDirtyFlags( rootNode.GetDirtyFlags() );
189
190   NodePropertyFlags cumulativeDirtyFlags = nodeDirtyFlags;
191
192   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
193
194   DrawMode::Type drawMode( rootNode.GetDrawMode() );
195
196   // recurse children
197   NodeContainer& children = rootNode.GetChildren();
198   const NodeIter endIter = children.End();
199   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
200   {
201     Node& child = **iter;
202     cumulativeDirtyFlags |= UpdateNodes( child,
203                                          nodeDirtyFlags,
204                                          updateBufferIndex,
205                                          renderQueue,
206                                          rootNode,
207                                          drawMode );
208   }
209
210   return cumulativeDirtyFlags;
211 }
212
213 } // namespace SceneGraph
214
215 } // namespace Internal
216
217 } // namespace Dali