Added connection for sampler texture 48/37948/1
authorDavid Steele <david.steele@partner.samsung.com>
Wed, 8 Apr 2015 18:55:56 +0000 (19:55 +0100)
committerDavid Steele <david.steele@partner.samsung.com>
Wed, 8 Apr 2015 18:55:56 +0000 (19:55 +0100)
Adding an object connection for the sampler texture enables the
material to be informed when the sampler texture changes.

This is chained up to the renderable attachment, which re-sends
the data providers to the renderer, updating the texture.

Note, doubleBufferedProperty[i] = value does not enable the aging
behaviour, whereas doubleBufferedProperty.Set(i, value) does.

Change-Id: I3c43839e86cbc59a6c47598d287bfae512b18639
Signed-off-by: David Steele <david.steele@partner.samsung.com>
dali/internal/event/effects/sampler-impl.cpp
dali/internal/event/effects/sampler-impl.h
dali/internal/render/data-providers/material-data-provider.h
dali/internal/render/data-providers/render-data-provider.h
dali/internal/update/common/double-buffered-property.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/node-attachments/scene-graph-renderer-attachment.cpp
dali/public-api/shader-effects/sampler.cpp

index 9634eb5..ddd0e6f 100644 (file)
@@ -61,12 +61,15 @@ void Sampler::SetUniformName( const std::string& name )
   SetUnitNameMessage( GetEventThreadServices(), *mSceneObject, name);
 }
 
-void Sampler::SetImage( Image& image )
+void Sampler::SetImage( ImagePtr& image )
 {
-  unsigned int resourceId = image.GetResourceId();
+  // Keep a reference to the image object
+  mImageConnector.Set( image, OnStage() );
 
   // sceneObject is being used in a separate thread; queue a message to set
+  unsigned int resourceId = image->GetResourceId();
   SetTextureMessage( GetEventThreadServices(), *mSceneObject, resourceId );
+
 }
 
 void Sampler::SetFilterMode( Dali::Sampler::FilterMode minFilter, Dali::Sampler::FilterMode magFilter )
index 9cb2347..358313e 100644 (file)
@@ -61,7 +61,7 @@ public:
   /**
    * @copydoc Dali::Sampler::SetImage()
    */
-  void SetImage( Image& image );
+  void SetImage( ImagePtr& image );
 
   /**
    * @copydoc Dali::Sampler::SetFilterMode()
index f6e4234..dfc31f2 100644 (file)
@@ -24,8 +24,6 @@ namespace Internal
 {
 namespace SceneGraph
 {
-class SamplerDataProvider;
-class Shader;
 
 /**
  * Interface to provide data of the material to the renderer.
index d499db3..47170e3 100644 (file)
@@ -31,6 +31,7 @@ namespace Internal
 namespace SceneGraph
 {
 class PropertyBuffer;
+class Shader;
 
 /**
  * Wraps all the data providers for the renderer. This allows the
index be934b1..aa84dd0 100644 (file)
@@ -235,20 +235,19 @@ private:
 };
 
 
-
 /**
- * A float doubleBuffered property of a scene-graph object.
+ * A double buffered integer property of a scene-graph object.
  */
 template <>
-class DoubleBufferedProperty<float> : public DoubleBufferedPropertyBase
+class DoubleBufferedProperty<int> : public DoubleBufferedPropertyBase
 {
 public:
 
   /**
-   * Create a doubleBuffered property.
-   * @param[in] initialValue The initial value of the property.
+   * Create a double buffered property.
+   * @param [in] initialValue The initial value of the property.
    */
-  DoubleBufferedProperty( float initialValue )
+  DoubleBufferedProperty( int initialValue )
   : mValue( initialValue )
   {
   }
@@ -265,7 +264,7 @@ public:
    */
   virtual Dali::Property::Type GetType() const
   {
-    return Dali::PropertyTypes::Get<float>();
+    return Dali::PropertyTypes::Get<int>();
   }
 
   /**
@@ -281,9 +280,9 @@ public:
   }
 
   /**
-   * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
+   * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
    */
-  virtual const float& GetFloat( BufferIndex bufferIndex ) const
+  virtual const int& GetInteger( BufferIndex bufferIndex ) const
   {
     return mValue[ bufferIndex ];
   }
@@ -294,16 +293,21 @@ public:
    * @param[in] bufferIndex The buffer to write.
    * @param[in] value The new property value.
    */
-  void Set(BufferIndex bufferIndex, float value)
+  void Set(BufferIndex bufferIndex, int value)
   {
-    mValue[bufferIndex] = value;
-    OnSet();
+    // check if the value actually changed to avoid dirtying nodes unnecessarily
+    if( mValue[bufferIndex] != value )
+    {
+      mValue[bufferIndex] = value;
+
+      OnSet();
+    }
   }
 
   /**
    * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
    */
-  float& Get(size_t bufferIndex)
+  int& Get(size_t bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -311,7 +315,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
    */
-  const float& Get(size_t bufferIndex) const
+  const int& Get(size_t bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -321,7 +325,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  float& operator[](size_t bufferIndex)
+  int& operator[](size_t bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -331,7 +335,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const float& operator[](size_t bufferIndex) const
+  const int& operator[](size_t bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -344,23 +348,24 @@ private:
   DoubleBufferedProperty& operator=(const DoubleBufferedProperty& rhs);
 
 private:
-  DoubleBuffered<float> mValue; ///< The double-buffered property value
+  DoubleBuffered<int> mValue; ///< The double-buffered property value
 };
 
 
 /**
- * A double buffered integer property of a scene-graph object.
+ * A double buffered unsigned integer property of a scene-graph object.
  */
 template <>
-class DoubleBufferedProperty<int> : public DoubleBufferedPropertyBase
+class DoubleBufferedProperty<unsigned int> : public DoubleBufferedPropertyBase
 {
 public:
+  typedef unsigned int OwnType;
 
   /**
    * Create a double buffered property.
    * @param [in] initialValue The initial value of the property.
    */
-  DoubleBufferedProperty( int initialValue )
+  DoubleBufferedProperty( OwnType initialValue )
   : mValue( initialValue )
   {
   }
@@ -377,7 +382,7 @@ public:
    */
   virtual Dali::Property::Type GetType() const
   {
-    return Dali::PropertyTypes::Get<int>();
+    return Dali::PropertyTypes::Get<OwnType>();
   }
 
   /**
@@ -395,7 +400,7 @@ public:
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
    */
-  virtual const int& GetInteger( BufferIndex bufferIndex ) const
+  virtual const OwnType& GetUnsignedInteger( BufferIndex bufferIndex ) const
   {
     return mValue[ bufferIndex ];
   }
@@ -406,7 +411,7 @@ public:
    * @param[in] bufferIndex The buffer to write.
    * @param[in] value The new property value.
    */
-  void Set(BufferIndex bufferIndex, int value)
+  void Set(BufferIndex bufferIndex, OwnType value)
   {
     // check if the value actually changed to avoid dirtying nodes unnecessarily
     if( mValue[bufferIndex] != value )
@@ -420,7 +425,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
    */
-  int& Get(size_t bufferIndex)
+  OwnType& Get(size_t bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -428,7 +433,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
    */
-  const int& Get(size_t bufferIndex) const
+  const OwnType& Get(size_t bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -438,7 +443,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  int& operator[](size_t bufferIndex)
+  OwnType& operator[](size_t bufferIndex)
   {
     return mValue[bufferIndex];
   }
@@ -448,7 +453,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const int& operator[](size_t bufferIndex) const
+  const OwnType& operator[](size_t bufferIndex) const
   {
     return mValue[bufferIndex];
   }
@@ -461,7 +466,119 @@ private:
   DoubleBufferedProperty& operator=(const DoubleBufferedProperty& rhs);
 
 private:
-  DoubleBuffered<int> mValue; ///< The double-buffered property value
+  DoubleBuffered<OwnType> mValue; ///< The double-buffered property value
+};
+
+
+/**
+ * A float doubleBuffered property of a scene-graph object.
+ */
+template <>
+class DoubleBufferedProperty<float> : public DoubleBufferedPropertyBase
+{
+public:
+
+  /**
+   * Create a doubleBuffered property.
+   * @param[in] initialValue The initial value of the property.
+   */
+  DoubleBufferedProperty( float initialValue )
+  : mValue( initialValue )
+  {
+  }
+
+  /**
+   * Virtual destructor.
+   */
+  virtual ~DoubleBufferedProperty()
+  {
+  }
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
+   */
+  virtual Dali::Property::Type GetType() const
+  {
+    return Dali::PropertyTypes::Get<float>();
+  }
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::DoubleBufferedPropertyBase::CopyPrevious()
+   */
+  virtual void CopyPrevious( BufferIndex updateBufferIndex )
+  {
+    if( DoubleBufferedPropertyFlags::SET_FLAG == mDirtyFlags)
+    {
+      mValue[ updateBufferIndex ] = mValue[ 1-updateBufferIndex ];
+      mDirtyFlags = ( mDirtyFlags >> 1 );
+    }
+  }
+
+  /**
+   * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
+   */
+  virtual const float& GetFloat( BufferIndex bufferIndex ) const
+  {
+    return mValue[ bufferIndex ];
+  }
+
+  /**
+   * Set the property value. This will persist for the current frame, and will
+   * be copied to the other buffer next frame (unless it is set again)
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] value The new property value.
+   */
+  void Set(BufferIndex bufferIndex, float value)
+  {
+    mValue[bufferIndex] = value;
+    OnSet();
+  }
+
+  /**
+   * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
+   */
+  float& Get(size_t bufferIndex)
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * @copydoc Dali::SceneGraph::DoubleBufferedProperty::Get()
+   */
+  const float& Get(size_t bufferIndex) const
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * Retrieve the property value.
+   * @param[in] bufferIndex The buffer to read.
+   * @return The property value.
+   */
+  float& operator[](size_t bufferIndex)
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * Retrieve the property value.
+   * @param[in] bufferIndex The buffer to read.
+   * @return The property value.
+   */
+  const float& operator[](size_t bufferIndex) const
+  {
+    return mValue[bufferIndex];
+  }
+
+private:
+  // Undefined
+  DoubleBufferedProperty(const DoubleBufferedProperty& property);
+
+  // Undefined
+  DoubleBufferedProperty& operator=(const DoubleBufferedProperty& rhs);
+
+private:
+  DoubleBuffered<float> mValue; ///< The double-buffered property value
 };
 
 /**
index 952ae2a..c0ee2ca 100644 (file)
@@ -46,7 +46,8 @@ Material::~Material()
 void Material::SetShader( const Shader* shader )
 {
   mShader = shader;
-  // @todo inform NewRenderer about this shader
+  // Inform NewRenderer about this shader: (Will force a re-load of the
+  // shader from the data providers)
   mConnectionObservers.ConnectionsChanged(*this);
 }
 
@@ -61,6 +62,10 @@ void Material::AddSampler( const Sampler* sampler )
   const SamplerDataProvider* sdp = static_cast< const SamplerDataProvider*>( sampler );
   mSamplers.PushBack( sdp );
 
+  Sampler* mutableSampler = const_cast<Sampler*>(sampler);
+  mutableSampler->AddConnectionObserver( *this );
+  mutableSampler->AddUniformMapObserver( *this );
+
   mConnectionObservers.ConnectionsChanged(*this);
 }
 
@@ -81,6 +86,9 @@ void Material::RemoveSampler( const Sampler* sampler )
 
   if( found )
   {
+    Sampler* mutableSampler = const_cast<Sampler*>(sampler);
+    mutableSampler->RemoveConnectionObserver( *this );
+    mutableSampler->RemoveUniformMapObserver( *this );
     mSamplers.Erase(iter);
     mConnectionObservers.ConnectionsChanged(*this);
   }
@@ -120,6 +128,16 @@ void Material::UniformMappingsChanged( const UniformMap& mappings )
   mConnectionObservers.ConnectedUniformMapChanged();
 }
 
+void Material::ConnectionsChanged( PropertyOwner& owner )
+{
+  mConnectionObservers.ConnectionsChanged(*this);
+}
+
+void Material::ConnectedUniformMapChanged( )
+{
+  mConnectionObservers.ConnectedUniformMapChanged();
+}
+
 void Material::ResetDefaultProperties( BufferIndex updateBufferIndex )
 {
   mColor.ResetToBaseValue( updateBufferIndex );
index 14201e1..f4e7f56 100644 (file)
@@ -39,7 +39,7 @@ class Shader;
 class ConnectionObserver;
 class SceneController;
 
-class Material : public PropertyOwner, public MaterialDataProvider, public UniformMap::Observer
+class Material : public PropertyOwner, public MaterialDataProvider, public UniformMap::Observer, public ConnectionObservers::Observer
 {
 public:
   /**
@@ -114,6 +114,18 @@ public: // UniformMap::Observer
    */
   virtual void UniformMappingsChanged( const UniformMap& mappings );
 
+public: // ConnectionObserver::Observer
+
+  /**
+   * @copydoc ConnectionObservers::ConnectionsChanged
+   */
+  virtual void ConnectionsChanged( PropertyOwner& owner );
+
+  /**
+   * @copydoc ConnectionObservers::ConnectedUniformMapChanged
+   */
+  virtual void ConnectedUniformMapChanged( );
+
 public: // PropertyOwner implementation
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
index 02410d0..228e122 100644 (file)
@@ -29,14 +29,14 @@ namespace SceneGraph
 
 Sampler::Sampler( const std::string& unitName )
 : mUnitName( unitName ),
+  mTextureId( 0u ),
   mMinFilter( Dali::Sampler::DEFAULT ),
   mMagFilter( Dali::Sampler::DEFAULT ),
   mUWrapMode( Dali::Sampler::CLAMP_TO_EDGE ),
   mVWrapMode( Dali::Sampler::CLAMP_TO_EDGE ),
-  mAffectsTransparency( false )
+  mAffectsTransparency( false ),
+  mFullyOpaque(true)
 {
-  mTextureId[0] = 0;
-  mTextureId[1] = 0;
 }
 
 Sampler::~Sampler()
@@ -50,11 +50,11 @@ void Sampler::SetUnitName( const std::string& unitName )
 
 void Sampler::SetTexture( BufferIndex bufferIndex, Integration::ResourceId textureId )
 {
-  mTextureId[bufferIndex] = textureId;
-
-  // @todo MESH_REWORK
-  //const BitmapMetadata& metadata  - get it from ResourceManager
-  //mBitmapMetadata[bufferIndex] = metadata;
+  if( mTextureId[bufferIndex] != textureId )
+  {
+    mTextureId.Set( bufferIndex, textureId );
+    mConnectionObservers.ConnectionsChanged(*this);
+  }
 }
 
 void Sampler::SetFilterMode( BufferIndex bufferIndex, FilterMode minFilter, FilterMode magFilter )
@@ -102,9 +102,14 @@ bool Sampler::AffectsTransparency( BufferIndex bufferIndex ) const
   return mAffectsTransparency[bufferIndex] ;
 }
 
+void Sampler::SetFullyOpaque( bool fullyOpaque )
+{
+  mFullyOpaque = fullyOpaque;
+}
+
 bool Sampler::IsFullyOpaque( BufferIndex bufferIndex ) const
 {
-  return mBitmapMetadata[bufferIndex].IsFullyOpaque();
+  return mFullyOpaque;
 }
 
 void Sampler::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
@@ -115,6 +120,26 @@ void Sampler::DisconnectFromSceneGraph(SceneController& sceneController, BufferI
 {
 }
 
+void Sampler::AddConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Add(observer);
+}
+
+void Sampler::RemoveConnectionObserver( ConnectionObservers::Observer& observer )
+{
+  mConnectionObservers.Remove(observer);
+}
+
+void Sampler::ResetDefaultProperties( BufferIndex bufferIndex )
+{
+  mTextureId.CopyPrevious( bufferIndex );
+  mMinFilter.CopyPrevious( bufferIndex );
+  mMagFilter.CopyPrevious( bufferIndex );
+  mUWrapMode.CopyPrevious( bufferIndex );
+  mVWrapMode.CopyPrevious( bufferIndex );
+  mAffectsTransparency.CopyPrevious( bufferIndex );
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index d50ccc5..a9f3817 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/double-buffered-property.h>
 #include <dali/internal/update/common/property-owner.h>
+#include <dali/internal/update/common/scene-graph-connection-observers.h>
 #include <dali/internal/update/resources/bitmap-metadata.h>
 #include <dali/internal/render/data-providers/sampler-data-provider.h>
 
@@ -87,6 +88,12 @@ public:
   bool AffectsTransparency( BufferIndex bufferIndex ) const;
 
   /**
+   * Sets whether the associated texture is fully opaque or not.
+   * @param[in] fullyOpaque true if it's fully opaque
+   */
+  void SetFullyOpaque( bool fullyOpaque );
+
+  /**
    * @param[in] bufferIndex The buffer index to use
    * @return true if the texture is fully opaque
    * @note this should only be called from Update thread
@@ -150,17 +157,26 @@ public: // SamplerDataProvider interface - called from RenderThread
    * @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);
 
-private:
-  std::string mUnitName; ///< The name of the uniform of the texture unit
-
-  // @todo MESH_REWORK Need these to automatically copy
-  // new value into old value on frame change
+  /**
+   * @copydoc ConnectionObservers::RemoveObserver
+   */
+  void RemoveConnectionObserver(ConnectionObservers::Observer& observer);
 
-  ResourceId mTextureId[2]; ///< The identity of the associated texture for this frame (Can be read from RenderThread)
+public: // PropertyOwner implementation
+  /**
+   * @copydoc Dali::Internal::SceneGraph::PropertyOwner::ResetDefaultProperties()
+   */
+  virtual void ResetDefaultProperties( BufferIndex updateBufferIndex );
 
-  BitmapMetadata mBitmapMetadata[2]; /// The meta data of the associated texture for this frame (Not needed in RenderThread)
+private:
+  std::string mUnitName; ///< The name of the uniform of the texture unit
 
+  DoubleBufferedProperty<unsigned int> mTextureId;
   DoubleBufferedProperty<int> mMinFilter;    ///< The minify filter
   DoubleBufferedProperty<int> mMagFilter;    ///< The magnify filter
   DoubleBufferedProperty<int> mUWrapMode;    ///< The horizontal wrap mode
@@ -168,6 +184,9 @@ private:
 
   // Note, this is only called from UpdateThread
   DoubleBufferedProperty<bool>     mAffectsTransparency; ///< If this sampler affects renderer transparency
+
+  ConnectionObservers mConnectionObservers; ///< Connection observers that will be informed when textures change.
+  bool mFullyOpaque; // Update only flag - no need for double buffering
 };
 
 } // namespace SceneGraph
index 582dd93..841fcf9 100644 (file)
@@ -99,7 +99,7 @@ void RendererAttachment::OnDestroy2()
 void RendererAttachment::ConnectedToSceneGraph()
 {
   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
-  mParent->AddUniformMapObserver( *this );
+  mParent->AddUniformMapObserver( *this ); // Watch actor's uniform maps
 
   DALI_ASSERT_DEBUG( mParent != NULL );
 
@@ -334,12 +334,16 @@ bool RendererAttachment::DoPrepareResources(
       const Sampler* sampler = static_cast<const Sampler*>(*iter);
 
       ResourceId textureId = sampler->GetTextureId( updateBufferIndex );
+      BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
+
+      Sampler* mutableSampler = const_cast<Sampler*>(sampler);
+      mutableSampler->SetFullyOpaque( metaData.IsFullyOpaque() );
+
       switch( completeStatusManager.GetStatus( textureId ) )
       {
         case CompleteStatusManager::NOT_READY:
         {
           ready = false;
-          BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
           if( metaData.GetIsFramebuffer() )
           {
             frameBufferCount++;
index ceaee68..c8bdfc3 100644 (file)
@@ -27,7 +27,8 @@ namespace Dali
 Sampler Sampler::New( Image& image, const std::string& textureUnitUniformName )
 {
   Internal::SamplerPtr sampler = Internal::Sampler::New(textureUnitUniformName);
-  sampler->SetImage( GetImplementation( image ) );
+  Internal::ImagePtr imagePtr = &GetImplementation( image );
+  sampler->SetImage( imagePtr );
   return Sampler( sampler.Get() );
 }
 
@@ -57,7 +58,8 @@ void Sampler::SetUniformName( const std::string& name )
 
 void Sampler::SetImage( Image& image )
 {
-  GetImplementation(*this).SetImage( GetImplementation( image ) );
+  Internal::ImagePtr imagePtr = &GetImplementation( image );
+  GetImplementation(*this).SetImage( imagePtr );
 }
 
 void Sampler::SetFilterMode( FilterMode minFilter, FilterMode magFilter )