6f1fb4d417e917f9eca560566d1e6739e2f74ede
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-algorithms.cpp
1 /*
2  * Copyright (c) 2016 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/resources/resource-manager.h>
29 #include <dali/internal/update/nodes/node.h>
30 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
31 #include <dali/internal/update/nodes/scene-graph-layer.h>
32 #include <dali/internal/render/renderers/render-renderer.h>
33
34 #include <dali/integration-api/debug.h>
35
36 namespace Dali
37 {
38
39 namespace Internal
40 {
41
42 namespace SceneGraph
43 {
44
45 #if defined(DEBUG_ENABLED)
46 Debug::Filter* gUpdateFilter = Debug::Filter::New(Debug::Concise, false, "LOG_UPDATE_ALGORITHMS");
47 #endif
48
49 /******************************************************************************
50  *********************** Apply Constraints ************************************
51  ******************************************************************************/
52
53
54 /**
55  * Constrain the local properties of the PropertyOwner.
56  * @param propertyOwner to constrain
57  * @param updateBufferIndex buffer index to use
58  * @return The number of constraints that are still being applied
59  */
60 void ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBufferIndex )
61 {
62   ConstraintOwnerContainer& constraints = propertyOwner.GetConstraints();
63
64   const ConstraintIter endIter = constraints.End();
65   for( ConstraintIter iter = constraints.Begin(); iter != endIter; ++iter )
66   {
67     ConstraintBase& constraint = **iter;
68     constraint.Apply( updateBufferIndex );
69   }
70 }
71
72 /******************************************************************************
73  ************************** Update node hierarchy *****************************
74  ******************************************************************************/
75
76 inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
77 {
78   if ( nodeDirtyFlags & ColorFlag )
79   {
80     rootNode.SetWorldColor( rootNode.GetColor( updateBufferIndex ), updateBufferIndex );
81   }
82   else
83   {
84     // Copy previous value, in case it changed in the previous frame
85     rootNode.CopyPreviousWorldColor( updateBufferIndex );
86   }
87 }
88
89 inline void UpdateNodeOpacity( Node& node, int nodeDirtyFlags, BufferIndex updateBufferIndex )
90 {
91   // If opacity needs to be recalculated
92   if ( nodeDirtyFlags & ColorFlag )
93   {
94     node.InheritWorldColor( updateBufferIndex );
95   }
96   else
97   {
98     // Copy inherited value, if changed in the previous frame
99     node.CopyPreviousWorldColor( updateBufferIndex );
100   }
101 }
102
103 /**
104  * This is called recursively for all children of the root Node
105  */
106 inline int UpdateNodes( Node& node,
107                         int parentFlags,
108                         BufferIndex updateBufferIndex,
109                         ResourceManager& resourceManager,
110                         RenderQueue& renderQueue,
111                         Layer& currentLayer,
112                         int inheritedDrawMode )
113 {
114   //Apply constraints to the node
115   ConstrainPropertyOwner( node, updateBufferIndex );
116
117   // Short-circuit for invisible nodes
118   if ( !node.IsVisible( updateBufferIndex ) )
119   {
120     return 0;
121   }
122
123   // If the node was not previously visible
124   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
125   if ( !node.IsVisible( previousBuffer ) )
126   {
127     // The node was skipped in the previous update; it must recalculate everything
128     node.SetAllDirtyFlags();
129   }
130
131   // Some dirty flags are inherited from parent
132   int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
133
134   int cumulativeDirtyFlags = nodeDirtyFlags;
135
136   Layer* layer = &currentLayer;
137   Layer* nodeIsLayer( node.GetLayer() );
138   if( nodeIsLayer )
139   {
140     // all childs go to this layer
141     layer = nodeIsLayer;
142
143     // assume layer is clean to begin with
144     layer->SetReuseRenderers( updateBufferIndex, true );
145
146     // Layers do not inherit the DrawMode from their parents
147     inheritedDrawMode = DrawMode::NORMAL;
148   }
149   DALI_ASSERT_DEBUG( NULL != layer );
150
151   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
152
153   // Setting STENCIL will override OVERLAY_2D, if that would otherwise have been inherited.
154   inheritedDrawMode |= node.GetDrawMode();
155
156   node.PrepareRender( updateBufferIndex );
157
158   // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
159   // also if node has been deleted, dont reuse old render items
160   if( nodeDirtyFlags & RenderableUpdateFlags )
161   {
162     layer->SetReuseRenderers( updateBufferIndex, false );
163   }
164
165   // recurse children
166   NodeContainer& children = node.GetChildren();
167   const NodeIter endIter = children.End();
168   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
169   {
170     Node& child = **iter;
171     cumulativeDirtyFlags |=UpdateNodes( child,
172                                         nodeDirtyFlags,
173                                         updateBufferIndex,
174                                         resourceManager,
175                                         renderQueue,
176                                         *layer,
177                                         inheritedDrawMode );
178   }
179
180   return cumulativeDirtyFlags;
181 }
182
183 /**
184  * The root node is treated separately; it cannot inherit values since it has no parent
185  */
186 int UpdateNodeTree( Layer& rootNode,
187                     BufferIndex updateBufferIndex,
188                     ResourceManager& resourceManager,
189                     RenderQueue& renderQueue )
190 {
191   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
192
193   // Short-circuit for invisible nodes
194   if ( DALI_UNLIKELY( !rootNode.IsVisible( updateBufferIndex ) ) ) // almost never ever true
195   {
196     return 0;
197   }
198
199   // If the root node was not previously visible
200   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
201   if ( DALI_UNLIKELY( !rootNode.IsVisible( previousBuffer ) ) ) // almost never ever true
202   {
203     // The node was skipped in the previous update; it must recalculate everything
204     rootNode.SetAllDirtyFlags();
205   }
206
207   int nodeDirtyFlags( rootNode.GetDirtyFlags() );
208
209   int cumulativeDirtyFlags = nodeDirtyFlags;
210
211   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
212
213   DrawMode::Type drawMode( rootNode.GetDrawMode() );
214
215   // recurse children
216   NodeContainer& children = rootNode.GetChildren();
217   const NodeIter endIter = children.End();
218   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
219   {
220     Node& child = **iter;
221     cumulativeDirtyFlags |= UpdateNodes( child,
222                                          nodeDirtyFlags,
223                                          updateBufferIndex,
224                                          resourceManager,
225                                          renderQueue,
226                                          rootNode,
227                                          drawMode );
228   }
229
230   return cumulativeDirtyFlags;
231 }
232
233 } // namespace SceneGraph
234
235 } // namespace Internal
236
237 } // namespace Dali