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