2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/update/nodes/node.h>
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/internal/update/manager/geometry-batcher.h>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
29 namespace //Unnamed namespace
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;
44 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
45 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
49 return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node();
53 : mTransformManager( NULL ),
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 ),
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
67 mWorldColor( Color::WHITE ),
68 mGeometryBatcher( NULL ),
69 mBatchIndex( BATCH_NULL_HANDLE ),
70 mClippingSortModifier( 0u ),
71 mIsBatchParent( false ),
74 mExclusiveRenderTask( NULL ),
78 mRegenerateUniformMap( 0 ),
79 mDirtyFlags( AllFlags ),
80 mDrawMode( DrawMode::NORMAL ),
81 mColorMode( DEFAULT_COLOR_MODE ),
82 mClippingMode( ClippingMode::DISABLED ),
85 mUniformMapChanged[0] = 0u;
86 mUniformMapChanged[1] = 0u;
91 if( mTransformId != INVALID_TRANSFORM_ID )
93 mTransformManager->RemoveTransform(mTransformId);
97 void Node::operator delete( void* ptr )
99 gNodeMemoryPool.FreeThreadSafe( static_cast<Node*>( ptr ) );
102 void Node::OnDestroy()
104 // Animators, Constraints etc. should be disconnected from the child's properties.
105 PropertyOwner::Destroy();
108 void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
110 //Create a new transform
111 mTransformManager = transformManager;
112 mTransformId = transformManager->CreateTransform();
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 );
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 );
129 void Node::SetRoot(bool isRoot)
131 DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
136 void Node::AddUniformMapping( UniformPropertyMapping* map )
138 PropertyOwner::AddUniformMapping( map );
139 mRegenerateUniformMap = 2;
142 void Node::RemoveUniformMapping( const std::string& uniformName )
144 PropertyOwner::RemoveUniformMapping( uniformName );
145 mRegenerateUniformMap = 2;
148 void Node::PrepareRender( BufferIndex bufferIndex )
150 if(mRegenerateUniformMap != 0 )
152 if( mRegenerateUniformMap == 2 )
154 CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
157 for( unsigned int i=0, count=mUniformMaps.Count(); i<count; ++i )
159 localMap.PushBack( &mUniformMaps[i] );
162 else if( mRegenerateUniformMap == 1 )
164 CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
165 CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-bufferIndex ];
167 localMap.Resize( oldMap.Count() );
169 unsigned int index=0;
170 for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
172 localMap[index] = *iter;
175 --mRegenerateUniformMap;
176 mUniformMapChanged[bufferIndex] = 1u;
180 void Node::ConnectChild( Node* childNode )
182 DALI_ASSERT_ALWAYS( this != childNode );
183 DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
184 DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
186 childNode->SetParent( *this );
188 // Everything should be reinherited when reconnected to scene-graph
189 childNode->SetAllDirtyFlags();
191 // Add the node to the end of the child list.
192 mChildren.PushBack( childNode );
194 // Inform property observers of new connection
195 childNode->ConnectToSceneGraph();
198 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode )
200 DALI_ASSERT_ALWAYS( this != &childNode );
201 DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
203 // Find the childNode and remove it
206 const NodeIter endIter = mChildren.End();
207 for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
209 Node* current = *iter;
210 if ( current == &childNode )
213 mChildren.Erase( iter ); // order matters here
214 break; // iter is no longer valid
217 DALI_ASSERT_ALWAYS( NULL != found );
219 found->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
222 void Node::AddRenderer( Renderer* renderer )
224 // Check that it has not been already added.
225 unsigned int rendererCount( mRenderer.Size() );
226 for( unsigned int i(0); i < rendererCount; ++i )
228 if( mRenderer[i] == renderer )
230 // Renderer is already in the list.
235 // If it is the first renderer added, make sure the world transform will be calculated
236 // in the next update as world transform is not computed if node has no renderers.
237 if( rendererCount == 0 )
239 mDirtyFlags |= TransformFlag;
242 mRenderer.PushBack( renderer );
244 // Tell geometry batcher if should batch the child
245 if( mRenderer.Size() == 1 && mRenderer[0]->mBatchingEnabled )
247 mGeometryBatcher->AddNode( this );
251 void Node::RemoveRenderer( Renderer* renderer )
253 unsigned int rendererCount( mRenderer.Size() );
254 for( unsigned int i(0); i<rendererCount; ++i )
256 if( mRenderer[i] == renderer )
258 mRenderer.Erase( mRenderer.Begin()+i);
264 int Node::GetDirtyFlags() const
266 // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
267 int flags = mDirtyFlags;
269 // Check whether the visible property has changed
270 if ( !mVisible.IsClean() )
272 flags |= VisibleFlag;
275 // Check whether the color property has changed
276 if ( !mColor.IsClean() )
284 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
286 mVisible.ResetToBaseValue( updateBufferIndex );
287 mColor.ResetToBaseValue( updateBufferIndex );
289 mDirtyFlags = NothingFlag;
292 void Node::SetParent( Node& parentNode )
294 DALI_ASSERT_ALWAYS(this != &parentNode);
295 DALI_ASSERT_ALWAYS(!mIsRoot);
296 DALI_ASSERT_ALWAYS(mParent == NULL);
298 mParent = &parentNode;
300 if( mTransformId != INVALID_TRANSFORM_ID )
302 mTransformManager->SetParent( mTransformId, parentNode.GetTransformId() );
306 void Node::SetBatchParent( Node* batchParentNode )
308 DALI_ASSERT_ALWAYS(!mIsRoot);
309 mBatchParent = batchParentNode;
312 void Node::SetIsBatchParent( bool enabled )
314 if( mIsBatchParent != enabled )
316 mIsBatchParent = enabled;
320 mGeometryBatcher->AddBatchParent( this );
324 mGeometryBatcher->RemoveBatchParent( this );
329 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
331 DALI_ASSERT_ALWAYS(!mIsRoot);
332 DALI_ASSERT_ALWAYS(mParent != NULL);
334 const NodeIter endIter = mChildren.End();
335 for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
337 (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex );
340 // Animators, Constraints etc. should be disconnected from the child's properties.
341 PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
343 // Remove back-pointer to parent
346 // Remove all child pointers
349 if( mTransformId != INVALID_TRANSFORM_ID )
351 mTransformManager->SetParent( mTransformId, INVALID_TRANSFORM_ID );
355 } // namespace SceneGraph
357 } // namespace Internal