e873a6f48024f5415d1835094da9a760ce4fa394
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.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/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 //Unnamed namespace
29 {
30 //Memory pool used to allocate new nodes. Memory used by this pool will be released when shutting down DALi
31 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
32 }
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 namespace SceneGraph
41 {
42
43 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
44 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
45
46 Node* Node::New()
47 {
48   return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node();
49 }
50
51 Node::Node()
52 : mTransformManager(0),
53   mTransformId( INVALID_TRANSFORM_ID ),
54   mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ),
55   mAnchorPoint( TRANSFORM_PROPERTY_ANCHOR_POINT ),
56   mSize( TRANSFORM_PROPERTY_SIZE ),                                               // Zero initialized by default
57   mPosition( TRANSFORM_PROPERTY_POSITION ),                                       // Zero initialized by default
58   mOrientation(),                                                                 // Initialized to identity by default
59   mScale( TRANSFORM_PROPERTY_SCALE ),
60   mVisible( true ),
61   mColor( Color::WHITE ),
62   mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default
63   mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ),
64   mWorldOrientation(),                                                            // Initialized to identity by default
65   mWorldMatrix(),
66   mWorldColor( Color::WHITE ),
67   mClippingSortModifier( 0u ),
68   mParent( NULL ),
69   mExclusiveRenderTask( NULL ),
70   mChildren(),
71   mClippingDepth( 0u ),
72   mRegenerateUniformMap( 0 ),
73   mDepth( 0u ),
74   mDirtyFlags( AllFlags ),
75   mDrawMode( DrawMode::NORMAL ),
76   mColorMode( DEFAULT_COLOR_MODE ),
77   mClippingMode( ClippingMode::DISABLED ),
78   mIsRoot( false )
79 {
80   mUniformMapChanged[0] = 0u;
81   mUniformMapChanged[1] = 0u;
82 }
83
84 Node::~Node()
85 {
86   if( mTransformId != INVALID_TRANSFORM_ID )
87   {
88     mTransformManager->RemoveTransform(mTransformId);
89   }
90 }
91
92 void Node::operator delete( void* ptr )
93 {
94   gNodeMemoryPool.FreeThreadSafe( static_cast<Node*>( ptr ) );
95 }
96
97 void Node::OnDestroy()
98 {
99   // Animators, Constraints etc. should be disconnected from the child's properties.
100   PropertyOwner::Destroy();
101 }
102
103 void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
104 {
105   //Create a new transform
106   mTransformManager = transformManager;
107   mTransformId = transformManager->CreateTransform();
108
109   //Initialize all the animatable properties
110   mPosition.Initialize( transformManager, mTransformId );
111   mScale.Initialize( transformManager, mTransformId );
112   mOrientation.Initialize( transformManager, mTransformId );
113   mSize.Initialize( transformManager, mTransformId );
114   mParentOrigin.Initialize( transformManager, mTransformId );
115   mAnchorPoint.Initialize( transformManager, mTransformId );
116
117   //Initialize all the input properties
118   mWorldPosition.Initialize( transformManager, mTransformId );
119   mWorldScale.Initialize( transformManager, mTransformId );
120   mWorldOrientation.Initialize( transformManager, mTransformId );
121   mWorldMatrix.Initialize( transformManager, mTransformId );
122 }
123
124 void Node::SetRoot(bool isRoot)
125 {
126   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
127
128   mIsRoot = isRoot;
129 }
130
131 void Node::AddUniformMapping( UniformPropertyMapping* map )
132 {
133   PropertyOwner::AddUniformMapping( map );
134   mRegenerateUniformMap = 2;
135 }
136
137 void Node::RemoveUniformMapping( const std::string& uniformName )
138 {
139   PropertyOwner::RemoveUniformMapping( uniformName );
140   mRegenerateUniformMap = 2;
141 }
142
143 void Node::PrepareRender( BufferIndex bufferIndex )
144 {
145   if(mRegenerateUniformMap != 0 )
146   {
147     if( mRegenerateUniformMap == 2 )
148     {
149       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
150       localMap.Resize(0);
151
152       for( unsigned int i=0, count=mUniformMaps.Count(); i<count; ++i )
153       {
154         localMap.PushBack( &mUniformMaps[i] );
155       }
156     }
157     else if( mRegenerateUniformMap == 1 )
158     {
159       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
160       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-bufferIndex ];
161
162       localMap.Resize( oldMap.Count() );
163
164       unsigned int index=0;
165       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
166       {
167         localMap[index] = *iter;
168       }
169     }
170     --mRegenerateUniformMap;
171     mUniformMapChanged[bufferIndex] = 1u;
172   }
173 }
174
175 void Node::ConnectChild( Node* childNode )
176 {
177   DALI_ASSERT_ALWAYS( this != childNode );
178   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
179   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
180
181   childNode->SetParent( *this );
182
183   // Everything should be reinherited when reconnected to scene-graph
184   childNode->SetAllDirtyFlags();
185
186   // Add the node to the end of the child list.
187   mChildren.PushBack( childNode );
188
189   // Inform property observers of new connection
190   childNode->ConnectToSceneGraph();
191 }
192
193 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode )
194 {
195   DALI_ASSERT_ALWAYS( this != &childNode );
196   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
197
198   // Find the childNode and remove it
199   Node* found( NULL );
200
201   const NodeIter endIter = mChildren.End();
202   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
203   {
204     Node* current = *iter;
205     if ( current == &childNode )
206     {
207       found = current;
208       mChildren.Erase( iter ); // order matters here
209       break; // iter is no longer valid
210     }
211   }
212   DALI_ASSERT_ALWAYS( NULL != found );
213
214   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
215 }
216
217 void Node::RemoveRenderer( Renderer* renderer )
218 {
219   unsigned int rendererCount( mRenderer.Size() );
220   for( unsigned int i(0); i<rendererCount; ++i )
221   {
222     if( mRenderer[i] == renderer )
223     {
224       mRenderer.Erase( mRenderer.Begin()+i);
225       return;
226     }
227   }
228 }
229
230 int Node::GetDirtyFlags() const
231 {
232   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
233   int flags = mDirtyFlags;
234
235   // Check whether the visible property has changed
236   if ( !mVisible.IsClean() )
237   {
238     flags |= VisibleFlag;
239   }
240
241   // Check whether the color property has changed
242   if ( !mColor.IsClean() )
243   {
244     flags |= ColorFlag;
245   }
246
247   return flags;
248 }
249
250 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
251 {
252   mVisible.ResetToBaseValue( updateBufferIndex );
253   mColor.ResetToBaseValue( updateBufferIndex );
254
255   mDirtyFlags = NothingFlag;
256 }
257
258 void Node::SetParent(Node& parentNode)
259 {
260   DALI_ASSERT_ALWAYS(this != &parentNode);
261   DALI_ASSERT_ALWAYS(!mIsRoot);
262   DALI_ASSERT_ALWAYS(mParent == NULL);
263
264   mParent = &parentNode;
265   mDepth = mParent->GetDepth() + 1u;
266
267   if( mTransformId != INVALID_TRANSFORM_ID )
268   {
269     mTransformManager->SetParent( mTransformId, parentNode.GetTransformId() );
270   }
271 }
272
273 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
274 {
275   DALI_ASSERT_ALWAYS(!mIsRoot);
276   DALI_ASSERT_ALWAYS(mParent != NULL);
277
278   const NodeIter endIter = mChildren.End();
279   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
280   {
281     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
282   }
283
284   // Animators, Constraints etc. should be disconnected from the child's properties.
285   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
286
287   // Remove back-pointer to parent
288   mParent = NULL;
289   mDepth = 0u;
290
291   // Remove all child pointers
292   mChildren.Clear();
293
294   if( mTransformId != INVALID_TRANSFORM_ID )
295   {
296     mTransformManager->SetParent( mTransformId, INVALID_TRANSFORM_ID );
297   }
298 }
299
300 } // namespace SceneGraph
301
302 } // namespace Internal
303
304 } // namespace Dali