Remove batching.
[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( NULL ),
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   mDepthIndex( 0u ),
73   mRegenerateUniformMap( 0 ),
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::AddRenderer( Renderer* renderer )
218 {
219   // Check that it has not been already added.
220   unsigned int rendererCount( mRenderer.Size() );
221   for( unsigned int i(0); i < rendererCount; ++i )
222   {
223     if( mRenderer[i] == renderer )
224     {
225       // Renderer is already in the list.
226       return;
227     }
228   }
229
230   // If it is the first renderer added, make sure the world transform will be calculated
231   // in the next update as world transform is not computed if node has no renderers.
232   if( rendererCount == 0 )
233   {
234     mDirtyFlags |= TransformFlag;
235   }
236
237   mRenderer.PushBack( renderer );
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
289   if( mTransformId != INVALID_TRANSFORM_ID )
290   {
291     mTransformManager->SetParent( mTransformId, parentNode.GetTransformId() );
292   }
293 }
294
295 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
296 {
297   DALI_ASSERT_ALWAYS(!mIsRoot);
298   DALI_ASSERT_ALWAYS(mParent != NULL);
299
300   const NodeIter endIter = mChildren.End();
301   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
302   {
303     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
304   }
305
306   // Animators, Constraints etc. should be disconnected from the child's properties.
307   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
308
309   // Remove back-pointer to parent
310   mParent = NULL;
311
312   // Remove all child pointers
313   mChildren.Clear();
314
315   if( mTransformId != INVALID_TRANSFORM_ID )
316   {
317     mTransformManager->SetParent( mTransformId, INVALID_TRANSFORM_ID );
318   }
319 }
320
321 } // namespace SceneGraph
322
323 } // namespace Internal
324
325 } // namespace Dali