[4.0] Changed Update to reset only target properties each frame
[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, int nodeDirtyFlags, BufferIndex updateBufferIndex )
75 {
76   if ( nodeDirtyFlags & ColorFlag )
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, int nodeDirtyFlags, BufferIndex updateBufferIndex )
88 {
89   // If opacity needs to be recalculated
90   if ( nodeDirtyFlags & ColorFlag )
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 int UpdateNodes( Node& node,
105                         int parentFlags,
106                         BufferIndex updateBufferIndex,
107                         RenderQueue& renderQueue,
108                         Layer& currentLayer,
109                         int inheritedDrawMode )
110 {
111   // Apply constraints to the node
112   ConstrainPropertyOwner( node, updateBufferIndex );
113
114   // Short-circuit for invisible nodes
115   if ( !node.IsVisible( updateBufferIndex ) )
116   {
117     return 0;
118   }
119
120   // If the node was not previously visible
121   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
122   if ( !node.IsVisible( previousBuffer ) )
123   {
124     // The node was skipped in the previous update; it must recalculate everything
125     node.SetAllDirtyFlags();
126   }
127
128   // Some dirty flags are inherited from parent
129   int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
130
131   int cumulativeDirtyFlags = nodeDirtyFlags;
132
133   Layer* layer = &currentLayer;
134   Layer* nodeIsLayer( node.GetLayer() );
135   if( nodeIsLayer )
136   {
137     // all childs go to this layer
138     layer = nodeIsLayer;
139
140     // assume layer is clean to begin with
141     layer->SetReuseRenderers( updateBufferIndex, true );
142
143     // Layers do not inherit the DrawMode from their parents
144     inheritedDrawMode = DrawMode::NORMAL;
145   }
146   DALI_ASSERT_DEBUG( NULL != layer );
147
148   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
149
150   // Draw mode inheritance is treated as or-ing the modes together (as they are a bit-mask).
151   inheritedDrawMode |= node.GetDrawMode();
152
153   node.PrepareRender( updateBufferIndex );
154
155   // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
156   // also if node has been deleted, dont reuse old render items
157   if( nodeDirtyFlags & RenderableUpdateFlags )
158   {
159     layer->SetReuseRenderers( updateBufferIndex, false );
160   }
161
162   // recurse children
163   NodeContainer& children = node.GetChildren();
164   const NodeIter endIter = children.End();
165   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
166   {
167     Node& child = **iter;
168     cumulativeDirtyFlags |=UpdateNodes( child,
169                                         nodeDirtyFlags,
170                                         updateBufferIndex,
171                                         renderQueue,
172                                         *layer,
173                                         inheritedDrawMode );
174   }
175
176   return cumulativeDirtyFlags;
177 }
178
179 /**
180  * The root node is treated separately; it cannot inherit values since it has no parent
181  */
182 int UpdateNodeTree( Layer& rootNode,
183                     BufferIndex updateBufferIndex,
184                     RenderQueue& renderQueue )
185 {
186   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
187
188   // Short-circuit for invisible nodes
189   if ( DALI_UNLIKELY( !rootNode.IsVisible( updateBufferIndex ) ) ) // almost never ever true
190   {
191     return 0;
192   }
193
194   // If the root node was not previously visible
195   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
196   if ( DALI_UNLIKELY( !rootNode.IsVisible( previousBuffer ) ) ) // almost never ever true
197   {
198     // The node was skipped in the previous update; it must recalculate everything
199     rootNode.SetAllDirtyFlags();
200   }
201
202   int nodeDirtyFlags( rootNode.GetDirtyFlags() );
203
204   int cumulativeDirtyFlags = nodeDirtyFlags;
205
206   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
207
208   DrawMode::Type drawMode( rootNode.GetDrawMode() );
209
210   // recurse children
211   NodeContainer& children = rootNode.GetChildren();
212   const NodeIter endIter = children.End();
213   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
214   {
215     Node& child = **iter;
216     cumulativeDirtyFlags |= UpdateNodes( child,
217                                          nodeDirtyFlags,
218                                          updateBufferIndex,
219                                          renderQueue,
220                                          rootNode,
221                                          drawMode );
222   }
223
224   return cumulativeDirtyFlags;
225 }
226
227 } // namespace SceneGraph
228
229 } // namespace Internal
230
231 } // namespace Dali