Removed Meshes and Model loading
[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/node-attachments/scene-graph-renderable-attachment.h>
32 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
33 #include <dali/internal/update/nodes/scene-graph-layer.h>
34 #include <dali/internal/render/renderers/scene-graph-renderer.h>
35
36 #include <dali/integration-api/debug.h>
37
38 namespace Dali
39 {
40
41 namespace Internal
42 {
43
44 namespace SceneGraph
45 {
46
47 #if defined(DEBUG_ENABLED)
48 Debug::Filter* gUpdateFilter = Debug::Filter::New(Debug::Concise, false, "LOG_UPDATE_ALGORITHMS");
49 #endif
50
51 /******************************************************************************
52  *********************** Apply Constraints ************************************
53  ******************************************************************************/
54
55
56 /**
57  * Constrain the local properties of the PropertyOwner.
58  * @param propertyOwner to constrain
59  * @param updateBufferIndex buffer index to use
60  * @return The number of constraints that are still being applied
61  */
62 unsigned int ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBufferIndex )
63 {
64   unsigned int activeCount = 0;
65
66   ConstraintOwnerContainer& constraints = propertyOwner.GetConstraints();
67
68   const ConstraintIter endIter = constraints.End();
69   for( ConstraintIter iter = constraints.Begin(); iter != endIter; ++iter )
70   {
71     ConstraintBase& constraint = **iter;
72     constraint.Apply( updateBufferIndex );
73
74     if( constraint.mWeight[updateBufferIndex] < 1.0f )
75     {
76       // this constraint is still being applied
77       ++activeCount;
78     }
79   }
80
81   return activeCount;
82 }
83
84 /**
85  * Recursively apply the constraints on the nodes
86  * @param node to constraint
87  * @param updateBufferIndex buffer index to use
88  * @return number of active constraints
89  */
90 unsigned int ConstrainNodes( Node& node, BufferIndex updateBufferIndex )
91 {
92   unsigned int activeCount = ConstrainPropertyOwner( node, updateBufferIndex );
93
94   /**
95    *  Constrain the children next
96    */
97   NodeContainer& children = node.GetChildren();
98   const NodeIter endIter = children.End();
99   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
100   {
101     Node& child = **iter;
102     activeCount += ConstrainNodes( child, updateBufferIndex );
103   }
104   return activeCount;
105 }
106
107 /******************************************************************************
108  ************************** Update node hierarchy *****************************
109  ******************************************************************************/
110
111 inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
112 {
113   if ( nodeDirtyFlags & ColorFlag )
114   {
115     rootNode.SetWorldColor( rootNode.GetColor( updateBufferIndex ), updateBufferIndex );
116   }
117   else
118   {
119     // Copy previous value, in case it changed in the previous frame
120     rootNode.CopyPreviousWorldColor( updateBufferIndex );
121   }
122 }
123
124 inline void UpdateNodeOpacity( Node& node, int nodeDirtyFlags, BufferIndex updateBufferIndex )
125 {
126   // If opacity needs to be recalculated
127   if ( nodeDirtyFlags & ColorFlag )
128   {
129     node.InheritWorldColor( updateBufferIndex );
130   }
131   else
132   {
133     // Copy inherited value, if changed in the previous frame
134     node.CopyPreviousWorldColor( updateBufferIndex );
135   }
136 }
137
138 inline void UpdateRootNodeTransformValues( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
139 {
140   // If the transform values need to be reinherited
141   if ( nodeDirtyFlags & TransformFlag )
142   {
143     rootNode.SetWorldPosition( updateBufferIndex, rootNode.GetPosition( updateBufferIndex ) );
144     rootNode.SetWorldRotation( updateBufferIndex, rootNode.GetRotation( updateBufferIndex ) );
145     rootNode.SetWorldScale   ( updateBufferIndex, rootNode.GetScale   ( updateBufferIndex ) );
146   }
147   else
148   {
149     // Copy previous value, in case they changed in the previous frame
150     rootNode.CopyPreviousWorldRotation( updateBufferIndex );
151     rootNode.CopyPreviousWorldScale( updateBufferIndex );
152     rootNode.CopyPreviousWorldPosition( updateBufferIndex );
153   }
154 }
155
156 /**
157  * Updates transform values for the given node if the transform flag is dirty.
158  * This includes applying a new size should the SizeMode require it.
159  * Note that this will cause the size dirty flag to be set. This is why we pass
160  * the dirty flags in by reference.
161  * @param[in]     node The node to update
162  * @param[in,out] nodeDirtyFlags A reference to the dirty flags, these may be modified by this function
163  * @param[in]     updateBufferIndex The current index to use for this frame
164  */
165 inline void UpdateNodeTransformValues( Node& node, int& nodeDirtyFlags, BufferIndex updateBufferIndex )
166 {
167   // If the transform values need to be reinherited
168   if( nodeDirtyFlags & TransformFlag )
169   {
170     // Handle size relative to parent modes.
171     // This must be delt with before rotation/translation as otherwise anything
172     // anchored to a corner of this child would appear at the wrong position.
173     // The size dirty flag is modified if the size is being overridden.
174     // Note: Switch is in order of use-case commonality.
175     switch( node.GetSizeMode() )
176     {
177       case USE_OWN_SIZE:
178       {
179         // Completely ignore the parents size.
180         break;
181       }
182
183       case SIZE_EQUAL_TO_PARENT:
184       {
185         // Set the nodes size to that of the parent.
186         node.SetSize( updateBufferIndex, node.GetParent()->GetSize( updateBufferIndex ) );
187         nodeDirtyFlags |= SizeFlag;
188         break;
189       }
190
191       case SIZE_RELATIVE_TO_PARENT:
192       {
193         // Set the nodes size to the parents multiplied by a user defined value.
194         node.SetSize( updateBufferIndex, node.GetSizeModeFactor() * node.GetParent()->GetSize( updateBufferIndex ) );
195         nodeDirtyFlags |= SizeFlag;
196         break;
197       }
198
199       case SIZE_FIXED_OFFSET_FROM_PARENT:
200       {
201         // Set the nodes size to the parents plus a user defined value.
202         node.SetSize( updateBufferIndex, node.GetSizeModeFactor() + node.GetParent()->GetSize( updateBufferIndex ) );
203         nodeDirtyFlags |= SizeFlag;
204         break;
205       }
206     }
207
208     // With a non-central anchor-point, the world rotation and scale affects the world position.
209     // Therefore the world rotation & scale must be updated before the world position.
210     if( node.IsRotationInherited() )
211     {
212       node.InheritWorldRotation( updateBufferIndex );
213     }
214     else
215     {
216       node.SetWorldRotation( updateBufferIndex, node.GetRotation( updateBufferIndex ) );
217     }
218
219     if( node.IsScaleInherited() )
220     {
221       node.InheritWorldScale( updateBufferIndex );
222     }
223     else
224     {
225       node.SetWorldScale( updateBufferIndex, node.GetScale( updateBufferIndex ) );
226     }
227
228     node.InheritWorldPosition( updateBufferIndex );
229   }
230   else
231   {
232     // Copy inherited values, if those changed in the previous frame
233     node.CopyPreviousWorldRotation( updateBufferIndex );
234     node.CopyPreviousWorldScale( updateBufferIndex );
235     node.CopyPreviousWorldPosition( updateBufferIndex );
236     node.CopyPreviousSize( updateBufferIndex );
237   }
238 }
239
240 inline void UpdateNodeWorldMatrix( Node &node, int nodeDirtyFlags, BufferIndex updateBufferIndex )
241 {
242   // If world-matrix needs to be recalculated
243   if ( nodeDirtyFlags & TransformFlag )
244   {
245     if( node.GetInhibitLocalTransform() )
246     {
247       node.SetWorldMatrix( updateBufferIndex,
248                            node.GetWorldScale(updateBufferIndex),
249                            node.GetWorldRotation(updateBufferIndex) / node.GetRotation(updateBufferIndex),
250                            node.GetWorldPosition(updateBufferIndex) - node.GetPosition(updateBufferIndex) );
251     }
252     else
253     {
254       node.SetWorldMatrix( updateBufferIndex,
255                            node.GetWorldScale(updateBufferIndex),
256                            node.GetWorldRotation(updateBufferIndex),
257                            node.GetWorldPosition(updateBufferIndex) );
258     }
259   }
260   else
261   {
262     node.CopyPreviousWorldMatrix( updateBufferIndex );
263   }
264 }
265
266 inline void UpdateNodeWorldMatrix( Node& node, RenderableAttachment& updatedRenderable, int nodeDirtyFlags, BufferIndex updateBufferIndex )
267 {
268   /**
269    * If world-matrix needs to be recalculated.
270    */
271   if ( ( nodeDirtyFlags & TransformFlag ) ||
272          updatedRenderable.IsScaleForSizeDirty() )
273   {
274     if( updatedRenderable.UsesGeometryScaling() )
275     {
276       Vector3 scaling;
277       updatedRenderable.GetScaleForSize( node.GetSize( updateBufferIndex ), scaling );
278       if( node.GetInhibitLocalTransform() )
279       {
280         node.SetWorldMatrix( updateBufferIndex,
281                              node.GetWorldScale(updateBufferIndex) * scaling,
282                              node.GetWorldRotation(updateBufferIndex) / node.GetRotation(updateBufferIndex),
283                              node.GetWorldPosition(updateBufferIndex) - node.GetPosition(updateBufferIndex) );
284       }
285       else
286       {
287         node.SetWorldMatrix( updateBufferIndex,
288                              node.GetWorldScale(updateBufferIndex) * scaling,
289                              node.GetWorldRotation(updateBufferIndex),
290                              node.GetWorldPosition(updateBufferIndex) );
291       }
292     }
293     else
294     {
295       // no scaling, i.e. Image
296       if( node.GetInhibitLocalTransform() )
297       {
298         node.SetWorldMatrix( updateBufferIndex,
299                              node.GetWorldScale(updateBufferIndex),
300                              node.GetWorldRotation(updateBufferIndex) / node.GetRotation(updateBufferIndex),
301                              node.GetWorldPosition(updateBufferIndex) - node.GetPosition(updateBufferIndex) );
302       }
303       else
304       {
305         node.SetWorldMatrix( updateBufferIndex,
306                              node.GetWorldScale(updateBufferIndex),
307                              node.GetWorldRotation(updateBufferIndex),
308                              node.GetWorldPosition(updateBufferIndex) );
309       }
310     }
311   }
312   else
313   {
314     node.CopyPreviousWorldMatrix( updateBufferIndex );
315   }
316 }
317
318 /**
319  * Update an attachment.
320  * @return An updated renderable attachment if one was ready.
321  */
322 inline RenderableAttachment* UpdateAttachment( NodeAttachment& attachment,
323                                                Node& node,
324                                                BufferIndex updateBufferIndex,
325                                                ResourceManager& resourceManager,
326                                                int nodeDirtyFlags )
327 {
328   // Allow attachments to do specialised processing during updates
329   attachment.Update( updateBufferIndex, node, nodeDirtyFlags );
330
331   RenderableAttachment* renderable = attachment.GetRenderable(); // not all scene objects render
332   if( renderable )
333   {
334     // Notify renderables when size has changed
335     // Size can change while node was invisible so we need to check size again if we were previously invisible
336     if( nodeDirtyFlags & (SizeFlag|VisibleFlag) )
337     {
338       renderable->SizeChanged( updateBufferIndex );
339     }
340
341     // check if node is visible
342     if( renderable->ResolveVisibility( updateBufferIndex ) )
343     {
344       renderable->PrepareResources( updateBufferIndex, resourceManager );
345     }
346   }
347   return renderable;
348 }
349
350 inline void AddRenderableToLayer( Layer& layer,
351                                   RenderableAttachment& renderable,
352                                   BufferIndex updateBufferIndex,
353                                   int inheritedDrawMode )
354 {
355   // The renderables are stored into the opaque list temporarily for PrepareRenderables()
356   // step. The list is cleared by ProcessRenderTasks().
357   layer.opaqueRenderables.push_back( &renderable );
358 }
359
360 /**
361  * This is called recursively for all children of the root Node
362  */
363 inline int UpdateNodesAndAttachments( Node& node,
364                                       int parentFlags,
365                                       BufferIndex updateBufferIndex,
366                                       ResourceManager& resourceManager,
367                                       RenderQueue& renderQueue,
368                                       Layer& currentLayer,
369                                       int inheritedDrawMode )
370 {
371   Layer* layer = &currentLayer;
372
373   // Short-circuit for invisible nodes
374   if ( !node.IsVisible( updateBufferIndex ) )
375   {
376     return 0;
377   }
378
379   // If the node was not previously visible
380   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
381   if ( !node.IsVisible( previousBuffer ) )
382   {
383     // The node was skipped in the previous update; it must recalculate everything
384     node.SetAllDirtyFlags();
385   }
386
387   // Some dirty flags are inherited from parent
388   int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
389
390   int cumulativeDirtyFlags = nodeDirtyFlags;
391
392   if ( node.IsLayer() )
393   {
394     // all childs go to this layer
395     layer = node.GetLayer();
396
397     // assume layer is clean to begin with
398     layer->SetReuseRenderers( updateBufferIndex, true );
399
400     // Layers do not inherit the DrawMode from their parents
401     inheritedDrawMode = DrawMode::NORMAL;
402   }
403   DALI_ASSERT_DEBUG( NULL != layer );
404
405   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
406
407   // Note: nodeDirtyFlags are passed in by reference and may be modified by the following function.
408   // It is important that the modified version of these flags are used by the RenderableAttachment.
409   UpdateNodeTransformValues( node, nodeDirtyFlags, updateBufferIndex );
410
411   // Setting STENCIL will override OVERLAY, if that would otherwise have been inherited.
412   inheritedDrawMode |= node.GetDrawMode();
413
414   if ( node.HasAttachment() )
415   {
416     /*
417      * Add renderables for the children into the current Layer
418      */
419     RenderableAttachment* renderable = UpdateAttachment( node.GetAttachment(),
420                                                          node,
421                                                          updateBufferIndex,
422                                                          resourceManager,
423                                                          nodeDirtyFlags );
424
425
426     if( NULL != renderable )
427     {
428       // Update the world matrix after renderable update; the ScaleForSize property should now be calculated
429       UpdateNodeWorldMatrix( node, *renderable, nodeDirtyFlags, updateBufferIndex );
430
431       // The attachment is ready to render, so it is added to a set of renderables.
432       AddRenderableToLayer( *layer, *renderable, updateBufferIndex, inheritedDrawMode );
433     }
434   }
435   else if( node.IsObserved() )
436   {
437     // This node is being used as a property input for an animation, constraint,
438     // camera or bone. Ensure it's matrix is updated
439     UpdateNodeWorldMatrix( node, nodeDirtyFlags, updateBufferIndex );
440   }
441
442   // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
443   // also if node has been deleted, dont reuse old render items
444   if( nodeDirtyFlags & RenderableUpdateFlags )
445   {
446     layer->SetReuseRenderers( updateBufferIndex, false );
447   }
448
449   // recurse children
450   NodeContainer& children = node.GetChildren();
451   const NodeIter endIter = children.End();
452   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
453   {
454     Node& child = **iter;
455     cumulativeDirtyFlags |=UpdateNodesAndAttachments( child,
456                                                       nodeDirtyFlags,
457                                                       updateBufferIndex,
458                                                       resourceManager,
459                                                       renderQueue,
460                                                       *layer,
461                                                       inheritedDrawMode );
462   }
463
464   return cumulativeDirtyFlags;
465 }
466
467 /**
468  * The root node is treated separately; it cannot inherit values since it has no parent
469  */
470 int UpdateNodesAndAttachments( Layer& rootNode,
471                                BufferIndex updateBufferIndex,
472                                ResourceManager& resourceManager,
473                                RenderQueue& renderQueue )
474 {
475   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
476
477   // Short-circuit for invisible nodes
478   if ( !rootNode.IsVisible( updateBufferIndex ) )
479   {
480     return 0;
481   }
482
483   // If the root node was not previously visible
484   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
485   if ( !rootNode.IsVisible( previousBuffer ) )
486   {
487     // The node was skipped in the previous update; it must recalculate everything
488     rootNode.SetAllDirtyFlags();
489   }
490
491   int nodeDirtyFlags( rootNode.GetDirtyFlags() );
492
493   int cumulativeDirtyFlags = nodeDirtyFlags;
494
495   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
496
497   UpdateRootNodeTransformValues( rootNode, nodeDirtyFlags, updateBufferIndex );
498
499   DrawMode::Type drawMode( rootNode.GetDrawMode() );
500
501   // recurse children
502   NodeContainer& children = rootNode.GetChildren();
503   const NodeIter endIter = children.End();
504   for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
505   {
506     Node& child = **iter;
507     cumulativeDirtyFlags |= UpdateNodesAndAttachments( child,
508                                                        nodeDirtyFlags,
509                                                        updateBufferIndex,
510                                                        resourceManager,
511                                                        renderQueue,
512                                                        rootNode,
513                                                        drawMode );
514   }
515
516   return cumulativeDirtyFlags;
517 }
518
519 } // namespace SceneGraph
520
521 } // namespace Internal
522
523 } // namespace Dali