Remove deprecated APIs in Tizen 3.0
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.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/nodes/node.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/internal-constants.h>
23 #include <dali/internal/common/memory-pool-object-allocator.h>
24 #include <dali/internal/update/common/discard-queue.h>
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/common/constants.h>
27
28 namespace
29 {
30 //Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
31 // or DALI library is unloaded
32 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
33 #ifdef DEBUG_ENABLED
34 // keep track of nodes alive, to ensure we have 0 when the process exits or DALi library is unloaded
35 int32_t gNodeCount = 0;
36
37 // Called when the process is about to exit, Node count should be zero at this point.
38 void __attribute__ ((destructor)) ShutDown(void)
39 {
40 DALI_ASSERT_DEBUG( (gNodeCount == 0) && "Node memory leak");
41 }
42 #endif
43 } // Unnamed namespace
44
45 namespace Dali
46 {
47
48 namespace Internal
49 {
50
51 namespace SceneGraph
52 {
53
54 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
55
56 uint32_t Node::mNodeCounter = 0;        ///< A counter to provide unique node ids, up-to 4 billion
57
58 Node* Node::New()
59 {
60   return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node;
61 }
62
63 void Node::Delete( Node* node )
64 {
65   // check we have a node not a layer
66   if( !node->mIsLayer )
67   {
68     // Manually call the destructor
69     node->~Node();
70
71     // Mark the memory it used as free in the memory pool
72     gNodeMemoryPool.FreeThreadSafe( node );
73   }
74   else
75   {
76     // not in the pool, just delete it.
77     delete node;
78   }
79 }
80
81 Node::Node()
82 : mTransformManager( NULL ),
83   mTransformId( INVALID_TRANSFORM_ID ),
84   mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ),
85   mAnchorPoint( TRANSFORM_PROPERTY_ANCHOR_POINT ),
86   mSize( TRANSFORM_PROPERTY_SIZE ),                                               // Zero initialized by default
87   mPosition( TRANSFORM_PROPERTY_POSITION ),                                       // Zero initialized by default
88   mOrientation(),                                                                 // Initialized to identity by default
89   mScale( TRANSFORM_PROPERTY_SCALE ),
90   mVisible( true ),
91   mCulled( false ),
92   mColor( Color::WHITE ),
93   mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default
94   mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ),
95   mWorldOrientation(),                                                            // Initialized to identity by default
96   mWorldMatrix(),
97   mWorldColor( Color::WHITE ),
98   mClippingSortModifier( 0u ),
99   mId( ++mNodeCounter ),
100   mParent( NULL ),
101   mExclusiveRenderTask( NULL ),
102   mChildren(),
103   mClippingDepth( 0u ),
104   mScissorDepth( 0u ),
105   mDepthIndex( 0u ),
106   mDirtyFlags( NodePropertyFlags::ALL ),
107   mRegenerateUniformMap( 0 ),
108   mDrawMode( DrawMode::NORMAL ),
109   mColorMode( DEFAULT_COLOR_MODE ),
110   mClippingMode( ClippingMode::DISABLED ),
111   mIsRoot( false ),
112   mIsLayer( false ),
113   mPositionUsesAnchorPoint( true )
114 {
115   mUniformMapChanged[0] = 0u;
116   mUniformMapChanged[1] = 0u;
117
118 #ifdef DEBUG_ENABLED
119   gNodeCount++;
120 #endif
121
122 }
123
124 Node::~Node()
125 {
126   if( mTransformId != INVALID_TRANSFORM_ID )
127   {
128     mTransformManager->RemoveTransform(mTransformId);
129   }
130
131 #ifdef DEBUG_ENABLED
132   gNodeCount--;
133 #endif
134 }
135
136 void Node::OnDestroy()
137 {
138   // Animators, Constraints etc. should be disconnected from the child's properties.
139   PropertyOwner::Destroy();
140 }
141
142 uint32_t Node::GetId() const
143 {
144   return mId;
145 }
146
147 void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
148 {
149   //Create a new transform
150   mTransformManager = transformManager;
151   mTransformId = transformManager->CreateTransform();
152
153   //Initialize all the animatable properties
154   mPosition.Initialize( transformManager, mTransformId );
155   mScale.Initialize( transformManager, mTransformId );
156   mOrientation.Initialize( transformManager, mTransformId );
157   mSize.Initialize( transformManager, mTransformId );
158   mParentOrigin.Initialize( transformManager, mTransformId );
159   mAnchorPoint.Initialize( transformManager, mTransformId );
160
161   //Initialize all the input properties
162   mWorldPosition.Initialize( transformManager, mTransformId );
163   mWorldScale.Initialize( transformManager, mTransformId );
164   mWorldOrientation.Initialize( transformManager, mTransformId );
165   mWorldMatrix.Initialize( transformManager, mTransformId );
166
167   //Set whether the position should use the anchor point
168   transformManager->SetPositionUsesAnchorPoint( mTransformId, mPositionUsesAnchorPoint );
169 }
170
171 void Node::SetRoot(bool isRoot)
172 {
173   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
174
175   mIsRoot = isRoot;
176 }
177
178 void Node::AddUniformMapping( OwnerPointer< UniformPropertyMapping >& map )
179 {
180   PropertyOwner::AddUniformMapping( map );
181   mRegenerateUniformMap = 2;
182 }
183
184 void Node::RemoveUniformMapping( const std::string& uniformName )
185 {
186   PropertyOwner::RemoveUniformMapping( uniformName );
187   mRegenerateUniformMap = 2;
188 }
189
190 void Node::PrepareRender( BufferIndex bufferIndex )
191 {
192   if( mRegenerateUniformMap != 0 )
193   {
194     if( mRegenerateUniformMap == 2 )
195     {
196       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
197       localMap.Resize(0);
198
199       for( UniformMap::SizeType i = 0, count=mUniformMaps.Count(); i<count; ++i )
200       {
201         localMap.PushBack( &mUniformMaps[i] );
202       }
203     }
204     else if( mRegenerateUniformMap == 1 )
205     {
206       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
207       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-bufferIndex ];
208
209       localMap.Resize( oldMap.Count() );
210
211       CollectedUniformMap::SizeType index = 0;
212       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
213       {
214         localMap[index] = *iter;
215       }
216     }
217     --mRegenerateUniformMap;
218     mUniformMapChanged[bufferIndex] = 1u;
219   }
220 }
221
222 void Node::ConnectChild( Node* childNode )
223 {
224   DALI_ASSERT_ALWAYS( this != childNode );
225   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
226   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
227
228   childNode->SetParent( *this );
229
230   // Everything should be reinherited when reconnected to scene-graph
231   childNode->SetAllDirtyFlags();
232
233   // Add the node to the end of the child list.
234   mChildren.PushBack( childNode );
235
236   // Inform property observers of new connection
237   childNode->ConnectToSceneGraph();
238 }
239
240 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode )
241 {
242   DALI_ASSERT_ALWAYS( this != &childNode );
243   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
244
245   // Find the childNode and remove it
246   Node* found( NULL );
247
248   const NodeIter endIter = mChildren.End();
249   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
250   {
251     Node* current = *iter;
252     if ( current == &childNode )
253     {
254       found = current;
255       mChildren.Erase( iter ); // order matters here
256       break; // iter is no longer valid
257     }
258   }
259   DALI_ASSERT_ALWAYS( NULL != found );
260
261   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
262 }
263
264 void Node::AddRenderer( Renderer* renderer )
265 {
266   // If it is the first renderer added, make sure the world transform will be calculated
267   // in the next update as world transform is not computed if node has no renderers.
268   if( mRenderer.Empty() )
269   {
270     mDirtyFlags |= NodePropertyFlags::TRANSFORM;
271   }
272   else
273   {
274     // Check that it has not been already added.
275     for( auto&& existingRenderer : mRenderer )
276     {
277       if( existingRenderer == renderer )
278       {
279         // Renderer is already in the list.
280         return;
281       }
282     }
283   }
284
285   mRenderer.PushBack( renderer );
286 }
287
288 void Node::RemoveRenderer( const Renderer* renderer )
289 {
290   RendererContainer::SizeType rendererCount( mRenderer.Size() );
291   for( RendererContainer::SizeType i = 0; i < rendererCount; ++i )
292   {
293     if( mRenderer[i] == renderer )
294     {
295       mRenderer.Erase( mRenderer.Begin()+i);
296       return;
297     }
298   }
299 }
300
301 NodePropertyFlags Node::GetDirtyFlags() const
302 {
303   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
304   NodePropertyFlags flags = mDirtyFlags;
305
306   // Check whether the visible property has changed
307   if ( !mVisible.IsClean() )
308   {
309     flags |= NodePropertyFlags::VISIBLE;
310   }
311
312   // Check whether the color property has changed
313   if ( !mColor.IsClean() )
314   {
315     flags |= NodePropertyFlags::COLOR;
316   }
317
318   return flags;
319 }
320
321 NodePropertyFlags Node::GetInheritedDirtyFlags( NodePropertyFlags parentFlags ) const
322 {
323   // Size is not inherited. VisibleFlag is inherited
324   static const NodePropertyFlags InheritedDirtyFlags = NodePropertyFlags::TRANSFORM | NodePropertyFlags::VISIBLE | NodePropertyFlags::COLOR;
325   using UnderlyingType = typename std::underlying_type<NodePropertyFlags>::type;
326
327   return static_cast<NodePropertyFlags>( static_cast<UnderlyingType>( mDirtyFlags ) |
328                                          ( static_cast<UnderlyingType>( parentFlags ) & static_cast<UnderlyingType>( InheritedDirtyFlags ) ) );
329 }
330
331 void Node::ResetDirtyFlags( BufferIndex updateBufferIndex )
332 {
333   mDirtyFlags = NodePropertyFlags::NOTHING;
334 }
335
336 void Node::SetParent( Node& parentNode )
337 {
338   DALI_ASSERT_ALWAYS(this != &parentNode);
339   DALI_ASSERT_ALWAYS(!mIsRoot);
340   DALI_ASSERT_ALWAYS(mParent == NULL);
341
342   mParent = &parentNode;
343
344   if( mTransformId != INVALID_TRANSFORM_ID )
345   {
346     mTransformManager->SetParent( mTransformId, parentNode.GetTransformId() );
347   }
348 }
349
350 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
351 {
352   DALI_ASSERT_ALWAYS(!mIsRoot);
353   DALI_ASSERT_ALWAYS(mParent != NULL);
354
355   const NodeIter endIter = mChildren.End();
356   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
357   {
358     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
359   }
360
361   // Animators, Constraints etc. should be disconnected from the child's properties.
362   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
363
364   // Remove back-pointer to parent
365   mParent = NULL;
366
367   // Remove all child pointers
368   mChildren.Clear();
369
370   if( mTransformId != INVALID_TRANSFORM_ID )
371   {
372     mTransformManager->SetParent( mTransformId, INVALID_TRANSFORM_ID );
373   }
374 }
375
376 } // namespace SceneGraph
377
378 } // namespace Internal
379
380 } // namespace Dali