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