Merge "Removed redundant resource loading & rendering code" into devel/master
[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/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  * @return The number of constraints that are still being applied
58  */
59 void ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBufferIndex )
60 {
61   ConstraintOwnerContainer& constraints = propertyOwner.GetConstraints();
62
63   const ConstraintIter endIter = constraints.End();
64   for( ConstraintIter iter = constraints.Begin(); iter != endIter; ++iter )
65   {
66     ConstraintBase& constraint = **iter;
67     constraint.Apply( updateBufferIndex );
68   }
69 }
70
71 /******************************************************************************
72  ************************** Update node hierarchy *****************************
73  ******************************************************************************/
74
75 inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
76 {
77   if ( nodeDirtyFlags & ColorFlag )
78   {
79     rootNode.SetWorldColor( rootNode.GetColor( updateBufferIndex ), updateBufferIndex );
80   }
81   else
82   {
83     // Copy previous value, in case it changed in the previous frame
84     rootNode.CopyPreviousWorldColor( updateBufferIndex );
85   }
86 }
87
88 inline void UpdateNodeOpacity( Node& node, int nodeDirtyFlags, BufferIndex updateBufferIndex )
89 {
90   // If opacity needs to be recalculated
91   if ( nodeDirtyFlags & ColorFlag )
92   {
93     node.InheritWorldColor( updateBufferIndex );
94   }
95   else
96   {
97     // Copy inherited value, if changed in the previous frame
98     node.CopyPreviousWorldColor( updateBufferIndex );
99   }
100 }
101
102 /**
103  * This is called recursively for all children of the root Node
104  */
105 inline int UpdateNodes( Node& node,
106                         int parentFlags,
107                         BufferIndex updateBufferIndex,
108                         RenderQueue& renderQueue,
109                         Layer& currentLayer,
110                         int inheritedDrawMode )
111 {
112   //Apply constraints to the node
113   ConstrainPropertyOwner( node, updateBufferIndex );
114
115   // Short-circuit for invisible nodes
116   if ( !node.IsVisible( updateBufferIndex ) )
117   {
118     return 0;
119   }
120
121   // If the node was not previously visible
122   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
123   if ( !node.IsVisible( previousBuffer ) )
124   {
125     // The node was skipped in the previous update; it must recalculate everything
126     node.SetAllDirtyFlags();
127   }
128
129   // Some dirty flags are inherited from parent
130   int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
131
132   int cumulativeDirtyFlags = nodeDirtyFlags;
133
134   Layer* layer = &currentLayer;
135   Layer* nodeIsLayer( node.GetLayer() );
136   if( nodeIsLayer )
137   {
138     // all childs go to this layer
139     layer = nodeIsLayer;
140
141     // assume layer is clean to begin with
142     layer->SetReuseRenderers( updateBufferIndex, true );
143
144     // Layers do not inherit the DrawMode from their parents
145     inheritedDrawMode = DrawMode::NORMAL;
146   }
147   DALI_ASSERT_DEBUG( NULL != layer );
148
149   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
150
151   // Draw mode inheritance is treated as or-ing the modes together (as they are a bit-mask).
152   inheritedDrawMode |= node.GetDrawMode();
153
154   node.PrepareRender( updateBufferIndex );
155
156   // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
157   // also if node has been deleted, dont reuse old render items
158   if( nodeDirtyFlags & RenderableUpdateFlags )
159   {
160     layer->SetReuseRenderers( updateBufferIndex, false );
161   }
162
163   // recurse children
164   NodeContainer& children = node.GetChildren();
165   const NodeIter endIter = children.End();
166   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
167   {
168     Node& child = **iter;
169     cumulativeDirtyFlags |=UpdateNodes( child,
170                                         nodeDirtyFlags,
171                                         updateBufferIndex,
172                                         renderQueue,
173                                         *layer,
174                                         inheritedDrawMode );
175   }
176
177   return cumulativeDirtyFlags;
178 }
179
180 /**
181  * The root node is treated separately; it cannot inherit values since it has no parent
182  */
183 int UpdateNodeTree( Layer& rootNode,
184                     BufferIndex updateBufferIndex,
185                     RenderQueue& renderQueue )
186 {
187   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
188
189   // Short-circuit for invisible nodes
190   if ( DALI_UNLIKELY( !rootNode.IsVisible( updateBufferIndex ) ) ) // almost never ever true
191   {
192     return 0;
193   }
194
195   // If the root node was not previously visible
196   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
197   if ( DALI_UNLIKELY( !rootNode.IsVisible( previousBuffer ) ) ) // almost never ever true
198   {
199     // The node was skipped in the previous update; it must recalculate everything
200     rootNode.SetAllDirtyFlags();
201   }
202
203   int nodeDirtyFlags( rootNode.GetDirtyFlags() );
204
205   int cumulativeDirtyFlags = nodeDirtyFlags;
206
207   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
208
209   DrawMode::Type drawMode( rootNode.GetDrawMode() );
210
211   // recurse children
212   NodeContainer& children = rootNode.GetChildren();
213   const NodeIter endIter = children.End();
214   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
215   {
216     Node& child = **iter;
217     cumulativeDirtyFlags |= UpdateNodes( child,
218                                          nodeDirtyFlags,
219                                          updateBufferIndex,
220                                          renderQueue,
221                                          rootNode,
222                                          drawMode );
223   }
224
225   return cumulativeDirtyFlags;
226 }
227
228 } // namespace SceneGraph
229
230 } // namespace Internal
231
232 } // namespace Dali