Uniform map handling 49/37449/6
authorDavid Steele <david.steele@partner.samsung.com>
Thu, 26 Mar 2015 18:07:09 +0000 (18:07 +0000)
committerDavid Steele <david.steele@partner.samsung.com>
Wed, 1 Apr 2015 10:50:15 +0000 (11:50 +0100)
Updated event implementations of geometry, property buffer, material, sampler and renderer to handle custom properties and default animatable properties.

Added uniform maps to property-owners.

Uniform maps are only held by SceneGraph, so the API was updated to match. Event objects do not hold a copy of the map.

The maps from all 6 rendering objects are re-collected in the renderer-attachment's DoPrepareRender step if any of them have changed.

The collected map is accessible by the NewRenderer from the render thread through the UniformMapDataProvider interface, so is double buffered.

The NewRenderer maintains a list of uniform names/ program location index / property value address, and updates the uniform locations from the uniform names only when the uniform mapping has changed, not when property values change.

Change-Id: I9cec141cd7746540eda3f9049b0f4ede907b03f8
Signed-off-by: David Steele <david.steele@partner.samsung.com>
65 files changed:
dali/internal/event/actor-attachments/renderable-attachment-impl.cpp
dali/internal/event/actor-attachments/renderer-attachment-impl.cpp
dali/internal/event/actor-attachments/renderer-attachment-impl.h
dali/internal/event/actors/renderer-impl.cpp
dali/internal/event/actors/renderer-impl.h
dali/internal/event/common/object-impl-helper.h
dali/internal/event/common/object-impl.cpp
dali/internal/event/common/object-impl.h
dali/internal/event/common/property-buffer-impl.cpp
dali/internal/event/common/property-metadata.h
dali/internal/event/effects/material-impl.cpp
dali/internal/event/effects/material-impl.h
dali/internal/event/effects/sampler-impl.cpp
dali/internal/event/effects/sampler-impl.h
dali/internal/event/effects/shader-impl.cpp
dali/internal/event/effects/shader-impl.h
dali/internal/event/geometry/geometry-impl.cpp
dali/internal/event/geometry/geometry-impl.h
dali/internal/file.list
dali/internal/render/data-providers/uniform-map-data-provider.h [new file with mode: 0644]
dali/internal/render/renderers/render-geometry.cpp
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/renderers/scene-graph-renderer.cpp
dali/internal/render/renderers/scene-graph-renderer.h
dali/internal/update/common/discard-queue.cpp
dali/internal/update/common/discard-queue.h
dali/internal/update/common/property-owner-messages.cpp [moved from dali/internal/render/data-providers/uniform-map-provider.h with 52% similarity]
dali/internal/update/common/property-owner-messages.h
dali/internal/update/common/property-owner.cpp
dali/internal/update/common/property-owner.h
dali/internal/update/common/scene-graph-connection-observers.cpp [new file with mode: 0644]
dali/internal/update/common/scene-graph-connection-observers.h [new file with mode: 0644]
dali/internal/update/common/scene-graph-property-buffer.cpp
dali/internal/update/common/scene-graph-property-buffer.h
dali/internal/update/common/uniform-map.cpp [new file with mode: 0644]
dali/internal/update/common/uniform-map.h
dali/internal/update/effects/scene-graph-material.cpp
dali/internal/update/effects/scene-graph-material.h
dali/internal/update/effects/scene-graph-sampler.cpp
dali/internal/update/effects/scene-graph-sampler.h
dali/internal/update/geometry/scene-graph-geometry.cpp
dali/internal/update/geometry/scene-graph-geometry.h
dali/internal/update/manager/object-owner-container.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/node-attachments/node-attachment.h
dali/internal/update/node-attachments/scene-graph-camera-attachment.cpp
dali/internal/update/node-attachments/scene-graph-camera-attachment.h
dali/internal/update/node-attachments/scene-graph-image-attachment.cpp
dali/internal/update/node-attachments/scene-graph-image-attachment.h
dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp
dali/internal/update/node-attachments/scene-graph-renderable-attachment.h
dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp
dali/internal/update/node-attachments/scene-graph-renderer-attachment.h
dali/internal/update/node-attachments/scene-graph-text-attachment.cpp
dali/internal/update/node-attachments/scene-graph-text-attachment.h
dali/internal/update/nodes/node.cpp
dali/public-api/actors/renderer.cpp
dali/public-api/actors/renderer.h
dali/public-api/geometry/geometry.cpp
dali/public-api/object/handle.cpp
dali/public-api/object/handle.h
dali/public-api/object/property-index-ranges.h
dali/public-api/shader-effects/material.cpp

index 29fe2af..9902e82 100644 (file)
@@ -39,7 +39,6 @@ RenderableAttachment::~RenderableAttachment()
 {
 }
 
-
 void RenderableAttachment::OnStageConnection()
 {
   // For derived classes
index d760283..2007be7 100644 (file)
@@ -33,14 +33,25 @@ RendererAttachmentPtr RendererAttachment::New( EventThreadServices& eventThreadS
 {
   RendererAttachmentPtr attachment( new RendererAttachment( eventThreadServices ) );
 
-  // Transfer object ownership of scene-object to message
+  if( attachment )
+  {
+    attachment->Initialize( eventThreadServices, parentNode, renderer );
+  }
+  return attachment;
+}
+
+void RendererAttachment::Initialize( EventThreadServices& eventThreadServices, const SceneGraph::Node& parentNode, Renderer& renderer )
+{
   SceneGraph::RendererAttachment* sceneObject = renderer.GetRendererSceneObject();
+
+  // Takes ownership of scene object
   AttachToNodeMessage( eventThreadServices.GetUpdateManager(), parentNode, sceneObject );
 
-  // Keep raw pointer for message passing
-  attachment->mSceneObject = sceneObject;
+  // Connect to renderer
+  mRendererConnector.Set( renderer, false );
 
-  return attachment;
+  // Keep raw pointer for message passing
+  mSceneObject = sceneObject;
 }
 
 RendererAttachment::RendererAttachment( EventThreadServices& eventThreadServices )
@@ -53,18 +64,12 @@ RendererAttachment::~RendererAttachment()
 {
 }
 
-SceneGraph::RendererAttachment* RendererAttachment::CreateSceneObject()
-{
-  return SceneGraph::RendererAttachment::New();
-}
-
 const SceneGraph::RendererAttachment& RendererAttachment::GetSceneObject() const
 {
   DALI_ASSERT_DEBUG( mSceneObject != NULL );
   return *mSceneObject;
 }
 
-
 void RendererAttachment::OnStageConnection2()
 {
   mRendererConnector.OnStageConnect();
@@ -75,8 +80,6 @@ void RendererAttachment::OnStageDisconnection2()
   mRendererConnector.OnStageDisconnect();
 }
 
-
-
 } // namespace Internal
 
 } // namespace Dali
index b1a6b76..0fac85e 100644 (file)
@@ -40,6 +40,9 @@ typedef IntrusivePtr<RendererAttachment>  RendererAttachmentPtr;
 
 /**
  * An attachment for rendering renderers.
+ *
+ * Currently, the Renderer object creates the SceneGraph::RendererAttachment object, not this. It is attached
+ * here as needed.
  */
 class RendererAttachment : public RenderableAttachment
 {
@@ -54,6 +57,16 @@ public:
    */
   static RendererAttachmentPtr New( EventThreadServices& eventThreadServices, const SceneGraph::Node& parentNode, Renderer& renderer );
 
+
+  /**
+   * Second stage initialization
+   *
+   * @param[in] eventThreadServices Used for messaging to and reading from the SceneGraph
+   * @param[in] parentNode The node to attach a scene-object to.
+   * @poaram[in] renderer The renderer for this attachment
+   */
+  void Initialize( EventThreadServices& eventThreadServices, const SceneGraph::Node& parentNode, Renderer& renderer );
+
   /**
    * Get the renderer
    *
@@ -73,12 +86,6 @@ private:
   RendererAttachment( EventThreadServices& eventThreadServices );
 
   /**
-   * Creates the corresponding scene-graph RendererAttachment.
-   * @return A newly allocated scene object.
-   */
-  static SceneGraph::RendererAttachment* CreateSceneObject();
-
-  /**
    * @copydoc Dali::Internal::RenderableAttachment::GetSceneObject()
    */
   virtual const SceneGraph::RendererAttachment& GetSceneObject() const;
index 5496dbd..45aa14e 100644 (file)
@@ -22,8 +22,9 @@
 #include <dali/public-api/actors/renderer.h> // Dali::Renderer
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/common/property-input-impl.h>
 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
+#include <dali/internal/update/manager/update-manager.h>
 
 namespace Dali
 {
@@ -55,6 +56,7 @@ void Renderer::SetGeometry( Geometry& geometry )
 {
   mGeometryConnector.Set( geometry, OnStage() );
   const SceneGraph::Geometry* geometrySceneObject = geometry.GetGeometrySceneObject();
+
   SetGeometryMessage( GetEventThreadServices(), *mSceneObject, *geometrySceneObject );
 }
 
@@ -67,9 +69,18 @@ void Renderer::SetMaterial( Material& material )
 
 void Renderer::SetDepthIndex( int depthIndex )
 {
-  //SceneGraph::NodePropertyMessage<Vector3>::Send( mStage->GetUpdateManager(), mNode, &mNode->mPosition, &AnimatableProperty<Vector3>::Bake, position );
-  // TODO: MESH_REWORK
-  DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
+  SceneGraph::PropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mDepthIndex, &SceneGraph::AnimatableProperty<int>::Bake, depthIndex );
+}
+
+int Renderer::GetCurrentDepthIndex() const
+{
+  int depthIndex = 0;
+  if( mSceneObject )
+  {
+    BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
+    depthIndex = mSceneObject->mDepthIndex[bufferIndex];
+  }
+  return depthIndex;
 }
 
 SceneGraph::RendererAttachment* Renderer::GetRendererSceneObject()
@@ -120,24 +131,41 @@ Property::Type Renderer::GetDefaultPropertyType( Property::Index index ) const
 void Renderer::SetDefaultProperty( Property::Index index,
                                    const Property::Value& propertyValue )
 {
-  RENDERER_IMPL.SetDefaultProperty( index, propertyValue );
+  switch( index )
+  {
+    case Dali::Renderer::Property::DEPTH_INDEX:
+    {
+      SetDepthIndex( propertyValue.Get<int>() );
+    }
+    break;
+  }
 }
 
 void Renderer::SetSceneGraphProperty( Property::Index index,
                                       const PropertyMetadata& entry,
                                       const Property::Value& value )
 {
-  RENDERER_IMPL.SetSceneGraphProperty( index, entry, value );
+  RENDERER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
+  OnPropertySet(index, value);
 }
 
 Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
 {
-  return RENDERER_IMPL.GetDefaultProperty( index );
+  Property::Value value;
+  switch( index )
+  {
+    case Dali::Renderer::Property::DEPTH_INDEX:
+    {
+      value = GetCurrentDepthIndex();
+    }
+    break;
+  }
+  return value;
 }
 
 const SceneGraph::PropertyOwner* Renderer::GetPropertyOwner() const
 {
-  return RENDERER_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* Renderer::GetSceneObject() const
@@ -147,29 +175,75 @@ const SceneGraph::PropertyOwner* Renderer::GetSceneObject() const
 
 const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return RENDERER_IMPL.GetSceneObjectAnimatableProperty( index );
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = RENDERER_IMPL.GetRegisteredSceneGraphProperty(
+      this,
+      &Renderer::FindAnimatableProperty,
+      &Renderer::FindCustomProperty,
+      index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Renderer::Property::DEPTH_INDEX:
+        {
+          property = &mSceneObject->mDepthIndex;
+        }
+        break;
+      }
+    }
+  }
+
+  return property;
 }
 
 const PropertyInputImpl* Renderer::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return RENDERER_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      RENDERER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                     &Renderer::FindAnimatableProperty,
+                                                     &Renderer::FindCustomProperty,
+                                                     index );
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Renderer::Property::DEPTH_INDEX:
+        {
+          property = &mSceneObject->mDepthIndex;
+        }
+        break;
+      }
+    }
+  }
+
+  return property;
 }
 
 int Renderer::GetPropertyComponentIndex( Property::Index index ) const
 {
-  return RENDERER_IMPL.GetPropertyComponentIndex( index );
+  return Property::INVALID_COMPONENT_INDEX;
 }
 
 bool Renderer::OnStage() const
 {
-  // TODO: MESH_REWORK
-  //DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
   return mOnStage;
 }
 
 void Renderer::Connect()
 {
-  // TODO: MESH_REWORK : check this
+  // @todo: MESH_REWORK : check this
   mGeometryConnector.OnStageConnect();
   mMaterialConnector.OnStageConnect();
   mOnStage = true;
@@ -177,7 +251,7 @@ void Renderer::Connect()
 
 void Renderer::Disconnect()
 {
-  // TODO: MESH_REWORK : check this
+  // @todo: MESH_REWORK : check this
   mGeometryConnector.OnStageDisconnect();
   mMaterialConnector.OnStageDisconnect();
   mOnStage = false;
@@ -191,13 +265,20 @@ Renderer::Renderer()
 
 void Renderer::Initialize()
 {
+  DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
+  EventThreadServices& eventThreadServices = GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+
   // Transfer object ownership of scene-object to message
   mSceneObject = SceneGraph::RendererAttachment::New();
 
   // Send message to update to connect to scene graph:
-  AttachToSceneGraphMessage( Stage::GetCurrent()->GetUpdateManager(), mSceneObject );
+  AttachToSceneGraphMessage( updateManager, mSceneObject );
 }
 
+Renderer::~Renderer()
+{
+}
 
 } // namespace Internal
 } // namespace Dali
index 9404b77..64fa58c 100644 (file)
@@ -69,6 +69,11 @@ public:
   void SetDepthIndex( int depthIndex );
 
   /**
+   * @copydoc Dali::Renderer::GetCurrentDepthIndex()
+   */
+  int GetCurrentDepthIndex() const;
+
+  /**
    * @brief Get the scene graph object ( the node attachment )
    *
    * @return the scene object
@@ -178,6 +183,12 @@ private: // implementation
 
   void Initialize();
 
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Renderer();
+
 private: // unimplemented methods
   Renderer( const Renderer& );
   Renderer& operator=( const Renderer& );
index 95a39e7..aeae9c1 100644 (file)
 #include <dali/public-api/object/property.h> // Dali::Property
 #include <dali/public-api/object/property-index-ranges.h> // DEFAULT_DERIVED_HANDLE_PROPERTY_START_INDEX
 #include <dali/internal/event/common/property-helper.h> // Dali::Internal::PropertyDetails
+#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/update/common/animatable-property.h>
+#include <dali/internal/update/common/property-owner-messages.h>
+#include <dali/internal/update/manager/update-manager.h>
 
 namespace Dali
 {
 namespace Internal
 {
 class PropertyMetadata;
+class AnimatablePropertyMetadata;
+class CustomPropertyMetadata;
 class PropertyInputImpl;
 
 namespace SceneGraph
@@ -39,6 +45,11 @@ class PropertyOwner;
 
 } // namespace SceneGraph
 
+// Typedefs to allow object methods to be passed via parameter
+typedef AnimatablePropertyMetadata* (Object::*FindAnimatablePropertyMethod)( Property::Index index ) const;
+typedef CustomPropertyMetadata* (Object::*FindCustomPropertyMethod)( Property::Index index ) const;
+
+
 /**
  * Helper template class to be used by class that implement Object
  *
@@ -49,7 +60,6 @@ class PropertyOwner;
  * MyObjectImpl::GetDefaultPropertyCount();
  * </pre>
  */
-
 template<int DEFAULT_PROPERTY_COUNT>
 struct ObjectImplHelper
 {
@@ -86,6 +96,10 @@ struct ObjectImplHelper
   {
     Property::Index index = Property::INVALID_INDEX;
 
+    //@todo MESH_REWORK - Are we assuming that the index into the array is the
+    // same as the enumerated property? if enumIndex in the table was no longer
+    // debug only, wouldn't need to make this assumption.
+
     // Look for name in default properties
     for( unsigned int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
     {
@@ -148,50 +162,144 @@ struct ObjectImplHelper
     return type;
   }
 
-  void SetDefaultProperty( Property::Index index,
-                           const Property::Value& property ) const
+  // Get the (animatable) scene graph property. (All registered scene graph properties are animatable)
+  const SceneGraph::PropertyBase* GetRegisteredSceneGraphProperty(
+    const Object* object,
+    FindAnimatablePropertyMethod findAnimatablePropertyMethod,
+    FindCustomPropertyMethod findCustomPropertyMethod,
+    Property::Index index ) const
   {
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
+    const SceneGraph::PropertyBase* property = NULL;
+    if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
+    {
+      AnimatablePropertyMetadata* animatable = (object->*findAnimatablePropertyMethod)( index );
+      DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
+      property = animatable->GetSceneGraphProperty();
+    }
+    else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      CustomPropertyMetadata* custom = (object->*findCustomPropertyMethod)( index );
+      DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
+      property = custom->GetSceneGraphProperty();
+    }
+    return property;
   }
 
-  void SetSceneGraphProperty( Property::Index index,
+  void SetSceneGraphProperty( EventThreadServices& eventThreadServices,
+                              const Object* object,
+                              Property::Index index,
                               const PropertyMetadata& entry,
                               const Property::Value& value ) const
   {
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
-  }
+    const SceneGraph::PropertyOwner* sceneObject = object->GetSceneObject();
 
-  Property::Value GetDefaultProperty( Property::Index index ) const
-  {
-    Property::Value value;
+    switch ( entry.type )
+    {
+      case Property::BOOLEAN:
+      {
+        const SceneGraph::AnimatableProperty<bool>* property = dynamic_cast< const SceneGraph::AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
 
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<bool>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<bool>::Bake, value.Get<bool>() );
 
-    return value;
-  }
+        break;
+      }
 
-  const SceneGraph::PropertyOwner* GetPropertyOwner() const
-  {
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
-    return 0;
-  }
+      case Property::FLOAT:
+      {
+        const SceneGraph::AnimatableProperty<float>* property = dynamic_cast< const SceneGraph::AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
 
-  const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty( Property::Index index ) const
-  {
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
-    return 0;
-  }
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<float>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<float>::Bake, value.Get<float>() );
 
-  const PropertyInputImpl* GetSceneObjectInputProperty( Property::Index index ) const
-  {
-    // TODO: MESH_REWORK
-    DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
-    return 0;
+        break;
+      }
+
+      case Property::INTEGER:
+      {
+        const SceneGraph::AnimatableProperty<int>* property = dynamic_cast< const SceneGraph::AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<int>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<int>::Bake, value.Get<int>() );
+
+        break;
+      }
+
+      case Property::VECTOR2:
+      {
+        const SceneGraph::AnimatableProperty<Vector2>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Vector2>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
+
+        break;
+      }
+
+      case Property::VECTOR3:
+      {
+        const SceneGraph::AnimatableProperty<Vector3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Vector3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
+
+        break;
+      }
+
+      case Property::VECTOR4:
+      {
+        const SceneGraph::AnimatableProperty<Vector4>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Vector4>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
+
+        break;
+      }
+
+      case Property::ROTATION:
+      {
+        const SceneGraph::AnimatableProperty<Quaternion>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Quaternion>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
+
+        break;
+      }
+
+      case Property::MATRIX:
+      {
+        const SceneGraph::AnimatableProperty<Matrix>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Matrix>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
+
+        break;
+      }
+
+      case Property::MATRIX3:
+      {
+        const SceneGraph::AnimatableProperty<Matrix3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        // property is being used in a separate thread; queue a message to set the property
+        SceneGraph::PropertyMessage<Matrix3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
+
+        break;
+      }
+
+      default:
+      {
+        DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
+        break;
+      }
+    }
   }
 
   int GetPropertyComponentIndex( Property::Index index ) const
@@ -200,7 +308,6 @@ struct ObjectImplHelper
     DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
     return 0;
   }
-
 };
 
 
index b404f60..ab9aec1 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/property-owner-messages.h>
+#include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/event/animation/active-constraint-base.h>
 #include <dali/internal/event/animation/constraint-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
@@ -770,6 +771,57 @@ void Object::DisablePropertyNotifications()
   }
 }
 
+void Object::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
+{
+  // Get the address of the property if it's a scene property
+  const PropertyInputImpl* propertyPtr = GetSceneObjectInputProperty( propertyIndex );
+
+  // Check instead for newly registered properties
+  if( propertyPtr == NULL )
+  {
+    PropertyMetadata* animatable = FindAnimatableProperty( propertyIndex );
+    if( animatable != NULL )
+    {
+      propertyPtr = animatable->GetSceneGraphProperty();
+    }
+  }
+
+  if( propertyPtr == NULL )
+  {
+    PropertyMetadata* custom = FindCustomProperty( propertyIndex );
+    if( custom != NULL )
+    {
+      propertyPtr = custom->GetSceneGraphProperty();
+    }
+  }
+
+  // @todo MESH_REWORK Store mappings for unstaged objects?
+
+  if( propertyPtr != NULL )
+  {
+    const SceneGraph::PropertyOwner* sceneObject = GetPropertyOwner();
+
+    if( sceneObject != NULL )
+    {
+      SceneGraph::UniformPropertyMapping* map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
+      // Message takes ownership of Uniform map (and will delete it after copy)
+      AddUniformMapMessage( GetEventThreadServices(), *sceneObject, map);
+    }
+    else
+    {
+      // @todo MESH_REWORK FIXME Need to store something that can be sent to the scene
+      // object when staged.
+      DALI_ASSERT_ALWAYS(0 && "MESH_REWORK - Need to store property whilst off-stage" );
+    }
+  }
+}
+
+void Object::RemoveUniformMapping( const std::string& uniformName )
+{
+  const SceneGraph::PropertyOwner* sceneObject = GetSceneObject();
+  RemoveUniformMapMessage( GetEventThreadServices(), *sceneObject, uniformName);
+}
+
 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint )
 {
   return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Handle() ) );
index bb09d8c..8b96696 100644 (file)
@@ -59,6 +59,7 @@ typedef std::vector< Dali::ActiveConstraint >     ActiveConstraintContainer;
 typedef ActiveConstraintContainer::iterator       ActiveConstraintIter;
 typedef ActiveConstraintContainer::const_iterator ActiveConstraintConstIter;
 
+
 /**
  * A base class for objects which optionally provide properties.
  * The concrete derived class is responsible for implementing the property system methods.
@@ -211,7 +212,19 @@ public:
    */
   virtual void RemovePropertyNotifications();
 
-  // Constraints
+  /******************************** Uniform Mappings ********************************/
+
+  /**
+   * @copydoc Dali::Handle::AddUniformMapping()
+   */
+  void AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName );
+
+  /**
+   * @copydoc Dali::Handle::RemoveUniformMapping( )
+   */
+  void RemoveUniformMapping( const std::string& uniformName );
+
+  /******************************** Constraints ********************************/
 
   /**
    * Apply a constraint to a Object.
@@ -256,7 +269,7 @@ public:
     return PROPERTY_CUSTOM_START_INDEX;
   }
 
-  // To be overridden by deriving classes
+  /********************  To be overridden by deriving classes ********************/
 
   /**
    * Retrieve the scene-graph object added by this object.
@@ -273,7 +286,7 @@ public:
   virtual const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty( Property::Index index ) const = 0;
 
   /**
-   * Retrieve an constraint input-property owned by the scene-graph object.
+   * Retrieve a constraint input-property owned by the scene-graph object.
    * @pre -1 < index < GetPropertyCount().
    * @param[in] index The index of the property.
    * @return A dereferenceable pointer to an input property, or NULL if a scene-object does not exist with this property.
@@ -529,7 +542,6 @@ private:
   typedef PropertyNotificationContainer::const_iterator PropertyNotificationContainerConstIter;
   PropertyNotificationContainer* mPropertyNotifications; ///< Container of owned property notifications.
 };
-
 } // namespace Internal
 
 // Helpers for public-api forwarding methods
index 382c8bc..4279169 100644 (file)
@@ -22,8 +22,9 @@
 #include <dali/public-api/object/property-buffer.h>     // Dali::Internal::PropertyBuffer
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/update/common/scene-graph-property-buffer.h>
+#include <dali/internal/update/manager/update-manager.h>
+// @todo MESH_REWORK remove this comment - Don't include "stage.h" - use GetEventThreadServices() instead.
 
 namespace Dali
 {
@@ -123,26 +124,53 @@ Property::Type PropertyBuffer::GetDefaultPropertyType( Property::Index index ) c
 }
 
 void PropertyBuffer::SetDefaultProperty( Property::Index index,
-                                   const Property::Value& propertyValue )
+                                         const Property::Value& propertyValue )
 {
-  PROPERTY_BUFFER_IMPL.SetDefaultProperty( index, propertyValue );
+  switch( index )
+  {
+    case Dali::PropertyBuffer::Property::SIZE:
+    {
+      SetSize( propertyValue.Get<int>() );
+      break;
+    }
+    case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
 }
 
 void PropertyBuffer::SetSceneGraphProperty( Property::Index index,
                                             const PropertyMetadata& entry,
                                             const Property::Value& value )
 {
-  PROPERTY_BUFFER_IMPL.SetSceneGraphProperty( index, entry, value );
+  PROPERTY_BUFFER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
 }
 
 Property::Value PropertyBuffer::GetDefaultProperty( Property::Index index ) const
 {
-  return PROPERTY_BUFFER_IMPL.GetDefaultProperty( index );
+  Property::Value value;
+
+  switch( index )
+  {
+    case Dali::PropertyBuffer::Property::SIZE:
+    {
+      value = static_cast<int>( GetSize() ); // @todo MESH_REWORK Add a size_t type to PropertyValue
+      break;
+    }
+    case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
+  return value;
 }
 
 const SceneGraph::PropertyOwner* PropertyBuffer::GetPropertyOwner() const
 {
-  return PROPERTY_BUFFER_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* PropertyBuffer::GetSceneObject() const
@@ -152,12 +180,50 @@ const SceneGraph::PropertyOwner* PropertyBuffer::GetSceneObject() const
 
 const SceneGraph::PropertyBase* PropertyBuffer::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return PROPERTY_BUFFER_IMPL.GetSceneObjectAnimatableProperty( index );
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty(
+      this,
+      &PropertyBuffer::FindAnimatableProperty,
+      &PropertyBuffer::FindCustomProperty,
+      index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
+    }
+  }
+
+  return property;
 }
 
 const PropertyInputImpl* PropertyBuffer::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return PROPERTY_BUFFER_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                            &PropertyBuffer::FindAnimatableProperty,
+                                                            &PropertyBuffer::FindCustomProperty,
+                                                            index );
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      if( index == Dali::PropertyBuffer::Property::SIZE )
+      {
+        // @todo MESH_REWORK
+        DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      }
+    }
+  }
+
+  return property;
 }
 
 int PropertyBuffer::GetPropertyComponentIndex( Property::Index index ) const
index be416e0..b0c2a2a 100644 (file)
@@ -188,8 +188,8 @@ public:
    * @param [in] newProperty A pointer to the scene-graph owned property.
    */
   CustomPropertyMetadata( const std::string& newName,
-                  Property::Type newType,
-                  const SceneGraph::PropertyBase* newProperty)
+                          Property::Type newType,
+                          const SceneGraph::PropertyBase* newProperty)
   : name(newName),
     mAccessMode(Property::ANIMATABLE)
   {
@@ -205,8 +205,8 @@ public:
    * @param [in] accessMode The access mode of the custom property (writable, animatable etc).
    */
   CustomPropertyMetadata( const std::string& newName,
-                  Property::Value newValue,
-                  Property::AccessMode accessMode )
+                          Property::Value newValue,
+                          Property::AccessMode accessMode )
   : name(newName),
     mAccessMode(accessMode)
   {
index 714c950..2da87a4 100644 (file)
@@ -22,7 +22,7 @@
 #include <dali/public-api/shader-effects/material.h> // Dali::Internal::Material
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/update/effects/scene-graph-material.h>
 #include <dali/internal/update/effects/scene-graph-sampler.h>
 #include <dali/internal/update/manager/update-manager.h>
 
@@ -213,24 +213,130 @@ Property::Type Material::GetDefaultPropertyType( Property::Index index ) const
 void Material::SetDefaultProperty( Property::Index index,
                                    const Property::Value& propertyValue )
 {
-  MATERIAL_IMPL.SetDefaultProperty( index, propertyValue );
+  switch( index )
+  {
+    case Dali::Material::Property::COLOR:
+    {
+      SceneGraph::PropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
+      break;
+    }
+    case Dali::Material::Property::FACE_CULLING_MODE:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_MODE:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLEND_EQUATION:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLEND_COLOR:
+    {
+      SceneGraph::PropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
+      break;
+    }
+  }
 }
 
 void Material::SetSceneGraphProperty( Property::Index index,
                                       const PropertyMetadata& entry,
                                       const Property::Value& value )
 {
-  MATERIAL_IMPL.SetSceneGraphProperty( index, entry, value );
+  MATERIAL_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
+  OnPropertySet(index, value);
 }
 
 Property::Value Material::GetDefaultProperty( Property::Index index ) const
 {
-  return MATERIAL_IMPL.GetDefaultProperty( index );
+  BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
+  Property::Value value;
+
+  switch( index )
+  {
+    case Dali::Material::Property::COLOR:
+    {
+      if( mSceneObject )
+      {
+        value = mSceneObject->mColor[bufferIndex];
+      }
+      break;
+    }
+    case Dali::Material::Property::FACE_CULLING_MODE:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_MODE:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLEND_EQUATION:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+      break;
+    }
+    case Dali::Material::Property::BLEND_COLOR:
+    {
+      if( mSceneObject )
+      {
+        value = mSceneObject->mBlendColor[bufferIndex];
+      }
+      break;
+    }
+  }
+
+  return value;
 }
 
 const SceneGraph::PropertyOwner* Material::GetPropertyOwner() const
 {
-  return MATERIAL_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* Material::GetSceneObject() const
@@ -240,17 +346,120 @@ const SceneGraph::PropertyOwner* Material::GetSceneObject() const
 
 const SceneGraph::PropertyBase* Material::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return MATERIAL_IMPL.GetSceneObjectAnimatableProperty( index );
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                              &Material::FindAnimatableProperty,
+                                                              &Material::FindCustomProperty,
+                                                              index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Material::Property::COLOR:
+        {
+          property = &mSceneObject->mColor;
+          break;
+        }
+        case Dali::Material::Property::BLEND_COLOR:
+        {
+          property = &mSceneObject->mBlendColor;
+          break;
+        }
+        default:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Property is not animatable");
+          break;
+        }
+      }
+    }
+  }
+
+  return property;
 }
 
 const PropertyInputImpl* Material::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return MATERIAL_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                     &Material::FindAnimatableProperty,
+                                                     &Material::FindCustomProperty,
+                                                     index );
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Material::Property::COLOR:
+        {
+          property = &mSceneObject->mColor;
+          break;
+        }
+        case Dali::Material::Property::FACE_CULLING_MODE:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLENDING_MODE:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLEND_EQUATION:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+          break;
+        }
+        case Dali::Material::Property::BLEND_COLOR:
+        {
+          property = &mSceneObject->mBlendColor;
+          break;
+        }
+        default:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
+          break;
+        }
+      }
+    }
+  }
+
+  return property;
 }
 
 int Material::GetPropertyComponentIndex( Property::Index index ) const
 {
-  return MATERIAL_IMPL.GetPropertyComponentIndex( index );
+  return Property::INVALID_COMPONENT_INDEX;
 }
 
 bool Material::OnStage() const
@@ -292,11 +501,23 @@ Material::Material()
 
 void Material::Initialize()
 {
-  StagePtr stage = Stage::GetCurrent();
-  DALI_ASSERT_ALWAYS( stage && "Stage doesn't exist" );
+  EventThreadServices& eventThreadServices = GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+
+  DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
 
   mSceneObject = new SceneGraph::Material();
-  AddMessage( stage->GetUpdateManager(), stage->GetUpdateManager().GetMaterialOwner(), *mSceneObject );
+  AddMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
+}
+
+Material::~Material()
+{
+  if( EventThreadServices::IsCoreRunning() )
+  {
+    EventThreadServices& eventThreadServices = GetEventThreadServices();
+    SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+    RemoveMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
+  }
 }
 
 } // namespace Internal
index 55fcdd7..ec32837 100644 (file)
@@ -248,6 +248,12 @@ private: // implementation
    */
   void Initialize();
 
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Material();
+
 private: // unimplemented methods
   Material( const Material& );
   Material& operator=( const Material& );
index 8c37f4d..8a27378 100644 (file)
@@ -22,7 +22,6 @@
 #include <dali/public-api/shader-effects/sampler.h> // Dali::Internal::Sampler
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/update/effects/scene-graph-sampler.h> // Dali::Internal::SceneGraph::Sampler
 #include <dali/internal/update/manager/update-manager.h>
 
@@ -136,26 +135,84 @@ Property::Type Sampler::GetDefaultPropertyType( Property::Index index ) const
 }
 
 void Sampler::SetDefaultProperty( Property::Index index,
-                                   const Property::Value& propertyValue )
+                                  const Property::Value& propertyValue )
 {
-  SAMPLER_IMPL.SetDefaultProperty( index, propertyValue );
+  switch( index )
+  {
+    case Dali::Sampler::Property::MINIFICATION_FILTER:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::MAGNIGICATION_FILTER:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::U_WRAP:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::V_WRAP:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::AFFECTS_TRANSPARENCY:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
 }
 
 void Sampler::SetSceneGraphProperty( Property::Index index,
                                      const PropertyMetadata& entry,
                                      const Property::Value& value )
 {
-  SAMPLER_IMPL.SetSceneGraphProperty( index, entry, value );
+  SAMPLER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
+  OnPropertySet(index, value);
 }
 
 Property::Value Sampler::GetDefaultProperty( Property::Index index ) const
 {
-  return SAMPLER_IMPL.GetDefaultProperty( index );
+  Property::Value value;
+
+  switch( index )
+  {
+    case Dali::Sampler::Property::MINIFICATION_FILTER:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::MAGNIGICATION_FILTER:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::U_WRAP:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::V_WRAP:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Sampler::Property::AFFECTS_TRANSPARENCY:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
+  return value;
 }
 
 const SceneGraph::PropertyOwner* Sampler::GetPropertyOwner() const
 {
-  return SAMPLER_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* Sampler::GetSceneObject() const
@@ -165,17 +222,79 @@ const SceneGraph::PropertyOwner* Sampler::GetSceneObject() const
 
 const SceneGraph::PropertyBase* Sampler::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return SAMPLER_IMPL.GetSceneObjectAnimatableProperty( index );
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = SAMPLER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                             &Sampler::FindAnimatableProperty,
+                                                             &Sampler::FindCustomProperty,
+                                                             index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      // No animatable default props
+      DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
+    }
+  }
+
+  return property;
 }
 
 const PropertyInputImpl* Sampler::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return SAMPLER_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      SAMPLER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                    &Sampler::FindAnimatableProperty,
+                                                    &Sampler::FindCustomProperty,
+                                                    index );
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch( index )
+      {
+        case Dali::Sampler::Property::MINIFICATION_FILTER:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        case Dali::Sampler::Property::MAGNIGICATION_FILTER:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        case Dali::Sampler::Property::U_WRAP:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        case Dali::Sampler::Property::V_WRAP:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        case Dali::Sampler::Property::AFFECTS_TRANSPARENCY:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+      }
+    }
+  }
+
+  return property;
 }
 
 int Sampler::GetPropertyComponentIndex( Property::Index index ) const
 {
-  return SAMPLER_IMPL.GetPropertyComponentIndex( index );
+  return Property::INVALID_COMPONENT_INDEX;
 }
 
 bool Sampler::OnStage() const
@@ -205,13 +324,24 @@ Sampler::Sampler()
 
 void Sampler::Initialize( const std::string& textureUnitUniformName )
 {
-  StagePtr stage = Stage::GetCurrent();
-  DALI_ASSERT_ALWAYS( stage && "Stage doesn't exist" );
+  EventThreadServices& eventThreadServices = GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+
+  DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
 
   mSceneObject = new SceneGraph::Sampler( textureUnitUniformName );
-  AddMessage( stage->GetUpdateManager(), stage->GetUpdateManager().GetSamplerOwner(), *mSceneObject );
+  AddMessage( updateManager, updateManager.GetSamplerOwner(), *mSceneObject );
 }
 
+Sampler::~Sampler()
+{
+  if( EventThreadServices::IsCoreRunning() )
+  {
+    EventThreadServices& eventThreadServices = GetEventThreadServices();
+    SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+    RemoveMessage( updateManager, updateManager.GetSamplerOwner(), *mSceneObject );
+  }
+}
 
 } // namespace Internal
 } // namespace Dali
index c4bb1d3..9cb2347 100644 (file)
@@ -191,6 +191,11 @@ private:
    */
   void Initialize( const std::string& textureUnitUniformName );
 
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Sampler();
 
 private: // data
   //TODO: MESH_REWORK : change to ObjectConnector
index 8efe3df..6b581cb 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
+
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/effects/shader-factory.h>
 #include <dali/internal/event/resources/resource-ticket.h>
@@ -108,24 +108,54 @@ Property::Type Shader::GetDefaultPropertyType( Property::Index index ) const
 void Shader::SetDefaultProperty( Property::Index index,
                                  const Property::Value& propertyValue )
 {
-  SHADER_IMPL.SetDefaultProperty( index, propertyValue );
+  switch(index)
+  {
+    case Dali::Shader::Property::PROGRAM:
+    {
+      // @todo MESH_REWORK Set program again?
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Shader::Property::SHADER_HINTS:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
 }
 
 void Shader::SetSceneGraphProperty( Property::Index index,
                                     const PropertyMetadata& entry,
                                     const Property::Value& value )
 {
-  SHADER_IMPL.SetSceneGraphProperty( index, entry, value );
+  SHADER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
+  OnPropertySet(index, value);
 }
 
 Property::Value Shader::GetDefaultProperty( Property::Index index ) const
 {
-  return SHADER_IMPL.GetDefaultProperty( index );
+  Property::Value value;
+
+  switch(index)
+  {
+    case Dali::Shader::Property::PROGRAM:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Shader::Property::SHADER_HINTS:
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
+
+  return value;
 }
 
 const SceneGraph::PropertyOwner* Shader::GetPropertyOwner() const
 {
-  return SHADER_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* Shader::GetSceneObject() const
@@ -135,12 +165,52 @@ const SceneGraph::PropertyOwner* Shader::GetSceneObject() const
 
 const SceneGraph::PropertyBase* Shader::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return SHADER_IMPL.GetSceneObjectAnimatableProperty( index );
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = SHADER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                            &Shader::FindAnimatableProperty,
+                                                            &Shader::FindCustomProperty,
+                                                            index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
+    }
+  }
+
+  return property;
 }
 
 const PropertyInputImpl* Shader::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return SHADER_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      SHADER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                   &Shader::FindAnimatableProperty,
+                                                   &Shader::FindCustomProperty,
+                                                   index );
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      if( index == Dali::Shader::Property::SHADER_HINTS )
+      {
+        // @todo MESH_REWORK - return the property
+      }
+      else
+      {
+        DALI_ASSERT_ALWAYS( 0 && "Property is not a valid constraint input" );
+      }
+    }
+  }
+
+  return property;
 }
 
 int Shader::GetPropertyComponentIndex( Property::Index index ) const
@@ -171,14 +241,14 @@ Shader::Shader()
 
 void Shader::Initialize( const std::string& vertexSource, const std::string& fragmentSource )
 {
-  StagePtr stage = Stage::GetCurrent();
-  DALI_ASSERT_ALWAYS( stage && "Stage doesn't exist" );
+  DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
+  EventThreadServices& eventThreadServices = GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
 
   Dali::ShaderEffect::GeometryHints hint = Dali::ShaderEffect::HINT_NONE;
   mSceneObject = new SceneGraph::Shader(hint);
 
   // Add to update manager
-  SceneGraph::UpdateManager& updateManager = stage->GetUpdateManager();
   AddShaderMessage( updateManager, *mSceneObject );
 
   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
@@ -189,8 +259,18 @@ void Shader::Initialize( const std::string& vertexSource, const std::string& fra
 
   // Add shader program to scene-object using a message to the UpdateManager
   SetShaderProgramMessage( updateManager, *mSceneObject, GEOMETRY_TYPE_IMAGE, SHADER_SUBTYPE_ALL, mTicket->GetId(), shaderHash, false );
+}
 
+Shader::~Shader()
+{
+  if( EventThreadServices::IsCoreRunning() )
+  {
+    EventThreadServices& eventThreadServices = GetEventThreadServices();
+    SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+    RemoveShaderMessage( updateManager, *mSceneObject);
+  }
 }
 
+
 } // namespace Internal
 } // namespace Dali
index 8d85990..ec50176 100644 (file)
@@ -167,6 +167,12 @@ private: // implementation
    */
   void Initialize( const std::string& vertexShader, const std::string& fragmentShader );
 
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Shader();
+
 private: // unimplemented methods
   Shader( const Shader& );
   Shader& operator=( const Shader& );
index 31d068e..0a55826 100644 (file)
@@ -21,7 +21,6 @@
 // INTERNAL INCLUDES
 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/update/manager/update-manager.h>
 
 namespace Dali
@@ -149,24 +148,83 @@ Property::Type Geometry::GetDefaultPropertyType( Property::Index index ) const
 void Geometry::SetDefaultProperty( Property::Index index,
                                    const Property::Value& propertyValue )
 {
-  GEOMETRY_IMPL.SetDefaultProperty( index, propertyValue );
+  switch( index )
+  {
+    case Dali::Geometry::Property::GEOMETRY_TYPE :
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Geometry::Property::GEOMETRY_CENTER :
+    {
+      SceneGraph::PropertyMessage<Vector3>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mCenter, &SceneGraph::AnimatableProperty<Vector3>::Bake, propertyValue.Get<Vector3>() );
+      break;
+    }
+
+    case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
+    {
+      SceneGraph::PropertyMessage<Vector3>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mHalfExtents, &SceneGraph::AnimatableProperty<Vector3>::Bake, propertyValue.Get<Vector3>() );
+      break;
+    }
+
+    case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
 }
 
 void Geometry::SetSceneGraphProperty( Property::Index index,
                                       const PropertyMetadata& entry,
                                       const Property::Value& value )
 {
-  GEOMETRY_IMPL.SetSceneGraphProperty( index, entry, value );
+  GEOMETRY_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
 }
 
 Property::Value Geometry::GetDefaultProperty( Property::Index index ) const
 {
-  return GEOMETRY_IMPL.GetDefaultProperty( index );
+  BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
+  Property::Value value;
+
+  switch( index )
+  {
+    case Dali::Geometry::Property::GEOMETRY_TYPE :
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+    case Dali::Geometry::Property::GEOMETRY_CENTER :
+    {
+      if( mSceneObject )
+      {
+        value = mSceneObject->mCenter[bufferIndex];
+      }
+      break;
+    }
+
+    case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
+    {
+      if( mSceneObject )
+      {
+        value = mSceneObject->mHalfExtents[bufferIndex];
+      }
+      break;
+    }
+
+    case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
+    {
+      DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+      break;
+    }
+  }
+
+  return value;
 }
 
 const SceneGraph::PropertyOwner* Geometry::GetPropertyOwner() const
 {
-  return GEOMETRY_IMPL.GetPropertyOwner();
+  return mSceneObject;
 }
 
 const SceneGraph::PropertyOwner* Geometry::GetSceneObject() const
@@ -176,12 +234,88 @@ const SceneGraph::PropertyOwner* Geometry::GetSceneObject() const
 
 const SceneGraph::PropertyBase* Geometry::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  return GEOMETRY_IMPL.GetSceneObjectAnimatableProperty( index );
+  const SceneGraph::PropertyBase* property = NULL;
+
+  if( OnStage() )
+  {
+    property = GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
+                                                               &Geometry::FindAnimatableProperty,
+                                                               &Geometry::FindCustomProperty,
+                                                               index );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Geometry::Property::GEOMETRY_CENTER :
+        {
+          property = &mSceneObject->mCenter;
+          break;
+        }
+        case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
+        {
+          property = &mSceneObject->mHalfExtents;
+          break;
+        }
+        default:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
+          break;
+        }
+      }
+    }
+  }
+  return property;
 }
 
 const PropertyInputImpl* Geometry::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  return GEOMETRY_IMPL.GetSceneObjectInputProperty( index );
+  const PropertyInputImpl* property = NULL;
+
+  if( OnStage() )
+  {
+    const SceneGraph::PropertyBase* baseProperty =
+      GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
+                                                      &Geometry::FindAnimatableProperty,
+                                                      &Geometry::FindCustomProperty,
+                                                      index );
+
+    property = static_cast<const PropertyInputImpl*>( baseProperty );
+
+    if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
+    {
+      switch(index)
+      {
+        case Dali::Geometry::Property::GEOMETRY_TYPE :
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        case Dali::Geometry::Property::GEOMETRY_CENTER :
+        {
+          property = &mSceneObject->mCenter;
+          break;
+        }
+        case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
+        {
+          property = &mSceneObject->mHalfExtents;
+          break;
+        }
+        case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
+        {
+          DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
+          break;
+        }
+        default:
+        {
+          DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
+          break;
+        }
+      }
+    }
+  }
+
+  return property;
 }
 
 int Geometry::GetPropertyComponentIndex( Property::Index index ) const
@@ -230,11 +364,24 @@ Geometry::Geometry()
 
 void Geometry::Initialize()
 {
-  StagePtr stage = Stage::GetCurrent();
-  DALI_ASSERT_ALWAYS( stage && "Stage doesn't exist" );
+  EventThreadServices& eventThreadServices = GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+
+  DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
 
   mSceneObject = new SceneGraph::Geometry();
-  SceneGraph::AddMessage( stage->GetUpdateManager(), stage->GetUpdateManager().GetGeometryOwner(), *mSceneObject );
+  AddMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
+}
+
+Geometry::~Geometry()
+{
+  if( EventThreadServices::IsCoreRunning() )
+  {
+    EventThreadServices& eventThreadServices = GetEventThreadServices();
+    SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+
+    RemoveMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
+  }
 }
 
 
index db14c19..fc39a4d 100644 (file)
@@ -209,6 +209,12 @@ private: // implementation
    */
   void Initialize();
 
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Geometry();
+
 private: // unimplemented methods
   Geometry( const Geometry& );
   Geometry& operator=( const Geometry& );
index 93eb733..b089883 100644 (file)
@@ -161,13 +161,16 @@ internal_src_files = \
   $(internal_src_dir)/update/animation/scene-graph-constraint-base.cpp \
   $(internal_src_dir)/update/common/discard-queue.cpp \
   $(internal_src_dir)/update/common/property-base.cpp \
-  $(internal_src_dir)/update/common/scene-graph-property-buffer.cpp \
+  $(internal_src_dir)/update/common/property-owner-messages.cpp \
   $(internal_src_dir)/update/common/property-condition-functions.cpp \
   $(internal_src_dir)/update/common/property-condition-step-functions.cpp \
   $(internal_src_dir)/update/common/property-condition-variable-step-functions.cpp \
   $(internal_src_dir)/update/common/property-owner.cpp \
   $(internal_src_dir)/update/common/scene-graph-buffers.cpp \
+  $(internal_src_dir)/update/common/scene-graph-connection-observers.cpp \
+  $(internal_src_dir)/update/common/scene-graph-property-buffer.cpp \
   $(internal_src_dir)/update/common/scene-graph-property-notification.cpp \
+  $(internal_src_dir)/update/common/uniform-map.cpp \
   $(internal_src_dir)/update/controllers/render-message-dispatcher.cpp \
   $(internal_src_dir)/update/controllers/scene-controller-impl.cpp \
   $(internal_src_dir)/update/effects/scene-graph-material.cpp \
diff --git a/dali/internal/render/data-providers/uniform-map-data-provider.h b/dali/internal/render/data-providers/uniform-map-data-provider.h
new file mode 100644 (file)
index 0000000..e5610a5
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_DATA_PROVIDER_H
+#define DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_DATA_PROVIDER_H
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/integration-api/resource-declarations.h>
+#include <dali/internal/common/buffer-index.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+class UniformMap;
+class UniformPropertyMapping;
+
+typedef Dali::Vector< const UniformPropertyMapping* > CollectedUniformMap;
+
+/**
+ * This class maps uniform names to property value pointers.
+ */
+class UniformMapDataProvider
+{
+public:
+  /**
+   * Constructor
+   */
+  UniformMapDataProvider()
+  {
+  }
+
+  /**
+   * Return true if the uniform map has been changed this frame
+   * Note, this only informs if the uniform mappings have changed,
+   * not if any actual property value has changed.
+   *
+   * @param[in] bufferIndex The buffer index
+   * @return true if the uniform map has changed
+   */
+  virtual bool GetUniformMapChanged( BufferIndex bufferIndex ) const = 0;
+
+  /**
+   * Get the complete map of uniforms to property value addresses
+   * @param[in] bufferIndex The bufferIndex
+   * @return the uniform map
+   */
+  virtual const CollectedUniformMap& GetUniformMap( BufferIndex bufferIndex ) const = 0;
+
+protected:
+  /**
+   * No deletion through this interface
+   */
+  virtual ~UniformMapDataProvider()
+  {
+  }
+};
+
+} // namespace SceneGraph
+} // namespace Internal
+} // namespace Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_DATA_PROVIDER_H
index c06fe7c..c350fe1 100644 (file)
@@ -97,22 +97,23 @@ void RenderGeometry::DoUpload(
   BufferIndex bufferIndex,
   const GeometryDataProvider& geometry)
 {
-  // @todo MESH_REWORK Add support for multiple vertex buffers and attrs
-
   // Vertex buffer
   const Geometry::VertexBuffers& vertexBuffers = geometry.GetVertexBuffers();
   DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" );
 
-  PropertyBuffer* firstVertexBuffer = vertexBuffers[0];
+  for( unsigned int i=0; i<vertexBuffers.Count(); ++i)
+  {
+    PropertyBuffer* vertexBuffer = vertexBuffers[i];
 
-  // @todo MESH_REWORK STATIC_DRAW or DYNAMIC_DRAW depends on property buffer type (static / animated)
-  GpuBuffer* vertexGpuBuffer = new GpuBuffer( *context, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
+    // @todo MESH_REWORK STATIC_DRAW or DYNAMIC_DRAW depends on property buffer type (static / animated)
+    GpuBuffer* vertexGpuBuffer = new GpuBuffer( *context, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
 
-  std::size_t dataSize = firstVertexBuffer->GetDataSize( bufferIndex );
-  vertexGpuBuffer->UpdateDataBuffer( dataSize, firstVertexBuffer->GetData( bufferIndex ) );
-  vertexGpuBuffer->SetStride( firstVertexBuffer->GetElementSize( bufferIndex ) );
+    std::size_t dataSize = vertexBuffer->GetDataSize( bufferIndex );
+    vertexGpuBuffer->UpdateDataBuffer( dataSize, vertexBuffer->GetData( bufferIndex ) );
+    vertexGpuBuffer->SetStride( vertexBuffer->GetElementSize( bufferIndex ) );
 
-  mVertexBuffers.PushBack( vertexGpuBuffer );
+    mVertexBuffers.PushBack( vertexGpuBuffer );
+  }
 
   // Index buffer
   const PropertyBuffer* indexBuffer = geometry.GetIndexBuffer();
@@ -120,7 +121,7 @@ void RenderGeometry::DoUpload(
   {
     GpuBuffer* indexGpuBuffer = new GpuBuffer( *context, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
 
-    dataSize = indexBuffer->GetDataSize( bufferIndex );
+    unsigned int dataSize = indexBuffer->GetDataSize( bufferIndex );
     indexGpuBuffer->UpdateDataBuffer( dataSize, indexBuffer->GetData( bufferIndex ) );
 
     mIndexBuffer.Reset();
index 7a807de..8b3672a 100644 (file)
@@ -17,6 +17,9 @@
 #include "render-renderer.h"
 
 #include <dali/internal/common/image-sampler.h>
+#include <dali/internal/event/common/property-input-impl.h>
+#include <dali/internal/update/common/uniform-map.h>
+#include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/render/data-providers/geometry-data-provider.h>
 #include <dali/internal/render/data-providers/material-data-provider.h>
 #include <dali/internal/render/data-providers/node-data-provider.h>
@@ -34,17 +37,20 @@ namespace SceneGraph
 {
 
 NewRenderer* NewRenderer::New( NodeDataProvider& nodeDataProvider,
+                               const UniformMapDataProvider& uniformMapDataProvider,
                                const GeometryDataProvider* geometryDataProvider,
                                const MaterialDataProvider* materialDataProvider)
 {
-  return new NewRenderer(nodeDataProvider, geometryDataProvider, materialDataProvider);
+  return new NewRenderer(nodeDataProvider, uniformMapDataProvider, geometryDataProvider, materialDataProvider);
 }
 
 
 NewRenderer::NewRenderer( NodeDataProvider& nodeDataProvider,
+                          const UniformMapDataProvider& uniformMapDataProvider,
                           const GeometryDataProvider* geometryDataProvider,
                           const MaterialDataProvider* materialDataProvider)
 : Renderer( nodeDataProvider ),
+  mUniformMapDataProvider( uniformMapDataProvider ),
   //mShaderDataProvider( shaderDataProvider ), //@todo Add in after merge with parent class
   mMaterialDataProvider( materialDataProvider ),
   mGeometryDataProvider( geometryDataProvider )
@@ -60,6 +66,7 @@ NewRenderer::~NewRenderer()
 void NewRenderer::SetGeometryDataProvider( const GeometryDataProvider* geometryDataProvider )
 {
   mGeometryDataProvider = geometryDataProvider;
+  mRenderGeometry.GeometryUpdated();
 }
 
 void NewRenderer::SetMaterialDataProvider( const MaterialDataProvider* materialDataProvider )
@@ -99,6 +106,12 @@ bool NewRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& m
   return false;
 }
 
+void NewRenderer::DoSetUniforms( Shader* shader, Context* context, Program* program, BufferIndex bufferIndex, unsigned int programIndex, ShaderSubTypes subType )
+{
+  // Do nothing, we're going to set up the uniforms with our own code instead
+}
+
+
 void NewRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix )
 {
   BindTextures( bufferIndex, program, mMaterialDataProvider->GetSamplers() );
@@ -119,9 +132,35 @@ void NewRenderer::GlCleanup()
 
 void NewRenderer::SetUniforms( BufferIndex bufferIndex, Program& program )
 {
-  // @todo MESH_REWORK Implement uniform map
+  // Check if the map has changed
+  if( mUniformMapDataProvider.GetUniformMapChanged( bufferIndex ) )
+  {
+    const CollectedUniformMap& uniformMap = mUniformMapDataProvider.GetUniformMap( bufferIndex );
+
+    unsigned int numberOfMaps = uniformMap.Count();
+    mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
+    mUniformIndexMap.Resize( numberOfMaps );
+
+    // Remap uniform indexes to property value addresses
+
+    for( unsigned int mapIndex = 0 ; mapIndex < numberOfMaps ; ++mapIndex )
+    {
+      mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr;
+      mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName );
+    }
+  }
+
+  // Set uniforms in local map
+  for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
+         end = mUniformIndexMap.End() ;
+       iter != end ;
+       ++iter )
+  {
+    SetUniformFromProperty( bufferIndex, program, *iter );
+  }
+
+  // @todo MESH_REWORK On merge, copy code from renderer to setup standard matrices and color
 
-  // @todo Base class is currently setting MVP, Color etc.
   GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE );
   if( -1 != sizeLoc )
   {
@@ -130,6 +169,75 @@ void NewRenderer::SetUniforms( BufferIndex bufferIndex, Program& program )
   }
 }
 
+void NewRenderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map )
+{
+  GLint location = program.GetUniformLocation(map.uniformIndex);
+  if( Program::UNIFORM_UNKNOWN != location )
+  {
+    // switch based on property type to use correct GL uniform setter
+    switch ( map.propertyValue->GetType() )
+    {
+      case Property::INTEGER:
+      {
+        program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) );
+        break;
+      }
+      case Property::FLOAT:
+      {
+        program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) );
+        break;
+      }
+      case Property::VECTOR2:
+      {
+        Vector2 value( map.propertyValue->GetVector2( bufferIndex ) );
+        program.SetUniform2f( location, value.x, value.y );
+        break;
+      }
+
+      case Property::VECTOR3:
+      {
+        Vector3 value( map.propertyValue->GetVector3( bufferIndex ) );
+        program.SetUniform3f( location, value.x, value.y, value.z );
+        break;
+      }
+
+      case Property::VECTOR4:
+      {
+        Vector4 value( map.propertyValue->GetVector4( bufferIndex ) );
+        program.SetUniform4f( location, value.x, value.y, value.z, value.w );
+        break;
+      }
+
+      case Property::ROTATION:
+      {
+        Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) );
+        program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w );
+        break;
+      }
+
+      case Property::MATRIX:
+      {
+        const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
+        program.SetUniformMatrix4fv(location, 1, value.AsFloat() );
+        break;
+      }
+
+      case Property::MATRIX3:
+      {
+        const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
+        program.SetUniformMatrix3fv(location, 1, value.AsFloat() );
+        break;
+      }
+
+      default:
+      {
+        // Other property types are ignored
+        break;
+      }
+    }
+  }
+}
+
 void NewRenderer::BindTextures(
   BufferIndex bufferIndex,
   Program& program,
index 20e6c84..8ce5c76 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <dali/integration-api/resource-declarations.h> // For resource id
 #include <dali/internal/render/data-providers/material-data-provider.h>
+#include <dali/internal/render/data-providers/uniform-map-data-provider.h>
 #include <dali/internal/render/gl-resources/texture-units.h>
 #include <dali/internal/render/renderers/scene-graph-renderer.h>
 #include <dali/internal/render/renderers/render-geometry.h>
@@ -28,14 +29,17 @@ namespace Dali
 {
 namespace Internal
 {
+class PropertyInputImpl;
+
 namespace SceneGraph
 {
-class NodeDataProvider;
-class ShaderDataProvider;
-class SamplerDataProvider;
-class MaterialDataProvider;
 class GeometryDataProvider;
+class MaterialDataProvider;
+class NodeDataProvider;
 class RenderGeometry;
+class SamplerDataProvider;
+class ShaderDataProvider;
+class UniformMapDataProvider;
 
 /**
  * The new geometry renderer.
@@ -44,25 +48,32 @@ class RenderGeometry;
  */
 class NewRenderer : public Renderer
 {
+private:
+  struct UniformIndexMap;
+
 public:
   typedef Integration::ResourceId ResourceId;
 
   /**
    * Create a new renderer instance
    * @param[in] nodeDataProvider The node data provider
-   * @param[in] geoemtryDataProvider The geometry data provider
+   * @param[in] uniformMapDataProvider The uniform map data provider
+   * @param[in] geometryDataProvider The geometry data provider
    * @param[in] materialDataProvider The material data provider
    */
   static NewRenderer* New( NodeDataProvider& nodeDataProvider,
+                           const UniformMapDataProvider& uniformMapDataProvider,
                            const GeometryDataProvider* geometryDataProvider,
                            const MaterialDataProvider* materialDataProvider );
   /**
    * Constructor.
    * @param[in] nodeDataProvider The node data provider
-   * @param[in] geoemtryDataProvider The geometry data provider
+   * @param[in] uniformMapDataProvider The uniform map data provider
+   * @param[in] geometryDataProvider The geometry data provider
    * @param[in] materialDataProvider The material data provider
    */
   NewRenderer( NodeDataProvider& nodeDataProvider,
+               const UniformMapDataProvider& uniformMapDataProvider,
                const GeometryDataProvider* geometryDataProvider,
                const MaterialDataProvider* materialDataProvider );
 
@@ -105,6 +116,11 @@ public: // Implementation of Renderer
                                    const Matrix& modelViewProjectionMatrix );
 
   /**
+   * @copydoc SceneGraph::Renderer::DoSetUniforms()
+   */
+  virtual void DoSetUniforms(Shader* shader, Context* context, Program* program, BufferIndex bufferIndex, unsigned int programIndex, ShaderSubTypes subType );
+
+  /**
    * @copydoc SceneGraph::Renderer::DoRender()
    */
   virtual void DoRender( BufferIndex bufferIndex,
@@ -132,6 +148,11 @@ private:
   void SetUniforms( BufferIndex bufferIndex, Program& program );
 
   /**
+   * Set the program uniform in the map from the mapped property
+   */
+  void SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map );
+
+  /**
    * Bind the material textures in the samplers and setup the samplers
    * @param[in] bufferIndex The buffer index
    * @param[in] program The shader program
@@ -183,6 +204,7 @@ public:
   // @todo MESH_REWORK Make private - add getters
   //const NodeDataProvider&     mNodeDataProvider;
   //const ShaderDataProvider&   mShaderDataProvider;
+  const UniformMapDataProvider& mUniformMapDataProvider;
   const MaterialDataProvider* mMaterialDataProvider;
   const GeometryDataProvider* mGeometryDataProvider;
 
@@ -198,6 +220,15 @@ private:
 
   typedef Dali::Vector< TextureUnitUniformIndex > TextureUnitUniforms;
   TextureUnitUniforms mTextureUnitUniforms;
+
+  struct UniformIndexMap
+  {
+    unsigned int uniformIndex; // The index of the cached location in the Program
+    const PropertyInputImpl* propertyValue;
+  };
+
+  typedef Dali::Vector< UniformIndexMap > UniformIndexMappings;
+  UniformIndexMappings mUniformIndexMap;
 };
 
 
index 5ef9b9d..5041c94 100644 (file)
@@ -254,13 +254,18 @@ void Renderer::Render( BufferIndex bufferIndex,
     program->SetUniform1f( loc, frametime );
   }
 
-  // set custom uniforms
-  mShader->SetUniforms( *mContext, *program, bufferIndex, programIndex, subType );
+  DoSetUniforms(mShader, mContext, program, bufferIndex, programIndex, subType );
 
   // subclass rendering and actual draw call
   DoRender( bufferIndex, *program, modelViewMatrix, viewMatrix );
 }
 
+// can be overridden by deriving class
+void Renderer::DoSetUniforms(Shader* shader, Context* context, Program* program, BufferIndex bufferIndex, unsigned int programIndex, ShaderSubTypes subType )
+{
+  shader->SetUniforms( *context, *program, bufferIndex, programIndex, subType );
+}
+
 Renderer::Renderer( NodeDataProvider& dataprovider )
 : mDataProvider( dataprovider ),
   mContext( NULL ),
index 843c56b..3d54d25 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/public-api/math/vector4.h>
 #include <dali/internal/common/blending-options.h>
 #include <dali/internal/common/message.h>
+#include <dali/internal/event/effects/shader-declarations.h>
 #include <dali/internal/render/gl-resources/gl-resource-owner.h>
 #include <dali/internal/render/renderers/scene-graph-renderer-declarations.h>
 #include <dali/integration-api/debug.h>
@@ -168,6 +169,12 @@ private:
   virtual bool IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix ) = 0;
 
   /**
+   * Called from Render prior to DoRender().
+   * @todo MESH_REWORK Remove after merge
+   */
+  virtual void DoSetUniforms(Shader* shader, Context* context, Program* program, BufferIndex bufferIndex, unsigned int programIndex, ShaderSubTypes subType );
+
+  /**
    * Called from Render; implemented in derived classes.
    * @param[in] bufferIndex The index of the previous update buffer.
    * @param[in] program to use.
index 0e68aca..f08e8af 100644 (file)
@@ -133,6 +133,34 @@ void DiscardQueue::Add( BufferIndex updateBufferIndex, Shader* shader )
   }
 }
 
+void DiscardQueue::Add( BufferIndex updateBufferIndex, Sampler* sampler )
+{
+  DALI_ASSERT_DEBUG( NULL != sampler );
+
+  if ( 0u == updateBufferIndex )
+  {
+    mSamplerQueue0.PushBack( sampler );
+  }
+  else
+  {
+    mSamplerQueue1.PushBack( sampler );
+  }
+}
+
+void DiscardQueue::Add( BufferIndex updateBufferIndex, PropertyBuffer* propertyBuffer )
+{
+  DALI_ASSERT_DEBUG( NULL != propertyBuffer );
+
+  if ( 0u == updateBufferIndex )
+  {
+    mPropertyBufferQueue0.PushBack( propertyBuffer );
+  }
+  else
+  {
+    mPropertyBufferQueue1.PushBack( propertyBuffer );
+  }
+}
+
 void DiscardQueue::Clear( BufferIndex updateBufferIndex )
 {
   // Destroy some discarded objects; these should no longer own any GL resources
@@ -144,6 +172,8 @@ void DiscardQueue::Clear( BufferIndex updateBufferIndex )
     mShaderQueue0.Clear();
     mGeometryQueue0.Clear();
     mMaterialQueue0.Clear();
+    mSamplerQueue0.Clear();
+    mPropertyBufferQueue0.Clear();
   }
   else
   {
@@ -152,6 +182,8 @@ void DiscardQueue::Clear( BufferIndex updateBufferIndex )
     mShaderQueue1.Clear();
     mGeometryQueue1.Clear();
     mMaterialQueue1.Clear();
+    mSamplerQueue1.Clear();
+    mPropertyBufferQueue1.Clear();
   }
 }
 
index 56bd2db..c4c66d9 100644 (file)
 #include <dali/internal/common/owner-container.h>
 #include <dali/internal/update/nodes/node-declarations.h>
 #include <dali/internal/update/node-attachments/node-attachment-declarations.h>
+#include <dali/internal/update/common/scene-graph-property-buffer.h>
 #include <dali/internal/update/geometry/scene-graph-geometry.h>
 #include <dali/internal/update/effects/scene-graph-material.h>
+#include <dali/internal/update/effects/scene-graph-sampler.h>
 
 namespace Dali
 {
@@ -42,6 +44,7 @@ class Node;
 class RenderQueue;
 class Shader;
 
+
 /**
  * DiscardQueue is used to cleanup nodes & resources when no longer in use.
  * Unwanted objects are added here during UpdateManager::Update().
@@ -56,6 +59,8 @@ public:
   typedef OwnerContainer< Shader* > ShaderQueue;
   typedef OwnerContainer< Geometry* > GeometryQueue;
   typedef OwnerContainer< Material* > MaterialQueue;
+  typedef OwnerContainer< Sampler* > SamplerQueue;
+  typedef OwnerContainer< PropertyBuffer* > PropertyBufferQueue;
 
   /**
    * Create a new DiscardQueue.
@@ -96,9 +101,21 @@ public:
    * Adds an unwanted material to the discard queue.
    * A message will be sent to clean up GL resources in the next Render.
    */
+  void Add( BufferIndex updateBufferIndex, PropertyBuffer* material );
+
+  /**
+   * Adds an unwanted material to the discard queue.
+   * A message will be sent to clean up GL resources in the next Render.
+   */
   void Add( BufferIndex updateBufferIndex, Material* material );
 
   /**
+   * Adds an unwanted material to the discard queue.
+   * A message will be sent to clean up GL resources in the next Render.
+   */
+  void Add( BufferIndex updateBufferIndex, Sampler* material );
+
+  /**
    * Adds an unwanted shader to the discard queue.
    * A message will be sent to clean-up GL resources in the next Render.
    * @pre This method is not thread-safe, and should only be called from the update-thread.
@@ -132,6 +149,8 @@ private:
   ShaderQueue                  mShaderQueue0;
   GeometryQueue                mGeometryQueue0;
   MaterialQueue                mMaterialQueue0;
+  SamplerQueue                 mSamplerQueue0;
+  PropertyBufferQueue          mPropertyBufferQueue0;
 
   // Messages are queued here when the update buffer index == 1
   NodeOwnerContainer           mNodeQueue1;
@@ -139,6 +158,8 @@ private:
   ShaderQueue                  mShaderQueue1;
   GeometryQueue                mGeometryQueue1;
   MaterialQueue                mMaterialQueue1;
+  SamplerQueue                 mSamplerQueue1;
+  PropertyBufferQueue          mPropertyBufferQueue1;
 };
 
 } // namespace SceneGraph
@@ -1,6 +1,3 @@
-#ifndef DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H
-#define DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H
-
 /*
  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
  */
 
-#include <dali/integration-api/resource-declarations.h>
-#include <dali/internal/common/buffer-index.h>
+// CLASS HEADER
+#include <dali/internal/update/common/property-owner-messages.h>
 
 namespace Dali
 {
+
 namespace Internal
 {
+
 namespace SceneGraph
 {
 
-/**
- * This class maps uniform names to property value pointers.
- * After the first string lookup, it caches the uniform location to avoid
- * further lookups.
- */
-class UniformMapProvider
+// Messages for a property owner
+
+PropertyMessageBase::PropertyMessageBase()
 {
-public:
-  /**
-   * Constructor
-   */
-  UniformMapProvider()
-  {
-  }
-
-  // @todo Force material color?
-
-protected:
-
-  /**
-   * No deletion through this interface
-   */
-  virtual ~UniformMapProvider()
-  {
-  }
-};
+}
+
+PropertyMessageBase::~PropertyMessageBase()
+{
+}
 
 } // namespace SceneGraph
+
 } // namespace Internal
-} // namespace Dali
 
-#endif // DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H
+} // namespace Dali
index d7f69ae..fe2045f 100644 (file)
  */
 
 // INTERNAL INCLUDES
+
 #include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/event/common/property-input-impl.h>
 #include <dali/internal/update/common/property-owner.h>
+#include <dali/internal/update/animation/scene-graph-constraint-base.h>
+#include <string>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace SceneGraph
 {
+class UniformMap;
+class PropertyOwner;
+
+// Property Messages for PropertyOwner
+
+class PropertyMessageBase : public MessageBase
+{
+public:
+
+  /**
+   * Create a message.
+   */
+  PropertyMessageBase();
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~PropertyMessageBase();
+
+private:
+
+  // Undefined
+  PropertyMessageBase(const PropertyMessageBase&);
+  PropertyMessageBase& operator=(const PropertyMessageBase& rhs);
+};
+
+/**
+ * Templated message which bakes a property.
+ */
+template< typename P >
+class PropertyMessage : public PropertyMessageBase
+{
+public:
+
+  typedef void(AnimatableProperty<P>::*MemberFunction)( BufferIndex, typename ParameterType< P >::PassingType );
+
+  /**
+   * Create a message.
+   * @note The scene object is expected to be const in the thread which sends this message.
+   * However it can be modified when Process() is called in a different thread.
+   * @param[in] updateManager The update-manager.
+   * @param[in] sceneObject The property owner scene object
+   * @param[in] property The property to bake.
+   * @param[in] member The member function of the object.
+   * @param[in] value The new value of the property.
+   */
+  static void Send( EventThreadServices& eventThreadServices,
+                    const PropertyOwner* sceneObject,
+                    const AnimatableProperty<P>* property,
+                    MemberFunction member,
+                    typename ParameterType< P >::PassingType value )
+  {
+    // Reserve some memory inside the message queue
+    unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( PropertyMessage ) );
+
+    // Construct message in the message queue memory; note that delete should not be called on the return value
+    new (slot) PropertyMessage( sceneObject, property, member, value );
+  }
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~PropertyMessage()
+  {
+  }
+
+  /**
+   * @copydoc MessageBase::Process
+   */
+  virtual void Process( BufferIndex updateBufferIndex )
+  {
+    (mProperty->*mMemberFunction)( updateBufferIndex, mParam );
+  }
+
+private:
+
+  /**
+   * Create a message.
+   * @note The property owner is expected to be const in the thread which sends this message.
+   * However it can be modified when Process() is called in a different thread.
+   * @param[in] sceneObject the property owner scene object
+   * @param[in] property The property to bake.
+   * @param[in] member The member function of the object.
+   * @param[in] value The new value of the property.
+   */
+  PropertyMessage( const PropertyOwner* sceneObject,
+                   const AnimatableProperty<P>* property,
+                   MemberFunction member,
+                   typename ParameterType< P >::PassingType value )
+  : PropertyMessageBase(),
+    mSceneObject( const_cast< PropertyOwner* >( sceneObject ) ),
+    mProperty( const_cast< AnimatableProperty<P>* >( property ) ),
+    mMemberFunction( member ),
+    mParam( value )
+  {
+  }
+
+private:
+
+  PropertyOwner* mSceneObject;
+  AnimatableProperty<P>* mProperty;
+  MemberFunction mMemberFunction;
+  typename ParameterType< P >::HolderType mParam;
+};
+
+/**
+ * Templated message which bakes a property.
+ */
+template< typename P >
+class PropertyComponentMessage : public PropertyMessageBase
+{
+public:
+
+  typedef void(AnimatableProperty<P>::*MemberFunction)( BufferIndex, float );
+
+  /**
+   * Send a message.
+   * @note The scene object is expected to be const in the thread which sends this message.
+   * However it can be modified when Process() is called in a different thread.
+   * @param[in] eventThreadServices The service object used for sending messages to the scene graph
+   * @param[in] sceneObject The property owner scene object
+   * @param[in] property The property to bake.
+   * @param[in] member The member function of the object.
+   * @param[in] value The new value of the X,Y,Z or W component.
+   */
+  static void Send( EventThreadServices& eventThreadServices,
+                    const PropertyOwner* sceneObject,
+                    const AnimatableProperty<P>* property,
+                    MemberFunction member,
+                    float value )
+  {
+    // Reserve some memory inside the message queue
+    unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( PropertyComponentMessage ) );
+
+    // Construct message in the message queue memory; note that delete should not be called on the return value
+    new (slot) PropertyComponentMessage( sceneObject, property, member, value );
+  }
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~PropertyComponentMessage()
+  {
+  }
+
+  /**
+   * @copydoc MessageBase::Process
+   */
+  virtual void Process( BufferIndex updateBufferIndex )
+  {
+    (mProperty->*mMemberFunction)( updateBufferIndex, mParam );
+  }
+
+private:
+
+  /**
+   * Create a message.
+   * @note The scene object is expected to be const in the thread which sends this message.
+   * However it can be modified when Process() is called in a different thread.
+   * @param[in] sceneObject The property owner scene object
+   * @param[in] property The property to bake.
+   * @param[in] member The member function of the object.
+   * @param[in] value The new value of the X,Y,Z or W component.
+  */
+  PropertyComponentMessage( const PropertyOwner* sceneObject,
+                            const AnimatableProperty<P>* property,
+                            MemberFunction member,
+                            float value )
+  : PropertyMessageBase(),
+    mSceneObject( const_cast< PropertyOwner* >( sceneObject ) ),
+    mProperty( const_cast< AnimatableProperty<P>* >( property ) ),
+    mMemberFunction( member ),
+    mParam( value )
+  {
+  }
+
+private:
+  PropertyOwner* mSceneObject;
+  AnimatableProperty<P>* mProperty;
+  MemberFunction mMemberFunction;
+  float mParam;
+};
+
 
 // Messages for PropertyOwner
 
@@ -69,6 +254,21 @@ inline void RemoveConstraintMessage( EventThreadServices& eventThreadServices, c
   new (slot) LocalType( &owner, &PropertyOwner::RemoveConstraint, &constraint );
 }
 
+inline void AddUniformMapMessage( EventThreadServices& eventThreadServices, const PropertyOwner& owner, UniformPropertyMapping* map )
+{
+  typedef MessageValue1< PropertyOwner, OwnerPointer< UniformPropertyMapping > > LocalType;
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  new (slot) LocalType( &owner, &PropertyOwner::AddUniformMapping, map );
+}
+
+inline void RemoveUniformMapMessage( EventThreadServices& eventThreadServices, const PropertyOwner& owner, const std::string& uniformName )
+{
+  typedef MessageValue1< PropertyOwner, std::string > LocalType;
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  new (slot) LocalType( &owner, &PropertyOwner::RemoveUniformMapping, uniformName );
+}
+
+
 } // namespace SceneGraph
 
 } // namespace Internal
index e6cfa77..e68591a 100644 (file)
@@ -170,6 +170,33 @@ PropertyOwner::PropertyOwner()
 {
 }
 
+void PropertyOwner::AddUniformMapping( UniformPropertyMapping* map )
+{
+  mUniformMaps.Add( map );
+}
+
+void PropertyOwner::RemoveUniformMapping( const std::string& uniformName )
+{
+  mUniformMaps.Remove( uniformName );
+}
+
+const UniformMap& PropertyOwner::GetUniformMap() const
+{
+  return mUniformMaps;
+}
+
+void PropertyOwner::AddUniformMapObserver( UniformMap::Observer& observer )
+{
+  mUniformMaps.AddObserver( observer );
+}
+
+void PropertyOwner::RemoveUniformMapObserver( UniformMap::Observer& observer )
+{
+  mUniformMaps.RemoveObserver( observer );
+}
+
+
+
 } // namespace SceneGraph
 
 } // namespace Internal
index b60a838..01ff3dd 100644 (file)
 #include <dali/internal/common/owner-container.h>
 #include <dali/internal/update/common/property-base.h>
 #include <dali/internal/update/common/scene-graph-buffers.h>
+#include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/update/animation/scene-graph-constraint-declarations.h>
 
+
 namespace Dali
 {
 
@@ -179,6 +181,32 @@ public:
    */
   ConstraintOwnerContainer& GetConstraints();
 
+  /**
+   * @copydoc UniformMap::Add
+   */
+  void AddUniformMapping( UniformPropertyMapping* map );
+
+  /**
+   * @copydoc UniformMap::Remove
+   */
+  void RemoveUniformMapping( const std::string& uniformName );
+
+  /**
+   * Get the mappings table
+   */
+  const UniformMap& GetUniformMap() const;
+
+  /**
+   * @copydoc UniformMap::AddUniformMapObserver
+   */
+  void AddUniformMapObserver( UniformMap::Observer& observer );
+
+  /**
+   * @copydoc UniformMap::RemoveUniformMapObserver
+   */
+  void RemoveUniformMapObserver( UniformMap::Observer& observer );
+
+
 protected:
 
   /**
@@ -203,6 +231,7 @@ private:
 protected:
 
   OwnedPropertyContainer mCustomProperties; ///< Properties provided with InstallCustomProperty()
+  UniformMap mUniformMaps; ///< Container of owned uniform maps
 
 private:
 
@@ -213,7 +242,6 @@ private:
   ObserverContainer mObservers; ///< Container of observer raw-pointers (not owned)
 
   ConstraintOwnerContainer mConstraints; ///< Container of owned constraints
-
 };
 
 } // namespace SceneGraph
diff --git a/dali/internal/update/common/scene-graph-connection-observers.cpp b/dali/internal/update/common/scene-graph-connection-observers.cpp
new file mode 100644 (file)
index 0000000..d175f6e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "scene-graph-connection-observers.h"
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+
+ConnectionObservers::ConnectionObservers()
+{
+}
+
+ConnectionObservers::~ConnectionObservers()
+{
+}
+
+void ConnectionObservers::Add(Observer& observer)
+{
+  bool foundObserver = false;
+  for( ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    if( *iter == &observer )
+    {
+      foundObserver = true;
+      break;
+    }
+  }
+  if( !foundObserver )
+  {
+    mObservers.PushBack( &observer );
+  }
+}
+
+void ConnectionObservers::Remove(Observer& observer)
+{
+  for( ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    if( *iter == &observer )
+    {
+      mObservers.Erase(iter);
+      return;
+    }
+  }
+}
+
+void ConnectionObservers::ConnectionsChanged(PropertyOwner& object)
+{
+  // Inform observers that the object's children have changed
+  for( ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    Observer* observer = (*iter);
+    observer->ConnectionsChanged( object );
+  }
+}
+
+void ConnectionObservers::ConnectedUniformMapChanged()
+{
+  // Inform observers that the object's uniform map has changed
+  for( ObserversIterator iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    Observer* observer = (*iter);
+    observer->ConnectedUniformMapChanged();
+  }
+}
+
+} // SceneGraph
+} // Internal
+} // Dali
diff --git a/dali/internal/update/common/scene-graph-connection-observers.h b/dali/internal/update/common/scene-graph-connection-observers.h
new file mode 100644 (file)
index 0000000..78d0d15
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef DALI_INTERNAL_SCENE_GRAPH_CONNECTION_H
+#define DALI_INTERNAL_SCENE_GRAPH_CONNECTION_H
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+class PropertyOwner;
+
+/**
+ * This class maintains a list of observers that are informed when
+ * it's owner changes it's connections.
+ */
+class ConnectionObservers
+{
+public:
+  class Observer
+  {
+  public:
+    /**
+     * Inform the observer of the object that it's connections have changed
+     * @param[in] object The connection owner
+     */
+    virtual void ConnectionsChanged(PropertyOwner& object) = 0;
+
+    /**
+     * Inform the observer of the object that a connected object has
+     * changed it's uniform map in some way.
+     */
+    virtual void ConnectedUniformMapChanged() = 0;
+  };
+
+  /**
+   * Constructor
+   */
+  ConnectionObservers();
+
+  /**
+   * Destructor
+   */
+  ~ConnectionObservers();
+
+  /**
+   * Add an observer
+   */
+  void Add(Observer& observer);
+
+  /**
+   * Remove an observer
+   */
+  void Remove(Observer& observer);
+
+  /**
+   * Inform the observers that the connections to the object have changed
+   * @param[in] object The connection owner
+   */
+  void ConnectionsChanged(PropertyOwner& object);
+
+  /**
+   * Inform the observers that the uniform map of this or a connected object
+   * has changed.
+   */
+  void ConnectedUniformMapChanged();
+
+private:
+  typedef Dali::Vector<Observer*> Observers;
+  typedef Observers::Iterator ObserversIterator;
+
+  Observers mObservers;
+};
+
+
+} // SceneGraph
+} // Internal
+} // Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_CONNECTION_H
index 699ad6b..f4f57bf 100644 (file)
@@ -80,6 +80,13 @@ const void* PropertyBuffer::GetData( BufferIndex bufferIndex ) const
   return reinterpret_cast< const void* >(&mData[0]);
 }
 
+void PropertyBuffer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void PropertyBuffer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
 
 } // namespace SceneGraph
 } // namespace Internal
index 82b1cd5..879b260 100644 (file)
@@ -27,6 +27,7 @@ namespace Internal
 {
 namespace SceneGraph
 {
+class SceneController;
 
 class PropertyBuffer : public PropertyOwner
 {
@@ -45,7 +46,7 @@ public:
   /**
    * Destructor
    */
-  ~PropertyBuffer();
+  virtual ~PropertyBuffer();
 
   /**
    * Get the size of the property buffer in bytes
@@ -65,6 +66,19 @@ public:
    */
   const void* GetData( BufferIndex bufferIndex ) const;
 
+  /**
+   * Connect the object to the scene graph
+   *
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * Disconnect the object from the scene graph
+   */
+  void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
 private:
 
   // @todo MESH_REWORK - TEMPORARY TYPES - REMOVE WHEN WE HAVE WORKING BUFFERS
diff --git a/dali/internal/update/common/uniform-map.cpp b/dali/internal/update/common/uniform-map.cpp
new file mode 100644 (file)
index 0000000..58de329
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "uniform-map.h"
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+
+UniformMap::UniformMap()
+{
+}
+
+UniformMap::~UniformMap()
+{
+  // Nothing to do - let the owner container delete the maps
+}
+
+void UniformMap::AddObserver( Observer& observer )
+{
+  bool foundObserver = false;
+  for( ObserversIter iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    if( *iter == &observer )
+    {
+      foundObserver = true;
+      break;
+    }
+  }
+  if( !foundObserver )
+  {
+    mObservers.PushBack( &observer );
+  }
+}
+
+void UniformMap::RemoveObserver( Observer& observer )
+{
+  for( ObserversIter iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    if( *iter == &observer )
+    {
+      mObservers.Erase(iter);
+      return;
+    }
+  }
+}
+
+void UniformMap::MappingChanged()
+{
+  for( ObserversIter iter = mObservers.Begin(); iter != mObservers.End(); ++iter )
+  {
+    Observer* observer = (*iter);
+    observer->UniformMappingsChanged( *this );
+  }
+}
+
+//
+// The uniform map can never grow beyond the limits of GL - so really, the
+// map size is likely to be small; if retaining an unsorted map proves to be
+// slow, then it should be changed to perform an insertion sort.
+void UniformMap::Add( UniformPropertyMapping* newMap )
+{
+  UniformPropertyMapping::Hash nameHash = CalculateHash( newMap->uniformName );
+
+  bool found = false;
+
+  for( UniformMapIter iter = mUniformMaps.Begin() ;
+       iter != mUniformMaps.End() ;
+       ++iter )
+  {
+    UniformPropertyMapping* map = *iter;
+    if( map->uniformNameHash == nameHash )
+    {
+      if( map->uniformName == newMap->uniformName )
+      {
+        found = true;
+        // Mapping already exists - update it.
+        map->propertyPtr = newMap->propertyPtr;
+        break;
+      }
+    }
+  }
+
+  if( found == false )
+  {
+    // Take ownership of the new map
+    mUniformMaps.PushBack(newMap);
+  }
+
+  MappingChanged();
+}
+
+void UniformMap::Remove( const std::string& uniformName )
+{
+  UniformPropertyMapping::Hash nameHash = CalculateHash( uniformName );
+
+  bool found=false;
+
+  for( UniformMapIter iter = mUniformMaps.Begin() ;
+       iter != mUniformMaps.End() ;
+       ++iter )
+  {
+    UniformPropertyMapping* map = *iter;
+    if( map->uniformNameHash == nameHash )
+    {
+      if( map->uniformName == uniformName )
+      {
+        mUniformMaps.Erase( iter );
+        found = true;
+        break;
+      }
+    }
+  }
+
+  if( found )
+  {
+    MappingChanged();
+  }
+}
+
+const PropertyInputImpl* UniformMap::Find( const std::string& uniformName )
+{
+  UniformPropertyMapping::Hash nameHash = CalculateHash( uniformName );
+
+  for( UniformMapIter iter = mUniformMaps.Begin() ;
+       iter != mUniformMaps.End() ;
+       ++iter )
+  {
+    UniformPropertyMapping* map = *iter;
+    if( map->uniformNameHash == nameHash )
+    {
+      if( map->uniformName == uniformName )
+      {
+        return map->propertyPtr;
+      }
+    }
+  }
+  return NULL;
+}
+
+unsigned int UniformMap::Count() const
+{
+  return mUniformMaps.Count();
+}
+
+const UniformPropertyMapping& UniformMap::operator[]( unsigned int index ) const
+{
+  return *mUniformMaps[index];
+}
+
+} // SceneGraph
+} // Internal
+} // Dali
index 1fb6e43..3936e7a 100644 (file)
  * limitations under the License.
  */
 
+#include <dali/internal/common/owner-container.h>
+#include <dali/internal/common/dali-hash.h>
+
+#include <string>
+
 namespace Dali
 {
 namespace Internal
 {
+class PropertyInputImpl;
+
 namespace SceneGraph
 {
 
 /**
- * The uniform map is generated on stage change, e.g when renderers, materials, geometry,
- * actors etc are added/removed from the stage.
+ * The uniform map is used to map a uniform name to a property value.
+ */
+class UniformPropertyMapping
+{
+public:
+  typedef unsigned long Hash;
+
+  /**
+   * Constructor
+   */
+  UniformPropertyMapping( const std::string& theUniformName, const PropertyInputImpl* thePropertyPtr )
+  : propertyPtr( thePropertyPtr ),
+    uniformName( theUniformName ),
+    uniformNameHash( Dali::CalculateHash( theUniformName ) )
+  {
+  }
+
+  UniformPropertyMapping()
+  : propertyPtr( NULL ),
+    uniformName( "" ),
+    uniformNameHash( 0 )
+  {
+  }
+
+
+  const PropertyInputImpl* propertyPtr;
+  std::string uniformName;
+  Hash uniformNameHash;
+};
+
+/**
+ * The UniformMap class is used to map uniform names to property values. It is available
+ * in all of the classes responsible for rendering:
+ * Actor, Renderer, Geometry, PropertyBuffer, Material, Sampler, Shader.
  *
- * It computes a list of uniform strings to property value addresses that is needed
- * for the Renderer to match once against Program uniforms; subsequent render calls do
- * not need to re-generate the match, instead using the uniform index.
+ * It can be observed for changes to the mapping table.
  */
 class UniformMap
 {
 public:
+  class Observer
+  {
+  public:
+    virtual void UniformMappingsChanged(const UniformMap& mappings) = 0;
+  };
+
   /**
    * Constructor
    */
@@ -45,10 +88,63 @@ public:
    */
   ~UniformMap();
 
+  /**
+   * Add an observer that watches for changes in the mappings
+   */
+  void AddObserver( Observer& observer );
+
+  /**
+   * Remove an observer
+   */
+  void RemoveObserver( Observer& observer );
+
+  /**
+   * Add a map to the mappings table.
+   */
+  void Add( UniformPropertyMapping* map );
+
+  /**
+   * Remove a map from the mappings table
+   */
+  void Remove( const std::string& uniformName );
+
+  /**
+   * Find a property given the uniform name.
+   * @return The address of the property if it's in the map, or NULL otherwise.
+   */
+  const PropertyInputImpl* Find( const std::string& uniformName );
+
+  /**
+   * Get the count of uniforms in the map
+   * @return The number of uniform mappings
+   */
+  unsigned int Count() const;
+
+  /**
+   * @pre index must be in the range 0 :: Count()-1
+   * @param[in] index The index of the element to fetch
+   * @return reference to the element in the map
+   */
+  const UniformPropertyMapping& operator[]( unsigned int index ) const;
+
 private:
-  // data
+  /**
+   * Helper to call the observers when the mappings have changed
+   */
+  void MappingChanged();
+
+private:
+  typedef OwnerContainer< UniformPropertyMapping* > UniformMapContainer;
+  typedef UniformMapContainer::Iterator UniformMapIter;
+  typedef Dali::Vector< Observer* > Observers;
+  typedef Observers::Iterator ObserversIter;
+
+  UniformMapContainer mUniformMaps; // Owner container of uniform maps
+
+  Observers mObservers;
 };
 
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index b05382f..a6773ce 100644 (file)
@@ -29,9 +29,12 @@ namespace SceneGraph
 {
 
 Material::Material()
-: mShader(NULL),
-  mColor( Color::WHITE )
+: mColor( Color::WHITE ),
+  mBlendColor( Color::WHITE ),
+  mShader(NULL)
 {
+  // Observe own property-owner's uniform map
+  AddUniformMapObserver( *this );
 }
 
 Material::~Material()
@@ -41,12 +44,13 @@ Material::~Material()
 void Material::SetShader( const Shader* shader )
 {
   mShader = shader;
-  // Need to inform renderer in render thread about this shader
+  // @todo inform NewRenderer about this shader
+  mConnectionObservers.ConnectionsChanged(*this);
 }
 
 Shader* Material::GetShader() const
 {
-  // @todo - Fix this - move shader setup to the Renderer connect to stage... or summit
+  // @todo - Fix this - move shader setup to the Renderer connect to stage...
   return const_cast<Shader*>(mShader);
 }
 
@@ -54,21 +58,34 @@ void Material::AddSampler( const Sampler* sampler )
 {
   const SamplerDataProvider* sdp = static_cast< const SamplerDataProvider*>( sampler );
   mSamplers.PushBack( sdp );
+
+  mConnectionObservers.ConnectionsChanged(*this);
 }
 
 void Material::RemoveSampler( const Sampler* sampler )
 {
   const SamplerDataProvider* samplerDataProvider = sampler;
+  bool found = false;
 
-  for( Samplers::Iterator iter = mSamplers.Begin(); iter != mSamplers.End(); ++iter )
+  Samplers::Iterator iter = mSamplers.Begin();
+  for( ; iter != mSamplers.End(); ++iter )
   {
     if( *iter == samplerDataProvider )
     {
-      mSamplers.Erase(iter);
-      return;
+      found = true;
+      break;
     }
   }
-  DALI_ASSERT_DEBUG( 0 && "Sampler not found" );
+
+  if( found )
+  {
+    mSamplers.Erase(iter);
+    mConnectionObservers.ConnectionsChanged(*this);
+  }
+  else
+  {
+    DALI_ASSERT_DEBUG( 0 && "Sampler not found" );
+  }
 }
 
 const Material::Samplers& Material::GetSamplers() const
@@ -76,6 +93,31 @@ const Material::Samplers& Material::GetSamplers() const
   return mSamplers;
 }
 
+void Material::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void Material::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void Material::AddConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Add(observer);
+}
+
+void Material::RemoveConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Remove(observer);
+}
+
+void Material::UniformMappingsChanged( const UniformMap& mappings )
+{
+  // Our uniform map, or that of one of the watched children has changed.
+  // Inform connected observers.
+  mConnectionObservers.ConnectedUniformMapChanged();
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index 20aea35..54e3b10 100644 (file)
@@ -24,6 +24,8 @@
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/property-owner.h>
+#include <dali/internal/update/common/scene-graph-connection-observers.h>
+#include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/render/data-providers/material-data-provider.h>
 
 namespace Dali
@@ -34,11 +36,12 @@ namespace SceneGraph
 {
 class Sampler;
 class Shader;
+class ConnectionObserver;
+class SceneController;
 
-class Material : public PropertyOwner, public MaterialDataProvider
+class Material : public PropertyOwner, public MaterialDataProvider, public UniformMap::Observer
 {
 public:
-
   /**
    * Constructor
    */
@@ -56,12 +59,6 @@ public:
   void SetShader( const Shader* shader );
 
   /**
-   * Get the shader effect of this material
-   * @return the shader effect;
-   */
-  virtual Shader* GetShader() const;
-
-  /**
    * Add a sampler (image + sampler modes) to the material
    * @param[in] sampler A sampler to add
    */
@@ -74,16 +71,58 @@ public:
   void RemoveSampler( const Sampler* sampler );
 
   /**
+   * Connect the object to the scene graph
+   *
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * Disconnect the object from the scene graph
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * @copydoc ConnectionObservers::AddObserver
+   */
+  void AddConnectionObserver(ConnectionObservers::Observer& observer);
+
+  /**
+   * @copydoc ConnectionObservers::RemoveObserver
+   */
+  void RemoveConnectionObserver(ConnectionObservers::Observer& observer);
+
+public: // MaterialDataProvider implementation
+  /**
+   * Get the shader effect of this material
+   * @return the shader effect;
+   */
+  virtual Shader* GetShader() const;
+
+  /**
    * Get the samplers this material uses.
    * @return the samplers
    */
   virtual const Samplers& GetSamplers() const;
 
+
+public: // UniformMap::Observer
+  /**
+   * @copydoc UniformMap::Observer::UniformMappingsChanged
+   */
+  virtual void UniformMappingsChanged( const UniformMap& mappings );
+
+public: // Property data
+  AnimatableProperty<Vector4> mColor;
+  AnimatableProperty<Vector4> mBlendColor;
+
 private:
   const Shader* mShader;
   Samplers mSamplers; // Not owned
-
-  AnimatableProperty<Vector4> mColor;
+  ConnectionObservers mConnectionObservers;
 
   // @todo MESH_REWORK add property values for cull face mode, blending options, blend color
   // Add getters/setters?
index 5a8eff0..05c4542 100644 (file)
@@ -106,6 +106,14 @@ bool Sampler::IsFullyOpaque( BufferIndex bufferIndex ) const
   return mBitmapMetadata[bufferIndex].IsFullyOpaque();
 }
 
+void Sampler::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void Sampler::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
+{
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index 436710a..5b5a173 100644 (file)
@@ -33,6 +33,7 @@ namespace Internal
 {
 namespace SceneGraph
 {
+class SceneController;
 
 class Sampler : public PropertyOwner, public SamplerDataProvider
 {
@@ -134,6 +135,21 @@ public: // SamplerDataProvider interface - called from RenderThread
    */
   virtual WrapMode GetVWrapMode( BufferIndex bufferIndex ) const;
 
+  /**
+   * Connect the object to the scene graph
+   *
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * Disconnect the object from the scene graph
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
 private:
   std::string mUnitName; ///< The name of the uniform of the texture unit
 
index 16492a7..3a94ca2 100644 (file)
@@ -35,16 +35,23 @@ Geometry::Geometry()
   mVertexBuffers.PushBack( vertexPropertyBuffer );
 
   mIndexBuffer = PropertyBuffer::NewQuadIndices();
+
+  // Observe our own PropertyOwner's uniform map
+  AddUniformMapObserver( *this );
 }
 
 Geometry::~Geometry()
 {
   // @todo Inform renderers of deletion of buffers?
+
+  // could remove self from own uniform map observer, but it's about to be destroyed.
 }
 
 void Geometry::AddVertexBuffer( PropertyBuffer* vertexBuffer )
 {
   mVertexBuffers.PushBack( vertexBuffer );
+  vertexBuffer->AddUniformMapObserver(*this);
+  mConnectionObservers.ConnectionsChanged(*this);
 }
 
 void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
@@ -57,7 +64,9 @@ void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
     PropertyBuffer* current = *iter;
     if ( current == vertexBuffer )
     {
+      vertexBuffer->RemoveUniformMapObserver(*this);
       mVertexBuffers.Erase( iter );
+      mConnectionObservers.ConnectionsChanged(*this);
       return;
     }
   }
@@ -67,13 +76,18 @@ void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer )
 
 void Geometry::SetIndexBuffer( PropertyBuffer* indexBuffer )
 {
-  mIndexBuffer = indexBuffer;
+  if( mIndexBuffer.Get() != indexBuffer )
+  {
+    mIndexBuffer = indexBuffer;
+    mConnectionObservers.ConnectionsChanged(*this);
+  }
 }
 
 void Geometry::ClearIndexBuffer()
 {
   // @todo Actually delete, or put on Discard Queue and tell Renderer in render thread?
   mIndexBuffer.Reset();
+  mConnectionObservers.ConnectionsChanged(*this);
 }
 
 void Geometry::SetGeometryType( BufferIndex bufferIndex, Geometry::GeometryType geometryType )
@@ -102,6 +116,31 @@ bool Geometry::GetRequiresDepthTest( BufferIndex bufferIndex ) const
   return mRequiresDepthTest.GetBoolean( bufferIndex );
 }
 
+void Geometry::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void Geometry::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
+{
+}
+
+void Geometry::AddConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Add(observer);
+}
+
+void Geometry::RemoveConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Remove(observer);
+}
+
+void Geometry::UniformMappingsChanged( const UniformMap& mappings )
+{
+  // Our uniform map, or that of one of the watched children has changed.
+  // Inform connected observers.
+  mConnectionObservers.ConnectedUniformMapChanged();
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index 169593e..f0476de 100644 (file)
@@ -23,6 +23,8 @@
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/property-owner.h>
 #include <dali/internal/update/common/property-boolean.h>
+#include <dali/internal/update/common/uniform-map.h>
+#include <dali/internal/update/common/scene-graph-connection-observers.h>
 #include <dali/internal/update/common/scene-graph-property-buffer.h>
 #include <dali/internal/render/data-providers/geometry-data-provider.h>
 
@@ -32,12 +34,13 @@ namespace Internal
 {
 namespace SceneGraph
 {
+class SceneController;
 
 /**
  * This scene graph object is a property owner. It describes a geometry using a
  * number of PropertyBuffers acting as Vertex buffers.
  */
-class Geometry : public PropertyOwner, public GeometryDataProvider
+class Geometry : public PropertyOwner, public GeometryDataProvider, public UniformMap::Observer
 {
 public:
 
@@ -49,7 +52,7 @@ public:
   /**
    * Destructor
    */
-  ~Geometry();
+  virtual ~Geometry();
 
   /**
    * Add a property buffer to be used as a vertex buffer
@@ -80,6 +83,37 @@ public:
    */
   void SetGeometryType( BufferIndex bufferIndex, GeometryType geometryType );
 
+  /**
+   * Connect the object to the scene graph
+   *
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * Disconnect the object from the scene graph
+   * @param[in] sceneController The scene controller - used for sending messages to render thread
+   * @param[in] bufferIndex The current buffer index - used for sending messages to render thread
+   */
+  void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+
+  /**
+   * @copydoc ConnectionObservers::AddObserver
+   */
+  void AddConnectionObserver(ConnectionObservers::Observer& observer);
+
+  /**
+   * @copydoc ConnectionObservers::RemoveObserver
+   */
+  void RemoveConnectionObserver(ConnectionObservers::Observer& observer);
+
+public: // UniformMap::Observer
+  /**
+   * @copydoc UniformMap::Observer::UniformMappingsChanged
+   */
+  virtual void UniformMappingsChanged( const UniformMap& mappings );
+
 public: // GeometryDataProvider
   /**
    * Get the vertex buffers of the geometry
@@ -98,7 +132,7 @@ public: // GeometryDataProvider
    */
   virtual GeometryType GetGeometryType( BufferIndex bufferIndex ) const;
 
-    /**
+  /**
    * Returns true if this geometry requires depth testing, e.g. if it is
    * a set of vertices with z != 0
    */
@@ -107,15 +141,12 @@ public: // GeometryDataProvider
 private:
   VertexBuffers mVertexBuffers; ///< The vertex buffers
   OwnerPointer<PropertyBuffer> mIndexBuffer;  ///< The index buffer if required
+  ConnectionObservers mConnectionObservers;
 
-private: // Properties
-  //DoubleBufferedProperty<Vector3>       mCenter;
-  //DoubleBufferedProperty<Vector3>       mHalfExtents;
-  //DoubleBufferedProperty<GeometryType>  mGeometryType;   ///< The type of geometry (tris/lines etc)
-  //DoubleBufferedProperty<bool>          mRequiresDepthTest;
-
+public: // Properties
   AnimatableProperty<Vector3>  mCenter;
   AnimatableProperty<Vector3>  mHalfExtents;
+
   AnimatableProperty<int>      mGeometryType;   ///< The type of geometry (tris/lines etc)
   PropertyBoolean              mRequiresDepthTest;
 };
index 3a52c84..6936e36 100644 (file)
@@ -81,8 +81,7 @@ public:
 
     mObjectContainer.PushBack( pointer );
 
-    // @todo MESH_REWORK FIX ME NOW!
-    //pointer->ConnectToSceneGraph(*mSceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+    pointer->ConnectToSceneGraph(*mSceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
   }
 
   /**
index f648442..3472e8c 100644 (file)
@@ -54,6 +54,8 @@
 #include <dali/internal/update/manager/update-manager-debug.h>
 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
+#include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
+#include <dali/internal/update/node-attachments/scene-graph-text-attachment.h>
 #include <dali/internal/update/nodes/node.h>
 #include <dali/internal/update/nodes/scene-graph-layer.h>
 #include <dali/internal/update/queue/update-message-queue.h>
@@ -432,12 +434,21 @@ void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
 
   // attach node to attachment first so that parent is known by the time attachment is connected
   node->Attach( *attachment ); // node takes ownership
-  attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+
+  // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
+  if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL ||
+      dynamic_cast<SceneGraph::TextAttachment*>( attachment ) != NULL )
+  {
+    attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+  }
 }
 
 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
 {
-  renderer->AttachToSceneGraph( *(mImpl->sceneController), mSceneGraphBuffers.GetUpdateBufferIndex() );
+  // @todo MESH_REWORK Take ownership of this object after merge with SceneGraph::RenderableAttachment
+
+  SceneGraph::NodeAttachment* attachment = static_cast<SceneGraph::NodeAttachment*>(renderer);
+  attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
 }
 
 void UpdateManager::AddObject( PropertyOwner* object )
index b6b8973..60f2d11 100644 (file)
@@ -80,9 +80,12 @@ class Sampler;
 class RendererAttachment;
 
 /**
- * UpdateManager holds a scene graph i.e. a tree of nodes.
+ * UpdateManager maintains a scene graph i.e. a tree of nodes and attachments and
+ * other property owner objects.
  * It controls the Update traversal, in which nodes are repositioned/animated,
- * and organises the culling and rendering of the scene.
+ * and organizes the the culling and rendering of the scene.
+ * It also maintains the lifecycle of nodes and other property owners that are
+ * disconnected from the scene graph.
  */
 class UpdateManager
 {
@@ -573,6 +576,7 @@ inline void AttachToNodeMessage( UpdateManager& manager, const Node& constParent
   // Scene graph thread can modify this object.
   Node& parent = const_cast< Node& >( constParent );
 
+  // @todo MESH_REWORK Don't pass by owner pointer after merge with SceneGraph::RenderableAttachment
   typedef MessageValue2< UpdateManager, Node*, NodeAttachmentOwner > LocalType;
 
   // Reserve some memory inside the message queue
@@ -584,6 +588,7 @@ inline void AttachToNodeMessage( UpdateManager& manager, const Node& constParent
 
 inline void AttachToSceneGraphMessage( UpdateManager& manager, RendererAttachment* renderer )
 {
+  // @todo MESH_REWORK Pass by owner pointer after merge with SceneGraph::RenderableAttachment
   typedef MessageValue1< UpdateManager, RendererAttachment* > LocalType;
 
   // Reserve some memory inside the message queue
index 1dbbea8..7803450 100644 (file)
@@ -54,11 +54,11 @@ public:
 
   /**
    * Second-phase construction.
-   * This is called by the UpdateManager, when the attachment is attached to the scene-graph.
+   * This is called by the UpdateManager when the attachment is attached to the scene-graph.
    * @param[in] sceneController Allows attachments to get camera controllers.
    * @param[in] updateBufferIndex The current update buffer index.
    */
-  virtual void ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex ) = 0;
+  virtual void Initialize( SceneController& sceneController, BufferIndex updateBufferIndex ) = 0;
 
   /**
    * Called shortly before destruction.
@@ -67,6 +67,16 @@ public:
   virtual void OnDestroy() = 0;
 
   /**
+   * Called when the parent node is connected to the SceneGraph
+   */
+  virtual void ConnectedToSceneGraph() = 0;
+
+  /**
+   * Called when the parent node is disconnected from the SceneGraph
+   */
+  virtual void DisconnectedFromSceneGraph( ) = 0;
+
+  /**
    * Set the parent of a NodeAttachment.
    * @param[in] parent the new parent.
    */
index 14376be..5f8c59e 100644 (file)
@@ -177,7 +177,7 @@ CameraAttachment* CameraAttachment::New()
   return new CameraAttachment();
 }
 
-void CameraAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
+void CameraAttachment::Initialize( SceneController& sceneController, BufferIndex updateBufferIndex )
 {
   // do nothing
 }
@@ -187,6 +187,16 @@ void CameraAttachment::OnDestroy()
   // do nothing
 }
 
+void CameraAttachment::ConnectedToSceneGraph()
+{
+  // do nothing
+}
+
+void CameraAttachment::DisconnectedFromSceneGraph()
+{
+  // do nothing
+}
+
 CameraAttachment::~CameraAttachment()
 {
 }
index 70af53f..97da909 100644 (file)
@@ -73,9 +73,9 @@ public:
   static CameraAttachment* New();
 
   /**
-   * @copydoc NodeAttachment::ConnectToSceneGraph().
+   * @copydoc NodeAttachment::Initialize().
    */
-  virtual void ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex );
+  virtual void Initialize( SceneController& sceneController, BufferIndex updateBufferIndex );
 
   /**
    * @copydoc NodeAttachment::OnDestroy().
@@ -83,6 +83,16 @@ public:
   virtual void OnDestroy();
 
   /**
+   * @copydoc NodeAttachment::ConnectedToSceneGraph()
+   */
+  virtual void ConnectedToSceneGraph();
+
+  /**
+   * @copydoc NodeAttachment::DisconnectedFromSceneGraph()
+   */
+  virtual void DisconnectedFromSceneGraph();
+
+  /**
    * Virtual destructor
    */
   virtual ~CameraAttachment();
index 4ecc828..5af55fc 100644 (file)
@@ -69,7 +69,7 @@ ImageAttachment::ImageAttachment( unsigned int textureId )
 {
 }
 
-void ImageAttachment::ConnectToSceneGraph2( BufferIndex updateBufferIndex )
+void ImageAttachment::Initialize2( BufferIndex updateBufferIndex )
 {
   DALI_ASSERT_DEBUG( NULL != mSceneController );
 
@@ -108,6 +108,16 @@ void ImageAttachment::OnDestroy2()
   mImageRenderer = NULL;
 }
 
+void ImageAttachment::ConnectedToSceneGraph()
+{
+  // Do nothing
+}
+
+void ImageAttachment::DisconnectedFromSceneGraph()
+{
+  // Do nothing
+}
+
 ImageAttachment::~ImageAttachment()
 {
 }
index f828a9f..1523d10 100644 (file)
@@ -206,9 +206,9 @@ private:
   void SendShaderChangeMessage( BufferIndex updateBufferIndex );
 
   /**
-   * @copydoc RenderableAttachment::ConnectToSceneGraph2().
+   * @copydoc RenderableAttachment::Initialize2().
    */
-  virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex );
+  virtual void Initialize2( BufferIndex updateBufferIndex );
 
   /**
    * @copydoc RenderableAttachment::OnDestroy2().
@@ -216,6 +216,16 @@ private:
   virtual void OnDestroy2();
 
   /**
+   * @copydoc NodeAttachment::ConnectedToSceneGraph()
+   */
+  virtual void ConnectedToSceneGraph();
+
+  /**
+   * @copydoc NodeAttachment::DisconnectedFromSceneGraph()
+   */
+  virtual void DisconnectedFromSceneGraph();
+
+  /**
    * @copydoc RenderableAttachment::DoPrepareResources()
    */
   virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
index a60c39e..6f0444f 100644 (file)
@@ -39,77 +39,54 @@ namespace Internal
 namespace SceneGraph
 {
 
-void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
+RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
+: mSceneController(NULL), //@todo MESH_REWORK Pass in where required rather than store
+  mShader( NULL ),
+  mTrackedResources(),
+  mSortModifier( 0.0f ),
+  mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
+  mUsesGeometryScaling( usesGeometryScaling ),
+  mScaleForSizeDirty( true ),
+  mUseBlend( false ),
+  mHasSizeAndColorFlag( false ),
+  mResourcesReady( false ),
+  mFinishedResourceAcquisition( false ),
+  mHasUntrackedResources( false )
 {
-  mBlendingMode = mode;
 }
 
-BlendingMode::Type RenderableAttachment::GetBlendingMode() const
+RenderableAttachment::~RenderableAttachment()
 {
-  return mBlendingMode;
 }
 
-
-void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
+void RenderableAttachment::Initialize( SceneController& sceneController, BufferIndex updateBufferIndex )
 {
-  mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
-  mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
-
-  if( mShader )
-  {
-    Integration::ResourceId id = mShader->GetEffectTextureResourceId();
+  mSceneController = &sceneController;
 
-    if( id != 0 )
-    {
-      CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
+  // Chain to derived attachments
+  Initialize2( updateBufferIndex );
 
-      if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
-      {
-        FollowTracker(id);
-        mFinishedResourceAcquisition = false;
-        mResourcesReady = false;
+  // @todo MESH_REWORK: removed: renderer.SetCullFace & renderer.SetShader;
+}
 
-        // If shader has effect texture and it's not complete and tracked, ensure
-        // we call DoPrepareResources, as the effect texture may become ready in
-        // the ProcessRenderTasks step.  Otherwise, may early out.
-        if( mHasUntrackedResources )
-        {
-          return;
-        }
-      }
-    }
-  }
+void RenderableAttachment::OnDestroy()
+{
+  // Chain to derived attachments
+  OnDestroy2();
 
-  mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
+  // SceneController is no longer valid
+  mSceneController = NULL;
 }
 
-void RenderableAttachment::FollowTracker( Integration::ResourceId id )
+void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
 {
-  CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
-
-  if( completeStatusManager.FindResourceTracker(id) != NULL )
-  {
-    bool found = false;
-    std::size_t numTrackedResources = mTrackedResources.Count();
-    for( size_t i=0; i < numTrackedResources; ++i )
-    {
-      if(mTrackedResources[i] == id)
-      {
-        found = true;
-        break;
-      }
-    }
-    if( ! found )
-    {
-      mTrackedResources.PushBack( id );
-    }
-  }
-  else
-  {
-    mHasUntrackedResources = true;
-  }
+  mBlendingMode = mode;
 }
 
+BlendingMode::Type RenderableAttachment::GetBlendingMode() const
+{
+  return mBlendingMode;
+}
 
 void RenderableAttachment::SetRecalculateScaleForSize()
 {
@@ -148,42 +125,6 @@ bool RenderableAttachment::ResolveVisibility( BufferIndex updateBufferIndex )
   return mHasSizeAndColorFlag;
 }
 
-void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
-{
-  scaling = Vector3::ONE;
-}
-
-void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
-{
-  ready = mResourcesReady;
-  complete = false;
-
-  CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
-
-  std::size_t numTrackedResources = mTrackedResources.Count();
-  if( mHasUntrackedResources || numTrackedResources == 0 )
-  {
-    complete = mFinishedResourceAcquisition;
-  }
-  else
-  {
-    // If there are tracked resources and no untracked resources, test the trackers
-    bool trackersComplete = true;
-    for( size_t i=0; i < numTrackedResources; ++i )
-    {
-      ResourceId id = mTrackedResources[i];
-      ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
-      if( tracker  && ! tracker->IsComplete() )
-      {
-        trackersComplete = false;
-        break;
-      }
-    }
-
-    complete = mFinishedResourceAcquisition || trackersComplete;
-  }
-}
-
 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
 {
   // Check whether blending needs to be disabled / enabled
@@ -233,54 +174,115 @@ void RenderableAttachment::ChangeBlending( BufferIndex updateBufferIndex, bool u
   }
 }
 
-void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
+void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
 {
-  // call the derived class first as it might change its state regarding blending
-  DoPrepareRender( updateBufferIndex );
-
-  bool blend = IsBlendingOn( updateBufferIndex );
-  ChangeBlending( updateBufferIndex, blend );
+  scaling = Vector3::ONE;
 }
 
-RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
-: mSceneController(NULL), //@todo MESH_REWORK Pass in where required rather than store
-  mShader( NULL ),
-  mTrackedResources(),
-  mSortModifier( 0.0f ),
-  mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
-  mUsesGeometryScaling( usesGeometryScaling ),
-  mScaleForSizeDirty( true ),
-  mUseBlend( false ),
-  mHasSizeAndColorFlag( false ),
-  mResourcesReady( false ),
-  mFinishedResourceAcquisition( false ),
-  mHasUntrackedResources( false )
+
+void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
 {
+  mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
+  mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
+
+  if( mShader )
+  {
+    Integration::ResourceId id = mShader->GetEffectTextureResourceId();
+
+    if( id != 0 )
+    {
+      CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
+
+      if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
+      {
+        FollowTracker(id);
+        mFinishedResourceAcquisition = false;
+        mResourcesReady = false;
+
+        // If shader has effect texture and it's not complete and tracked, ensure
+        // we call DoPrepareResources, as the effect texture may become ready in
+        // the ProcessRenderTasks step.  Otherwise, may early out.
+        if( mHasUntrackedResources )
+        {
+          return;
+        }
+      }
+    }
+  }
+
+  mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
 }
 
-RenderableAttachment::~RenderableAttachment()
+void RenderableAttachment::FollowTracker( Integration::ResourceId id )
 {
+  CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
+
+  if( completeStatusManager.FindResourceTracker(id) != NULL )
+  {
+    bool found = false;
+    std::size_t numTrackedResources = mTrackedResources.Count();
+    for( size_t i=0; i < numTrackedResources; ++i )
+    {
+      if(mTrackedResources[i] == id)
+      {
+        found = true;
+        break;
+      }
+    }
+    if( ! found )
+    {
+      mTrackedResources.PushBack( id );
+    }
+  }
+  else
+  {
+    mHasUntrackedResources = true;
+  }
 }
 
-void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
+
+void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
 {
-  mSceneController = &sceneController;
+  ready = mResourcesReady;
+  complete = false;
 
-  // Chain to derived attachments
-  ConnectToSceneGraph2( updateBufferIndex );
+  CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
 
-  // @todo MESH_REWORK: removed: renderer.SetCullFace & renderer.SetShader;
+  std::size_t numTrackedResources = mTrackedResources.Count();
+  if( mHasUntrackedResources || numTrackedResources == 0 )
+  {
+    complete = mFinishedResourceAcquisition;
+  }
+  else
+  {
+    // If there are tracked resources and no untracked resources, test the trackers
+    bool trackersComplete = true;
+    for( size_t i=0; i < numTrackedResources; ++i )
+    {
+      ResourceId id = mTrackedResources[i];
+      ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id);
+      if( tracker  && ! tracker->IsComplete() )
+      {
+        trackersComplete = false;
+        break;
+      }
+    }
+
+    complete = mFinishedResourceAcquisition || trackersComplete;
+  }
 }
 
-void RenderableAttachment::OnDestroy()
+
+void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
 {
-  // Chain to derived attachments
-  OnDestroy2();
+  // call the derived class first as it might change its state regarding blending
+  DoPrepareRender( updateBufferIndex );
 
-  // SceneController is no longer valid
-  mSceneController = NULL;
+  bool blend = IsBlendingOn( updateBufferIndex );
+  ChangeBlending( updateBufferIndex, blend );
 }
 
+
 RenderableAttachment* RenderableAttachment::GetRenderable()
 {
   return this;
index 6686af6..968e9c0 100644 (file)
@@ -48,6 +48,47 @@ class Shader;
  */
 class RenderableAttachment : public NodeAttachment
 {
+protected:
+  /**
+   * Protected constructor; only derived classes can be instantiated.
+   * @param usesGeometryScaling should be false if the derived class does not need geometry scaling
+   */
+  RenderableAttachment( bool usesGeometryScaling );
+
+  /**
+   * Virtual destructor, no deletion through this interface
+   */
+  virtual ~RenderableAttachment();
+
+private: // From NodeAttachment
+
+  /**
+   * @copydoc NodeAttachment::Initialize().
+   */
+  virtual void Initialize( SceneController& sceneController, BufferIndex updateBufferIndex );
+
+  /**
+   * @copydoc NodeAttachment::OnDestroy().
+   */
+  virtual void OnDestroy();
+
+  /**
+   * @copydoc NodeAttachment::GetRenderable()
+   */
+  virtual RenderableAttachment* GetRenderable();
+
+public: // Connection API for derived classes
+  /**
+   * Chained from RenderableAttachment::Initialize()
+   */
+  virtual void Initialize2( BufferIndex updateBufferIndex ) = 0;
+
+  /**
+   * Chained from RenderableAttachment::OnDestroy()
+   */
+  virtual void OnDestroy2() = 0;
+
+
 public: // API
 
   /**
@@ -110,15 +151,6 @@ public: // For use during in the update algorithm only
   }
 
   /**
-   * Check whether the attachment has been marked as ready to render
-   * @param[out] ready TRUE if the attachment has resources to render
-   * @param[out] complete TRUE if the attachment's resources are complete
-   * (e.g. image has finished loading, framebuffer is ready to render, native image
-   * framebuffer has been rendered)
-   */
-  void GetReadyAndComplete(bool& ready, bool& complete) const;
-
-  /**
    * Query whether the attachment has blending enabled.
    * @param[in] updateBufferIndex The current update buffer index.
    * @return true if blending is enabled, false otherwise.
@@ -133,6 +165,30 @@ public: // For use during in the update algorithm only
   void ChangeBlending( BufferIndex updateBufferIndex, bool useBlending );
 
   /**
+   * Prepare the object resources.
+   * This must be called by the UpdateManager before calling PrepareRender, for each frame.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] resourceManager The resource manager.
+   */
+  void PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
+
+  /**
+   * If the resource is being tracked, then follow it. ( Further ready tests will use this
+   * list ) Otherwise, if it's not complete, set mHasUntrackedResources.
+   * @param[in] The resource id
+   */
+  void FollowTracker( Integration::ResourceId id );
+
+  /**
+   * Check whether the attachment has been marked as ready to render
+   * @param[out] ready TRUE if the attachment has resources to render
+   * @param[out] complete TRUE if the attachment's resources are complete
+   * (e.g. image has finished loading, framebuffer is ready to render, native image
+   * framebuffer has been rendered)
+   */
+  void GetReadyAndComplete(bool& ready, bool& complete) const;
+
+  /**
    * Prepare the object for rendering.
    * This is called by the UpdateManager when an object is due to be rendered in the current frame.
    * @param[in] updateBufferIndex The current update buffer index.
@@ -159,21 +215,6 @@ public: // API for derived classes
   virtual const Renderer& GetRenderer() const = 0;
 
   /**
-   * Prepare the object resources.
-   * This must be called by the UpdateManager before calling PrepareRender, for each frame.
-   * @param[in] updateBufferIndex The current update buffer index.
-   * @param[in] resourceManager The resource manager.
-   */
-  void PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
-
-  /**
-   * If the resource is being tracked, then follow it. ( Further ready tests will use this
-   * list ) Otherwise, if it's not complete, set mHasUntrackedResources.
-   * @param[in] The resource id
-   */
-  void FollowTracker( Integration::ResourceId id );
-
-  /**
    * @copydoc RenderableAttachment::PrepareRender()
    */
   virtual void DoPrepareRender( BufferIndex updateBufferIndex ) = 0;
@@ -194,16 +235,6 @@ public: // API for derived classes
   virtual void SizeChanged( BufferIndex updateBufferIndex ) = 0;
 
   /**
-   * Chained from NodeAttachment::ConnectToSceneGraph()
-   */
-  virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex ) = 0;
-
-  /**
-   * Chained from NodeAttachment::OnDestroy()
-   */
-  virtual void OnDestroy2() = 0;
-
-  /**
    * Retrieve the scale-for-size for given node size. Default implementation returns Vector3::ZERO
    * @param[in] nodeSize to scale to
    * @param[out] scaling factors
@@ -227,36 +258,6 @@ public: // API for derived classes
     return mSortModifier;
   }
 
-protected:
-
-  /**
-   * Protected constructor; only base classes can be instantiated.
-   * @param usesGeometryScaling should be false if the derived class does not need geometry scaling
-   */
-  RenderableAttachment( bool usesGeometryScaling );
-
-  /**
-   * Virtual destructor, no deletion through this interface
-   */
-  virtual ~RenderableAttachment();
-
-private: // From NodeAttachment
-
-  /**
-   * @copydoc NodeAttachment::ConnectToSceneGraph().
-   */
-  virtual void ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex );
-
-  /**
-   * @copydoc NodeAttachment::DisconnectFromSceneGraph().
-   */
-  virtual void OnDestroy();
-
-  /**
-   * @copydoc NodeAttachment::GetRenderable()
-   */
-  virtual RenderableAttachment* GetRenderable();
-
 private:
 
   /**
index 95c6f4d..a78cb3e 100644 (file)
 #include "scene-graph-renderer-attachment.h"
 #include <dali/internal/update/effects/scene-graph-material.h>
 #include <dali/internal/update/effects/scene-graph-sampler.h>
+#include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/update/geometry/scene-graph-geometry.h>
 #include <dali/internal/update/resources/complete-status-manager.h>
 #include <dali/internal/update/resources/resource-manager.h>
 #include <dali/internal/render/queue/render-queue.h>
 #include <dali/internal/render/renderers/render-renderer.h>
+#include <dali/internal/render/shaders/scene-graph-shader.h>
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gImageAttachmentLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SCENE_GRAPH_IMAGE_ATTACHMENT");
@@ -39,6 +41,12 @@ Debug::Filter* gImageAttachmentLogFilter = Debug::Filter::New(Debug::NoLogging,
 #endif
 
 
+namespace // unnamed namespace
+{
+const int REGENERATE_UNIFORM_MAP = 2;
+const int COPY_UNIFORM_MAP       = 1;
+}
+
 namespace Dali
 {
 namespace Internal
@@ -57,19 +65,59 @@ RendererAttachment::RendererAttachment()
   mRenderer(NULL),
   mMaterial(NULL),
   mGeometry(NULL),
+  mRegenerateUniformMap(REGENERATE_UNIFORM_MAP),
   mDepthIndex(0)
 {
+  // Observe our own PropertyOwner's uniform map
+  AddUniformMapObserver( *this );
 }
 
+
 RendererAttachment::~RendererAttachment()
 {
+  mMaterial->RemoveConnectionObserver(*this);
+  mGeometry->RemoveConnectionObserver(*this);
+
   mMaterial=NULL;
   mGeometry=NULL;
 }
 
+void RendererAttachment::Initialize2( BufferIndex updateBufferIndex )
+{
+  DALI_ASSERT_DEBUG( mSceneController );
+}
+
+void RendererAttachment::OnDestroy2()
+{
+}
+
+void RendererAttachment::ConnectedToSceneGraph()
+{
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+  mParent->AddUniformMapObserver( *this );
+
+  DALI_ASSERT_DEBUG( mParent != NULL );
+  mRenderer = NewRenderer::New( *mParent, *this, mGeometry, mMaterial );
+  mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
+}
+
+void RendererAttachment::DisconnectedFromSceneGraph()
+{
+  mRegenerateUniformMap = 0;
+  mParent->RemoveUniformMapObserver( *this );
+
+  DALI_ASSERT_DEBUG( mSceneController );
+  mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
+  mRenderer = NULL;
+}
+
 void RendererAttachment::SetMaterial( BufferIndex updateBufferIndex, const Material* material)
 {
-  mMaterial = material;
+  DALI_ASSERT_DEBUG( material != NULL && "Material pointer is NULL" );
+
+  mMaterial = const_cast<Material*>(material); // Need this to be non-const to add observer only.
+  mMaterial->AddConnectionObserver( *this );
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
 
   // Tell renderer about a new provider
   if( mRenderer )
@@ -87,7 +135,11 @@ const Material& RendererAttachment::GetMaterial() const
 
 void RendererAttachment::SetGeometry( BufferIndex updateBufferIndex, const Geometry* geometry)
 {
-  mGeometry = geometry;
+  DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
+
+  mGeometry = const_cast<Geometry*>(geometry); // Need this to be non-const to add observer only
+  mGeometry->AddConnectionObserver( *this ); // Observe geometry connections / uniform mapping changes
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
 
   // Tell renderer about a new provider
   if( mRenderer )
@@ -103,18 +155,11 @@ const Geometry& RendererAttachment::GetGeometry() const
   return *mGeometry;
 }
 
-void RendererAttachment::SetDepthIndex( int index )
+int RendererAttachment::GetDepthIndex(BufferIndex bufferIndex) const
 {
-  // @todo MESH_REWORK
-  mDepthIndex = index;
+  return mDepthIndex[bufferIndex];
 }
 
-int RendererAttachment::GetDepthIndex() const
-{
-  return mDepthIndex;
-}
-
-
 Renderer& RendererAttachment::GetRenderer()
 {
   return *mRenderer;
@@ -125,9 +170,75 @@ const Renderer& RendererAttachment::GetRenderer() const
   return *mRenderer;
 }
 
+// Uniform maps are checked in the following priority order:
+//   Renderer (this object)
+//   Actor
+//   Material
+//   Samplers
+//   Shader
+//   Geometry
+//   VertexBuffers
 void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
 {
-  // Do nothing
+  if( mRegenerateUniformMap > 0)
+  {
+    if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
+    {
+      DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in DoPrepareRender()" );
+      DALI_ASSERT_DEBUG( mMaterial != NULL && "No geometry available in DoPrepareRender()" );
+
+      CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
+      localMap.Resize(0);
+
+      const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
+      AddMappings( localMap, rendererUniformMap );
+
+      const UniformMap& actorUniformMap = mParent->GetUniformMap();
+      AddMappings( localMap, actorUniformMap );
+
+      AddMappings( localMap, mMaterial->GetUniformMap() );
+      const MaterialDataProvider::Samplers& samplers = mMaterial->GetSamplers();
+      for( MaterialDataProvider::Samplers::ConstIterator iter = samplers.Begin(), end = samplers.End();
+           iter != end ;
+           ++iter )
+      {
+        const SceneGraph::Sampler* sampler = static_cast<const SceneGraph::Sampler*>( *iter );
+        AddMappings( localMap, sampler->GetUniformMap() );
+      }
+
+      AddMappings( localMap, mMaterial->GetShader()->GetUniformMap() );
+
+      AddMappings( localMap, mGeometry->GetUniformMap() );
+
+      const GeometryDataProvider::VertexBuffers& vertexBuffers = mGeometry->GetVertexBuffers();
+      for( GeometryDataProvider::VertexBuffers::ConstIterator iter = vertexBuffers.Begin(), end = vertexBuffers.End() ;
+           iter != end ;
+           ++iter )
+      {
+        AddMappings( localMap, (*iter)->GetUniformMap() );
+      }
+
+      mUniformMapChanged[updateBufferIndex] = true;
+    }
+    else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
+    {
+      // Copy old map into current map
+      CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
+      CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
+
+      localMap.Resize( oldMap.Count() );
+
+      unsigned int index=0;
+      for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter )
+      {
+        localMap[index] = *iter;
+      }
+
+      mUniformMapChanged[updateBufferIndex] = true;
+    }
+
+    mRegenerateUniformMap--;
+  }
 }
 
 bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
@@ -173,25 +284,6 @@ void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex )
   // Do nothing.
 }
 
-void RendererAttachment::AttachToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
-{
-  mSceneController = &sceneController;
-}
-
-void RendererAttachment::ConnectToSceneGraph2( BufferIndex updateBufferIndex )
-{
-  DALI_ASSERT_DEBUG( mSceneController );
-  mRenderer = NewRenderer::New( *mParent, mGeometry, mMaterial );
-  mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
-}
-
-void RendererAttachment::OnDestroy2()
-{
-  DALI_ASSERT_DEBUG( mSceneController );
-  mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
-  mRenderer = NULL;
-}
-
 bool RendererAttachment::DoPrepareResources(
   BufferIndex updateBufferIndex,
   ResourceManager& resourceManager )
@@ -203,7 +295,11 @@ bool RendererAttachment::DoPrepareResources(
   bool ready = false;
   mFinishedResourceAcquisition = false;
 
-  if( mGeometry && mMaterial )
+  // Can only be considered ready when all the scene graph objects are connected to the renderer
+  if( ( mGeometry ) &&
+      ( mGeometry->GetVertexBuffers().Count() > 0 ) &&
+      ( mMaterial ) &&
+      ( mMaterial->GetShader() != NULL ) )
   {
     unsigned int completeCount = 0;
     unsigned int neverCount = 0;
@@ -250,9 +346,84 @@ bool RendererAttachment::DoPrepareResources(
     ready = ( completeCount + frameBufferCount >= samplers.Count() ) ;
     mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() );
   }
+
   return ready;
 }
 
+void RendererAttachment::ConnectionsChanged( PropertyOwner& object )
+{
+  // One of our child objects has changed it's connections. Ensure the uniform
+  // map gets regenerated during PrepareRender
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+}
+
+void RendererAttachment::ConnectedUniformMapChanged()
+{
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+}
+
+void RendererAttachment::UniformMappingsChanged( const UniformMap& mappings )
+{
+  // The mappings are either from PropertyOwner base class, or the Actor
+  mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
+}
+
+bool RendererAttachment::GetUniformMapChanged( BufferIndex bufferIndex ) const
+{
+  return mUniformMapChanged[bufferIndex];
+}
+
+const CollectedUniformMap& RendererAttachment::GetUniformMap( BufferIndex bufferIndex ) const
+{
+  return mCollectedUniformMap[ bufferIndex ];
+}
+
+void RendererAttachment::AddMappings( CollectedUniformMap& localMap, const UniformMap& uniformMap )
+{
+  // Iterate thru uniformMap.
+  //   Any maps that aren't in localMap should be added in a single step
+  CollectedUniformMap newUniformMappings;
+
+  for( unsigned int i=0, count=uniformMap.Count(); i<count; ++i )
+  {
+    UniformPropertyMapping::Hash nameHash = uniformMap[i].uniformNameHash;
+    bool found = false;
+
+    for( CollectedUniformMap::Iterator iter = localMap.Begin() ; iter != localMap.End() ; ++iter )
+    {
+      const UniformPropertyMapping* map = (*iter);
+      if( map->uniformNameHash == nameHash )
+      {
+        if( map->uniformName == uniformMap[i].uniformName )
+        {
+          found = true;
+          break;
+        }
+      }
+    }
+    if( !found )
+    {
+      // it's a new mapping. Add raw ptr to temporary list
+      newUniformMappings.PushBack( &uniformMap[i] );
+    }
+  }
+
+  if( newUniformMappings.Count() > 0 )
+  {
+    localMap.Reserve( localMap.Count() + newUniformMappings.Count() );
+
+    for( CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
+           end = newUniformMappings.End() ;
+         iter != end ;
+         ++iter )
+    {
+      const UniformPropertyMapping* map = (*iter);
+      localMap.PushBack( map );
+    }
+    //@todo MESH_REWORK Use memcpy to copy ptrs from one array to the other
+  }
+}
+
 
 
 } // namespace SceneGraph
index effde67..6bb2d55 100644 (file)
 #include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/property-owner.h>
+#include <dali/internal/update/common/animatable-property.h>
+#include <dali/internal/update/common/scene-graph-connection-observers.h>
 #include <dali/internal/update/controllers/render-message-dispatcher.h>
 #include <dali/internal/update/controllers/scene-controller.h>
 #include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
-#include <dali/internal/render/data-providers/uniform-map-provider.h>
+#include <dali/internal/render/data-providers/uniform-map-data-provider.h>
 
 namespace Dali
 {
@@ -35,8 +37,29 @@ class Material;
 class Geometry;
 class NewRenderer;
 
+/**
+ * The renderer attachment is the SceneGraph equivalent of Dali::Renderer. It is used to create an instance of a geometry and material for rendering, and is attached to an actor.
+ *
+ * It observes it's children (Material and Geometry) for connection change and for uniform map change, and observer's it's actor parent for uniform map change - this allows it to re-generate the uniform maps used by its RenderThread equivalent class.
+ *
+ * Lifetime and ownership
+ * It is created when a Dali::Renderer is created, and sent to UpdateManager. At this point
+ * Initialize is called on the object, but ownership is NOT taken by UpdateManager.
+
+ * When a Dali::Renderer is added to an actor, then this object becomes the node attachment
+ * for that actor, and the node takes ownership. It will create the Render::NewRenderer object
+ * in the Update thread on reciept of the connection message.
 
-class RendererAttachment : public RenderableAttachment, public PropertyOwner, public UniformMapProvider
+ * When it's not attached to an actor, it is still possible to send messages to this
+ * object, to, e.g., set the material, or a property.
+ *
+ * @todo MESH_REWORK On merge with RenderableAttachment, change owner of all attachments to UpdateManager.
+ */
+class RendererAttachment : public RenderableAttachment,
+                           public PropertyOwner,
+                           public UniformMapDataProvider,
+                           public UniformMap::Observer,
+                           public ConnectionObservers::Observer
 {
 public:
   /**
@@ -56,6 +79,26 @@ public:
   virtual ~RendererAttachment();
 
   /**
+   * @copydoc RenderableAttachment::Initialize2().
+   */
+  virtual void Initialize2( BufferIndex updateBufferIndex );
+
+  /**
+   * @copydoc RenderableAttachment::OnDestroy2().
+   */
+  virtual void OnDestroy2();
+
+  /**
+   * @copydoc NodeAttachment::ConnectedToSceneGraph()
+   */
+  virtual void ConnectedToSceneGraph();
+
+  /**
+   * @copydoc NodeAttachment::DisconnectedFromSceneGraph()
+   */
+  virtual void DisconnectedFromSceneGraph();
+
+  /**
    * Set the material for the renderer
    * @param[in] bufferIndex The current frame's buffer index
    * @param[in] material The material this renderer will use
@@ -82,21 +125,10 @@ public:
   const Geometry& GetGeometry() const;
 
   /**
-   * Set the depth index
-   * @param[in] index The depth index to use
-   */
-  void SetDepthIndex( int index );
-
-  /**
    * Get the depth index
-   * @return The depth index to use
-   */
-  int GetDepthIndex() const ;
-
-  /**
-   * Initial setup on attaching to the scene graph
+   * @return The depth index of the renderer attachment in the current frame
    */
-  void AttachToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex );
+  int GetDepthIndex( BufferIndex bufferIndex ) const ;
 
 protected: // From RenderableAttachment
   /**
@@ -124,29 +156,59 @@ protected: // From RenderableAttachment
    */
   virtual void SizeChanged( BufferIndex updateBufferIndex );
 
-/**
-   * @copydoc RenderableAttachment::ConnectToSceneGraph2().
+  /**
+   * @copydoc RenderableAttachment::DoPrepareResources()
    */
-  virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex );
+  virtual bool DoPrepareResources( BufferIndex updateBufferIndex,
+                                   ResourceManager& resourceManager );
 
+protected: // From ConnectionObserver
   /**
-   * @copydoc RenderableAttachment::OnDestroy2().
+   * @copydoc ConnectionObservers::Observer::ConnectionsChanged
    */
-  virtual void OnDestroy2();
+  virtual void ConnectionsChanged(PropertyOwner& object);
 
   /**
-   * @copydoc RenderableAttachment::DoPrepareResources()
+   * @copydoc ConnectionObservers::Observer::ConnectedUniformMapChanged
    */
-  virtual bool DoPrepareResources( BufferIndex updateBufferIndex,
-                                   ResourceManager& resourceManager );
+  virtual void ConnectedUniformMapChanged();
+
+protected: // From UniformMap::Observer
+  /**
+   * @copydoc UniformMap::Observer::UniformMappingsChanged
+   */
+  virtual void UniformMappingsChanged( const UniformMap& mappings );
+
+protected: // From UniformMapDataProvider
+  /**
+   * @copydoc UniformMapDataProvider::GetUniformMapChanged
+   */
+  virtual bool GetUniformMapChanged( BufferIndex bufferIndex ) const;
+
+  /**
+   * @copydoc UniformMapDataProvider::GetUniformMap
+   */
+  virtual const CollectedUniformMap& GetUniformMap( BufferIndex bufferIndex ) const;
+
+private:
+  /**
+   * Add any new mappings from map into the current map.
+   * This doesn't override any existing mappings.
+   */
+  void AddMappings( CollectedUniformMap& localMap, const UniformMap& map );
 
 private:
   NewRenderer* mRenderer; ///< Raw pointer to the new renderer (that's owned by RenderManager)
 
-  const Material* mMaterial; ///< The material this renderer uses. (Not owned)
-  const Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned)
+  Material* mMaterial; ///< The material this renderer uses. (Not owned)
+  Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned)
+
+  CollectedUniformMap mCollectedUniformMap[2];
+  bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame
+  int mRegenerateUniformMap;  ///< 2 if the map should be regenerated, 1 if it should be copied.
+public: // Properties
 
-  int mDepthIndex;     ///< Used only in PrepareRenderInstructions
+  AnimatableProperty<int> mDepthIndex; ///< Used only in PrepareRenderInstructions
 };
 
 // Messages for RendererAttachment
@@ -173,17 +235,6 @@ inline void SetGeometryMessage( EventThreadServices& eventThreadServices, const
   new (slot) LocalType( &attachment, &RendererAttachment::SetGeometry, &geometry );
 }
 
-inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const RendererAttachment& attachment, int depthIndex )
-{
-  typedef MessageValue1< RendererAttachment, int > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &attachment, &RendererAttachment::SetDepthIndex, depthIndex );
-}
-
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index adfb456..4a4bfce 100644 (file)
@@ -66,7 +66,7 @@ TextAttachment::TextAttachment()
   DALI_LOG_INFO(gTextFilter, Debug::General, "TextAttachment::constructor(this=%p)\n", this);
 }
 
-void TextAttachment::ConnectToSceneGraph2( BufferIndex updateBufferIndex )
+void TextAttachment::Initialize2( BufferIndex updateBufferIndex )
 {
   DALI_ASSERT_DEBUG( NULL != mSceneController );
 
@@ -86,6 +86,16 @@ void TextAttachment::OnDestroy2()
   mTextRenderer = NULL;
 }
 
+void TextAttachment::ConnectedToSceneGraph()
+{
+  // Do nothing
+}
+
+void TextAttachment::DisconnectedFromSceneGraph()
+{
+  // Do nothing
+}
+
 TextAttachment::~TextAttachment()
 {
 }
index a146a60..1a0fb40 100644 (file)
@@ -171,9 +171,9 @@ protected:
 private:
 
   /**
-   * @copydoc RenderableAttachment::ConnectToSceneGraph2().
+   * @copydoc RenderableAttachment::Initialize2().
    */
-  virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex );
+  virtual void Initialize2( BufferIndex updateBufferIndex );
 
   /**
    * @copydoc RenderableAttachment::OnDestroy2().
@@ -181,6 +181,16 @@ private:
   virtual void OnDestroy2();
 
   /**
+   * @copydoc NodeAttachment::ConnectedToSceneGraph()
+   */
+  virtual void ConnectedToSceneGraph();
+
+  /**
+   * @copydoc NodeAttachment::DisconnectedFromSceneGraph()
+   */
+  virtual void DisconnectedFromSceneGraph();
+
+  /**
    * @copydoc RenderableAttachment::DoPrepareResources()
    */
   virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
index 48474f6..1b74e67 100644 (file)
@@ -124,7 +124,14 @@ void Node::ConnectChild( Node* childNode, int index )
     mChildren.Insert(mChildren.Begin()+index, childNode);
   }
 
+  // Inform property observers of new connection
   childNode->ConnectToSceneGraph();
+
+  // Inform child node attachment that the node has been added to the stage
+  if( childNode->mAttachment )
+  {
+    childNode->mAttachment->ConnectedToSceneGraph();
+  }
 }
 
 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
@@ -259,6 +266,12 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std
   // Remove all child pointers
   mChildren.Clear();
 
+  // Inform child node attachment that the node has been removed from the stage
+  if( mAttachment )
+  {
+    mAttachment->DisconnectedFromSceneGraph();
+  }
+
   // Move into disconnectedNodes
   std::set<Node*>::size_type removed = connectedNodes.erase( this );
   DALI_ASSERT_ALWAYS( removed );
index 8e51d9d..8adf0d5 100644 (file)
@@ -53,11 +53,13 @@ Renderer& Renderer::operator=( const Renderer& handle )
 
 void Renderer::SetGeometry( Geometry& geometry )
 {
+  DALI_ASSERT_ALWAYS( geometry && "Geometry handle not initialized" );
   GetImplementation(*this).SetGeometry( GetImplementation(geometry) );
 }
 
 void Renderer::SetMaterial( Material& material )
 {
+  DALI_ASSERT_ALWAYS( material && "Material handle not initialized" );
   GetImplementation(*this).SetMaterial( GetImplementation(material) );
 }
 
index e525247..8ff0a7c 100644 (file)
@@ -103,12 +103,23 @@ public:
   /**
    * @brief Set the depth index of this renderer
    *
-   * Renderer with higher depth indices are rendered in front of other with smaller values
+   * Renderer with higher depth indices are rendered in front of other renderers with smaller values
    *
    * @param[in] depthIndex The depth index of this renderer
    */
   void SetDepthIndex( int depthIndex );
 
+  //@todo No interface to remove geometry / material? I guess you have to throw away
+  // this renderer if you don't want it to work any more...
+
+  /**
+   * @brief Get the depth index of this renderer
+   *
+   * @sa SetDepthIndex()
+   * @return the depth index
+   */
+  int GetDepthIndex();
+
 public:
   /**
    * @brief The constructor
index a643553..84e9f8f 100644 (file)
@@ -51,6 +51,7 @@ Geometry& Geometry::operator=( const Geometry& handle )
 
 std::size_t Geometry::AddVertexBuffer( PropertyBuffer& vertexBuffer )
 {
+  DALI_ASSERT_ALWAYS( vertexBuffer && "VertexBuffer is not initialized ");
   return GetImplementation(*this).AddVertexBuffer( GetImplementation( vertexBuffer ) );
 }
 
@@ -66,6 +67,7 @@ void Geometry::RemoveVertexBuffer( std::size_t index )
 
 void Geometry::SetIndexBuffer( PropertyBuffer& indexBuffer )
 {
+  DALI_ASSERT_ALWAYS( indexBuffer && "indexBuffer is not initialized ");
   GetImplementation(*this).SetIndexBuffer( GetImplementation( indexBuffer ) );
 }
 
index 030bf7d..0a3f8bb 100644 (file)
@@ -184,25 +184,14 @@ void Handle::RemoveConstraints( unsigned int tag )
   GetImplementation(*this).RemoveConstraints( tag );
 }
 
-std::size_t Handle::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
+void Handle::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
 {
-  //TODO: MESH_REWORK Milestone 2
-  return 0;
-}
-
-void Handle::RemoveUniformMapping( std::size_t index )
-{
-  //TODO: MESH_REWORK Milestone 2
+  GetImplementation(*this).AddUniformMapping( propertyIndex, uniformName );
 }
 
 void Handle::RemoveUniformMapping( const std::string uniformName )
 {
-  //TODO: MESH_REWORK Milestone 2
-}
-
-std::size_t Handle::GetNumberOfUniformMappings() const
-{
-  return 0;
+  GetImplementation(*this).RemoveUniformMapping( uniformName );
 }
 
 namespace WeightObject
index 684a691..d71d4db 100644 (file)
@@ -385,16 +385,8 @@ public:
    *
    * @param[in] propertyIndex Index of a property hold by the object pointed by this handle
    * @param[in] uniformName Name of the uniform
-   * @return index of the mapping
    */
-  std::size_t AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName );
-
-  /**
-   * @brief Remove an uniform mapping
-   *
-   * @param[in] index Index of the mapping to remove
-   */
-  void RemoveUniformMapping( std::size_t index );
+  void AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName );
 
   /**
    * @brief Removes the mapping for the given uniform name, if there is any
@@ -402,13 +394,6 @@ public:
    * @param[in] uniformName Name of a uniform in a mapping
    */
   void RemoveUniformMapping( const std::string uniformName );
-
-  /**
-   * @brief Get the number of uniform mappings
-   *
-   * @return The number of uniform mappings on the object pointed by this handle
-   */
-  std::size_t GetNumberOfUniformMappings() const;
 };
 
 namespace WeightObject
index 8c3509e..cfc938d 100644 (file)
@@ -48,10 +48,10 @@ enum PropertyRanges
 
   PROPERTY_REGISTRATION_MAX_INDEX               = 19999999,   ///< The maximum index supported when registering a property
 
-  ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX  = 20000000,   ///< The index when registering an animatable property should start from this number.
+  ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX  = 20000000,   ///< The index when registering an animatable property should start from this number. (SceneGraph properties per type)
   ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX    = 29999999,   ///< The maximum index supported when registering an animatable property
 
-  PROPERTY_CUSTOM_START_INDEX                   = 50000000,   ///< The index at which custom properties start
+  PROPERTY_CUSTOM_START_INDEX                   = 50000000,   ///< The index at which custom properties start (SceneGraph and Event side properties per instance)
 };
 
 } // namespace Dali
index 5f17f92..dcfa364 100644 (file)
@@ -56,11 +56,13 @@ Material& Material::operator=( const Material& handle )
 
 void Material::SetShader( Shader& shader )
 {
+  DALI_ASSERT_ALWAYS( shader && "Shader handle is uninitialized" );
   GetImplementation(*this).SetShader( GetImplementation( shader ) );
 }
 
 void Material::AddSampler( Sampler& sampler )
 {
+  DALI_ASSERT_ALWAYS( sampler && "Sampler handle is uninitialized" );
   GetImplementation(*this).AddSampler( GetImplementation( sampler ) );
 }