[Tizen] Implement partial update
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.cpp
old mode 100644 (file)
new mode 100755 (executable)
index aa7f777..68ffe7e
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/constants.h>
 
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/constants.h>
 
-namespace //Unnamed namespace
+namespace
 {
 //Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
 // or DALI library is unloaded
 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
 #ifdef DEBUG_ENABLED
 {
 //Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
 // or DALI library is unloaded
 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
 #ifdef DEBUG_ENABLED
-// keep track of nodes created / deleted, to ensure we have 0 when the process exits or DALi library is unloaded
-int gNodeCount =0;
+// keep track of nodes alive, to ensure we have 0 when the process exits or DALi library is unloaded
+int32_t gNodeCount = 0;
 
 // Called when the process is about to exit, Node count should be zero at this point.
 void __attribute__ ((destructor)) ShutDown(void)
 
 // Called when the process is about to exit, Node count should be zero at this point.
 void __attribute__ ((destructor)) ShutDown(void)
@@ -40,7 +40,7 @@ void __attribute__ ((destructor)) ShutDown(void)
 DALI_ASSERT_DEBUG( (gNodeCount == 0) && "Node memory leak");
 }
 #endif
 DALI_ASSERT_DEBUG( (gNodeCount == 0) && "Node memory leak");
 }
 #endif
-}
+} // Unnamed namespace
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -51,13 +51,13 @@ namespace Internal
 namespace SceneGraph
 {
 
 namespace SceneGraph
 {
 
-const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
 
 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
 
+uint32_t Node::mNodeCounter = 0;        ///< A counter to provide unique node ids, up-to 4 billion
 
 Node* Node::New()
 {
 
 Node* Node::New()
 {
-  return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node();
+  return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node;
 }
 
 void Node::Delete( Node* node )
 }
 
 void Node::Delete( Node* node )
@@ -87,7 +87,9 @@ Node::Node()
   mPosition( TRANSFORM_PROPERTY_POSITION ),                                       // Zero initialized by default
   mOrientation(),                                                                 // Initialized to identity by default
   mScale( TRANSFORM_PROPERTY_SCALE ),
   mPosition( TRANSFORM_PROPERTY_POSITION ),                                       // Zero initialized by default
   mOrientation(),                                                                 // Initialized to identity by default
   mScale( TRANSFORM_PROPERTY_SCALE ),
+  mUpdateSizeHint( TRANSFORM_PROPERTY_UPDATE_SIZE_HINT ),
   mVisible( true ),
   mVisible( true ),
+  mCulled( false ),
   mColor( Color::WHITE ),
   mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default
   mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ),
   mColor( Color::WHITE ),
   mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default
   mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ),
@@ -95,14 +97,15 @@ Node::Node()
   mWorldMatrix(),
   mWorldColor( Color::WHITE ),
   mClippingSortModifier( 0u ),
   mWorldMatrix(),
   mWorldColor( Color::WHITE ),
   mClippingSortModifier( 0u ),
+  mId( ++mNodeCounter ),
   mParent( NULL ),
   mExclusiveRenderTask( NULL ),
   mChildren(),
   mClippingDepth( 0u ),
   mScissorDepth( 0u ),
   mDepthIndex( 0u ),
   mParent( NULL ),
   mExclusiveRenderTask( NULL ),
   mChildren(),
   mClippingDepth( 0u ),
   mScissorDepth( 0u ),
   mDepthIndex( 0u ),
+  mDirtyFlags( NodePropertyFlags::ALL ),
   mRegenerateUniformMap( 0 ),
   mRegenerateUniformMap( 0 ),
-  mDirtyFlags( AllFlags ),
   mDrawMode( DrawMode::NORMAL ),
   mColorMode( DEFAULT_COLOR_MODE ),
   mClippingMode( ClippingMode::DISABLED ),
   mDrawMode( DrawMode::NORMAL ),
   mColorMode( DEFAULT_COLOR_MODE ),
   mClippingMode( ClippingMode::DISABLED ),
@@ -112,6 +115,7 @@ Node::Node()
 {
   mUniformMapChanged[0] = 0u;
   mUniformMapChanged[1] = 0u;
 {
   mUniformMapChanged[0] = 0u;
   mUniformMapChanged[1] = 0u;
+  mPropertyDirty = false;
 
 #ifdef DEBUG_ENABLED
   gNodeCount++;
 
 #ifdef DEBUG_ENABLED
   gNodeCount++;
@@ -137,6 +141,11 @@ void Node::OnDestroy()
   PropertyOwner::Destroy();
 }
 
   PropertyOwner::Destroy();
 }
 
+uint32_t Node::GetId() const
+{
+  return mId;
+}
+
 void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
 {
   //Create a new transform
 void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
 {
   //Create a new transform
@@ -146,6 +155,7 @@ void Node::CreateTransform( SceneGraph::TransformManager* transformManager )
   //Initialize all the animatable properties
   mPosition.Initialize( transformManager, mTransformId );
   mScale.Initialize( transformManager, mTransformId );
   //Initialize all the animatable properties
   mPosition.Initialize( transformManager, mTransformId );
   mScale.Initialize( transformManager, mTransformId );
+  mUpdateSizeHint.Initialize( transformManager, mTransformId );
   mOrientation.Initialize( transformManager, mTransformId );
   mSize.Initialize( transformManager, mTransformId );
   mParentOrigin.Initialize( transformManager, mTransformId );
   mOrientation.Initialize( transformManager, mTransformId );
   mSize.Initialize( transformManager, mTransformId );
   mParentOrigin.Initialize( transformManager, mTransformId );
@@ -182,14 +192,14 @@ void Node::RemoveUniformMapping( const std::string& uniformName )
 
 void Node::PrepareRender( BufferIndex bufferIndex )
 {
 
 void Node::PrepareRender( BufferIndex bufferIndex )
 {
-  if(mRegenerateUniformMap != 0 )
+  if( mRegenerateUniformMap != 0 )
   {
     if( mRegenerateUniformMap == 2 )
     {
       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
       localMap.Resize(0);
 
   {
     if( mRegenerateUniformMap == 2 )
     {
       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
       localMap.Resize(0);
 
-      for( unsigned int i=0, count=mUniformMaps.Count(); i<count; ++i )
+      for( UniformMap::SizeType i = 0, count=mUniformMaps.Count(); i<count; ++i )
       {
         localMap.PushBack( &mUniformMaps[i] );
       }
       {
         localMap.PushBack( &mUniformMaps[i] );
       }
@@ -201,7 +211,7 @@ void Node::PrepareRender( BufferIndex bufferIndex )
 
       localMap.Resize( oldMap.Count() );
 
 
       localMap.Resize( oldMap.Count() );
 
-      unsigned int index=0;
+      CollectedUniformMap::SizeType index = 0;
       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
       {
         localMap[index] = *iter;
       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
       {
         localMap[index] = *iter;
@@ -256,63 +266,84 @@ void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode )
 
 void Node::AddRenderer( Renderer* renderer )
 {
 
 void Node::AddRenderer( Renderer* renderer )
 {
-  // Check that it has not been already added.
-  unsigned int rendererCount( mRenderer.Size() );
-  for( unsigned int i(0); i < rendererCount; ++i )
-  {
-    if( mRenderer[i] == renderer )
-    {
-      // Renderer is already in the list.
-      return;
-    }
-  }
-
   // If it is the first renderer added, make sure the world transform will be calculated
   // in the next update as world transform is not computed if node has no renderers.
   // If it is the first renderer added, make sure the world transform will be calculated
   // in the next update as world transform is not computed if node has no renderers.
-  if( rendererCount == 0 )
+  if( mRenderer.Empty() )
   {
   {
-    mDirtyFlags |= TransformFlag;
+    mDirtyFlags |= NodePropertyFlags::TRANSFORM;
+  }
+  else
+  {
+    // Check that it has not been already added.
+    for( auto&& existingRenderer : mRenderer )
+    {
+      if( existingRenderer == renderer )
+      {
+        // Renderer is already in the list.
+        return;
+      }
+    }
   }
 
   mRenderer.PushBack( renderer );
   }
 
   mRenderer.PushBack( renderer );
+  SetPropertyDirty( true );
 }
 
 }
 
-void Node::RemoveRenderer( Renderer* renderer )
+void Node::RemoveRenderer( const Renderer* renderer )
 {
 {
-  unsigned int rendererCount( mRenderer.Size() );
-  for( unsigned int i(0); i<rendererCount; ++i )
+  RendererContainer::SizeType rendererCount( mRenderer.Size() );
+  for( RendererContainer::SizeType i = 0; i < rendererCount; ++i )
   {
     if( mRenderer[i] == renderer )
     {
   {
     if( mRenderer[i] == renderer )
     {
+      SetPropertyDirty( true );
       mRenderer.Erase( mRenderer.Begin()+i);
       return;
     }
   }
 }
 
       mRenderer.Erase( mRenderer.Begin()+i);
       return;
     }
   }
 }
 
-int Node::GetDirtyFlags() const
+NodePropertyFlags Node::GetDirtyFlags() const
 {
   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
 {
   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
-  int flags = mDirtyFlags;
+  NodePropertyFlags flags = mDirtyFlags;
 
   // Check whether the visible property has changed
   if ( !mVisible.IsClean() )
   {
 
   // Check whether the visible property has changed
   if ( !mVisible.IsClean() )
   {
-    flags |= VisibleFlag;
+    flags |= NodePropertyFlags::VISIBLE;
   }
 
   // Check whether the color property has changed
   if ( !mColor.IsClean() )
   {
   }
 
   // Check whether the color property has changed
   if ( !mColor.IsClean() )
   {
-    flags |= ColorFlag;
+    flags |= NodePropertyFlags::COLOR;
   }
 
   return flags;
 }
 
   }
 
   return flags;
 }
 
+NodePropertyFlags Node::GetInheritedDirtyFlags( NodePropertyFlags parentFlags ) const
+{
+  // Size is not inherited. VisibleFlag is inherited
+  static const NodePropertyFlags InheritedDirtyFlags = NodePropertyFlags::TRANSFORM | NodePropertyFlags::VISIBLE | NodePropertyFlags::COLOR;
+  using UnderlyingType = typename std::underlying_type<NodePropertyFlags>::type;
+
+  return static_cast<NodePropertyFlags>( static_cast<UnderlyingType>( mDirtyFlags ) |
+                                         ( static_cast<UnderlyingType>( parentFlags ) & static_cast<UnderlyingType>( InheritedDirtyFlags ) ) );
+}
+
 void Node::ResetDirtyFlags( BufferIndex updateBufferIndex )
 {
 void Node::ResetDirtyFlags( BufferIndex updateBufferIndex )
 {
-  mDirtyFlags = NothingFlag;
+  mDirtyFlags = NodePropertyFlags::NOTHING;
+
+  SetPropertyDirty( false );
+
+  for( auto&& existingRenderer : mRenderer )
+  {
+    existingRenderer->SetDirty( false );
+  }
+
 }
 
 void Node::SetParent( Node& parentNode )
 }
 
 void Node::SetParent( Node& parentNode )
@@ -355,24 +386,33 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex )
   }
 }
 
   }
 }
 
-} // namespace SceneGraph
-
-template <>
-void OwnerPointer<Dali::Internal::SceneGraph::Node>::Reset()
+void Node::SetPropertyDirty( bool value )
 {
 {
-  if( mObject != NULL )
+  mPropertyDirty = value;
+
+  const NodeIter endIter = mChildren.End();
+  for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
   {
   {
-    Dali::Internal::SceneGraph::Node::Delete( mObject );
-    mObject = NULL;
+    Node* current = *iter;
+    current->SetPropertyDirty( value );
   }
 }
 
   }
 }
 
-} // namespace Internal
-
-template <>
-void OwnerContainer<Dali::Internal::SceneGraph::Node*>::Delete(Dali::Internal::SceneGraph::Node* pointer)
+bool Node::IsPropertyDirty() const
 {
 {
-  Dali::Internal::SceneGraph::Node::Delete( pointer );
+  for( auto&& existingRenderer : mRenderer )
+  {
+    if( existingRenderer->IsDirty() )
+    {
+      return true;
+    }
+  }
+
+  return mPropertyDirty;
 }
 
 }
 
+} // namespace SceneGraph
+
+} // namespace Internal
+
 } // namespace Dali
 } // namespace Dali