Merge "Refactored ControlRenderer so that derived classes are responsible for the...
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Tue, 27 Oct 2015 14:29:07 +0000 (07:29 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Tue, 27 Oct 2015 14:29:07 +0000 (07:29 -0700)
23 files changed:
automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp
dali-toolkit/devel-api/controls/renderer-factory/control-renderer.cpp
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp
dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/renderers/border/border-renderer.cpp
dali-toolkit/internal/controls/renderers/border/border-renderer.h
dali-toolkit/internal/controls/renderers/color/color-renderer.cpp
dali-toolkit/internal/controls/renderers/color/color-renderer.h
dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp
dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h
dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp
dali-toolkit/internal/controls/renderers/control-renderer-impl.h
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp
dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
dali-toolkit/internal/controls/renderers/image/image-renderer.h
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h
dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp
dali-toolkit/internal/controls/renderers/renderer-factory-impl.h
dali-toolkit/public-api/controls/control-impl.cpp

index e0b50d1..84df350 100644 (file)
@@ -262,7 +262,8 @@ int UtcDaliControlRendererGetPropertyMap1(void)
   DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::BLUE );
 
   // change the blend color
-  factory.ResetRenderer( colorRenderer, Color::CYAN );
+  Actor actor;
+  factory.ResetRenderer( colorRenderer, actor, Color::CYAN );
   colorRenderer.CreatePropertyMap( resultMap );
 
   colorValue = resultMap.Find( "blend-color", Property::VECTOR4 );
index 3b603b0..a3d65a7 100644 (file)
@@ -788,16 +788,14 @@ int UtcDaliRendererFactoryResetRenderer1(void)
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION );
 
-  bool isNewRenderer = factory.ResetRenderer( controlRenderer, Color::GREEN );
-  DALI_TEST_CHECK( !isNewRenderer );
+  factory.ResetRenderer( controlRenderer, actor, Color::GREEN );
   application.SendNotification();
   application.Render(0);
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, Color::GREEN, TEST_LOCATION );
 
   Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) );
-  isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage );
-  DALI_TEST_CHECK( isNewRenderer );
+  factory.ResetRenderer( controlRenderer, actor, bufferImage );
 
   Actor actor2 = Actor::New();
   actor2.SetSize(200.f, 200.f);
@@ -832,13 +830,11 @@ int UtcDaliRendererFactoryResetRenderer2(void)
   application.Render(0);
 
   Image bufferImage = CreateBufferImage( 100, 200, Vector4( 1.f, 1.f, 1.f, 1.f ) );
-  bool isNewRenderer = factory.ResetRenderer( controlRenderer, bufferImage );
-  DALI_TEST_CHECK( !isNewRenderer );
+  factory.ResetRenderer( controlRenderer, actor, bufferImage );
   application.SendNotification();
   application.Render(0);
 
-  isNewRenderer = factory.ResetRenderer( controlRenderer, Color::RED );
-  DALI_TEST_CHECK( isNewRenderer );
+  factory.ResetRenderer( controlRenderer, actor, Color::RED );
 
   Actor actor2 = Actor::New();
   actor2.SetSize(200.f, 200.f);
index c036334..36e5c02 100644 (file)
@@ -47,13 +47,13 @@ ControlRenderer& ControlRenderer::operator=( const ControlRenderer& handle )
 }
 
 ControlRenderer::ControlRenderer(Internal::ControlRenderer *impl)
-: BaseHandle(impl)
+: BaseHandle( impl )
 {
 }
 
 void ControlRenderer::SetSize( const Vector2& size )
 {
-  GetImplementation( *this ).SetSize(size);
+  GetImplementation( *this ).SetSize( size );
 }
 
 const Vector2& ControlRenderer::GetSize() const
@@ -68,7 +68,7 @@ void ControlRenderer::GetNaturalSize(Vector2& naturalSize ) const
 
 void ControlRenderer::SetDepthIndex( float index )
 {
-  GetImplementation( *this ).SetDepthIndex(index);
+  GetImplementation( *this ).SetDepthIndex( index );
 }
 
 float ControlRenderer::GetDepthIndex() const
@@ -78,12 +78,12 @@ float ControlRenderer::GetDepthIndex() const
 
 void ControlRenderer::SetOnStage( Actor& actor )
 {
-  GetImplementation( *this ).SetOnStage(actor);
+  GetImplementation( *this ).SetOnStage( actor );
 }
 
 void ControlRenderer::SetOffStage( Actor& actor )
 {
-  GetImplementation( *this ).SetOffStage(actor);
+  GetImplementation( *this ).SetOffStage( actor );
 }
 
 void ControlRenderer::RemoveAndReset( Actor& actor )
index 3f7ef6c..3ed8e73 100644 (file)
@@ -92,9 +92,9 @@ ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color )
   return GetImplementation( *this ).GetControlRenderer( color );
 }
 
-bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Vector4& color )
+void RendererFactory::ResetRenderer( ControlRenderer& renderer, Actor& actor, const Vector4& color )
 {
-  return GetImplementation( *this ).ResetRenderer( renderer, color );
+  GetImplementation( *this ).ResetRenderer( renderer, actor, color );
 }
 
 ControlRenderer RendererFactory::GetControlRenderer( float borderSize, const Vector4& borderColor )
@@ -107,9 +107,9 @@ ControlRenderer RendererFactory::GetControlRenderer( const Image& image )
   return GetImplementation( *this ).GetControlRenderer( image );
 }
 
-bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Image& image )
+void RendererFactory::ResetRenderer( ControlRenderer& renderer, Actor& actor, const Image& image )
 {
-  return GetImplementation( *this ).ResetRenderer( renderer, image );
+  GetImplementation( *this ).ResetRenderer( renderer, actor, image );
 }
 
 ControlRenderer RendererFactory::GetControlRenderer( const std::string& url )
@@ -117,14 +117,14 @@ ControlRenderer RendererFactory::GetControlRenderer( const std::string& url )
   return GetImplementation( *this ).GetControlRenderer( url );
 }
 
-bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const std::string& url )
+void RendererFactory::ResetRenderer( ControlRenderer& renderer, Actor& actor, const std::string& url )
 {
-  return GetImplementation( *this ).ResetRenderer( renderer, url );
+  GetImplementation( *this ).ResetRenderer( renderer, actor, url );
 }
 
-bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap )
+void RendererFactory::ResetRenderer( ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap )
 {
-  return GetImplementation( *this ).ResetRenderer( renderer, propertyMap );
+  GetImplementation( *this ).ResetRenderer( renderer, actor, propertyMap );
 }
 
 } // namespace Toolkit
index 13242f4..2e0c6c9 100644 (file)
@@ -109,10 +109,10 @@ public:
    * else the renderer would be a handle to a newly created internal color renderer.
    *
    * @param[in] renderer The ControlRenderer to reset
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] color The color to be rendered.
-   * @return Whether a new internal control renderer is created.
    */
-  bool ResetRenderer( ControlRenderer& renderer, const Vector4& color );
+  void ResetRenderer( ControlRenderer& renderer, Actor& actor, const Vector4& color );
 
   /**
    * @brief Request the control renderer to renderer the border with the given size and color.
@@ -138,10 +138,10 @@ public:
    * else the renderer would be a handle to a newly created internal image renderer.
    *
    * @param[in] renderer The ControlRenderer to reset
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] image The Image to be rendered.
-   * @return Whether a new internal control renderer is created.
    */
-  bool ResetRenderer( ControlRenderer& renderer, const Image& image );
+  void ResetRenderer( ControlRenderer& renderer, Actor& actor, const Image& image );
 
   /**
    * @brief Request the control renderer to render the given resource at the url.
@@ -158,10 +158,10 @@ public:
    * else the renderer would be a handle to a newly created internal image renderer.
    *
    * @param[in] renderer The ControlRenderer to reset
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] url The URL to the resource to be rendered.
-   * @return Whether a new internal control renderer is created.
    */
-  bool ResetRenderer( ControlRenderer& renderer, const std::string& url );
+  void ResetRenderer( ControlRenderer& renderer, Actor& actor, const std::string& url );
 
 
   /**
@@ -170,11 +170,12 @@ public:
    * if the current renderer is capable of merging with the property map the reset the renderer with the merged properties
    * else the renderer would be a handle to a newly created internal renderer.
    *
+   * @param[in] renderer The ControlRenderer to reset
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] propertyMap The map contains the properties required by the control renderer
    *            Depends on the content of the map, different kind of renderer would be returned.
-   * @return Whether a new internal control renderer is created.
    */
-  bool ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap );
+  void ResetRenderer( ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap );
 
 private:
 
index 2cb24bb..c7f1d8c 100644 (file)
@@ -73,24 +73,8 @@ void ImageView::SetImage( Image image )
 
     mImage = image;
 
-    bool newRendererCreated = false;
-    if( mRenderer )
-    {
-      newRendererCreated = Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, image );
-    }
-    else
-    {
-      mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( image );
-      newRendererCreated = true;
-    }
-
-    //we need to inform any newly created renderers if it is on stage
-    if( newRendererCreated && Self().OnStage() )
-    {
-      CustomActor self = Self();
-      mRenderer.SetOnStage( self );
-    }
-
+    Actor self = Self();
+    Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, image );
     mImageSize = image ? ImageDimensions( image.GetWidth(), image.GetHeight() ) : ImageDimensions( 0, 0 );
   }
 }
@@ -99,23 +83,8 @@ void ImageView::SetImage( Property::Map map )
 {
   mPropertyMap = map;
 
-  bool newRendererCreated = false;
-  if( mRenderer )
-  {
-    newRendererCreated = Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, mPropertyMap );
-  }
-  else
-  {
-    mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mPropertyMap );
-    newRendererCreated = true;
-  }
-
-  //we need to inform any newly created renderers if it is on stage
-  CustomActor self = Self();
-  if( newRendererCreated && self.OnStage() )
-  {
-    mRenderer.SetOnStage( self );
-  }
+  Actor self = Self();
+  Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mPropertyMap );
 
   int width = 0;
   Property::Value* widthValue = mPropertyMap.Find( "width" );
@@ -143,23 +112,8 @@ void ImageView::SetImage( const std::string& url )
 
     mUrl = url;
 
-    bool newRendererCreated = false;
-    if( mRenderer )
-    {
-      newRendererCreated = Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, mUrl );
-    }
-    else
-    {
-      mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mUrl );
-      newRendererCreated = true;
-    }
-
-    //we need to inform any newly created renderers if it is on stage
-    if( newRendererCreated && Self().OnStage() )
-    {
-      CustomActor self = Self();
-      mRenderer.SetOnStage( self );
-    }
+    Actor self = Self();
+    Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, self, mUrl );
 
     mImageSize = ResourceImage::GetImageSize( mUrl );
   }
index 1f2e178..43c6bde 100644 (file)
@@ -88,7 +88,7 @@ BorderRenderer::~BorderRenderer()
 {
 }
 
-void BorderRenderer::DoInitialize( const Property::Map& propertyMap )
+void BorderRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
   Property::Value* color = propertyMap.Find( COLOR_NAME );
   if( !( color && color->Get(mBorderColor) ) )
@@ -112,6 +112,8 @@ void BorderRenderer::SetClipRect( const Rect<int>& clipRect )
 
 void BorderRenderer::DoSetOnStage( Actor& actor )
 {
+  InitializeRenderer();
+
   mBorderColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBorderColor );
   if( mBorderColor.a < 1.f )
   {
@@ -128,7 +130,7 @@ void BorderRenderer::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( SIZE_NAME, mBorderSize );
 }
 
-void BorderRenderer::InitializeRenderer( Renderer& renderer )
+void BorderRenderer::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( RendererFactoryCache::BORDER_GEOMETRY );
   if( !geometry )
@@ -144,27 +146,15 @@ void BorderRenderer::InitializeRenderer( Renderer& renderer )
     mFactoryCache.SaveShader( RendererFactoryCache::BORDER_SHADER, shader );
   }
 
-  if( !renderer )
-  {
-    Material material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
-  }
-  else
-  {
-    mImpl->mRenderer.SetGeometry( geometry );
-    Material material = mImpl->mRenderer.GetMaterial();
-    if( material )
-    {
-      material.SetShader( shader );
-    }
-  }
+  Material material = Material::New( shader );
+  mImpl->mRenderer = Renderer::New( geometry, material );
 }
 
 void BorderRenderer::SetBorderColor(const Vector4& color)
 {
   mBorderColor = color;
 
-  if( mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
     (mImpl->mRenderer).SetProperty( mBorderColorIndex, color );
     if( color.a < 1.f &&  (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON)
@@ -178,7 +168,7 @@ void BorderRenderer::SetBorderSize( float size )
 {
   mBorderSize = size;
 
-  if( mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
     (mImpl->mRenderer).SetProperty( mBorderSizeIndex, size );
   }
index 859cf01..37c59d2 100644 (file)
@@ -71,12 +71,7 @@ protected:
   /**
    * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void DoInitialize( const Property::Map& propertyMap );
-
-  /**
-   * @copydoc ControlRenderer::InitializeRenderer
-   */
-  virtual void InitializeRenderer( Renderer& renderer );
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::DoSetOnStage
@@ -105,6 +100,11 @@ public:
 private:
 
   /**
+   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   */
+  void InitializeRenderer();
+
+  /**
    * Create the geometry which presents the border.
    * @return The border geometry
    */
index 4ca785d..5039c81 100644 (file)
@@ -77,7 +77,7 @@ ColorRenderer::~ColorRenderer()
 {
 }
 
-void ColorRenderer::DoInitialize( const Property::Map& propertyMap )
+void ColorRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
   Property::Value* color = propertyMap.Find( COLOR_NAME );
   if( !( color && color->Get(mBlendColor) ) )
@@ -105,6 +105,11 @@ void ColorRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
+void ColorRenderer::DoSetOnStage( Actor& actor )
+{
+  InitializeRenderer();
+}
+
 void ColorRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
@@ -112,7 +117,7 @@ void ColorRenderer::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( COLOR_NAME, mBlendColor );
 }
 
-void ColorRenderer::InitializeRenderer( Renderer& renderer )
+void ColorRenderer::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
   if( !geometry )
@@ -128,25 +133,13 @@ void ColorRenderer::InitializeRenderer( Renderer& renderer )
     mFactoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, shader );
   }
 
-  if( !renderer )
-  {
-    Material material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
-  }
-  else
-  {
-    mImpl->mRenderer.SetGeometry( geometry );
-    Material material = mImpl->mRenderer.GetMaterial();
-    if( material )
-    {
-      material.SetShader( shader );
-    }
-  }
+  Material material = Material::New( shader );
+  mImpl->mRenderer = Renderer::New( geometry, material );
 
-  mBlendColorIndex = renderer.RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor );
+  mBlendColorIndex = mImpl->mRenderer.RegisterProperty( COLOR_UNIFORM_NAME, mBlendColor );
   if( mBlendColor.a < 1.f )
   {
-    renderer.GetMaterial().SetBlendMode( BlendingMode::ON );
+    mImpl->mRenderer.GetMaterial().SetBlendMode( BlendingMode::ON );
   }
 }
 
@@ -154,7 +147,7 @@ void ColorRenderer::SetColor(const Vector4& color)
 {
   mBlendColor = color;
 
-  if( mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
     (mImpl->mRenderer).SetProperty( mBlendColorIndex, color );
     if( color.a < 1.f &&  (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON)
index 82071b5..70ad107 100644 (file)
@@ -82,12 +82,12 @@ protected:
   /**
    * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void DoInitialize( const Property::Map& propertyMap );
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc ControlRenderer::InitializeRenderer
+   * @copydoc ControlRenderer::DoSetOnStage
    */
-  virtual void InitializeRenderer( Renderer& renderer );
+  virtual void DoSetOnStage( Actor& actor );
 
 public:
 
@@ -98,6 +98,12 @@ public:
   void SetColor( const Vector4& color );
 
 private:
+  /**
+   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   */
+  void InitializeRenderer();
+
+private:
 
   // Undefined
   ColorRenderer( const ColorRenderer& colorRenderer );
index 6a58cfb..129ac03 100644 (file)
@@ -88,7 +88,7 @@ Shader::ShaderHints HintFromString( std::string hintString )
 Internal::ControlRenderer::Impl::Impl()
 : mCustomShader(NULL),
   mDepthIndex( 0.0f ),
-  mIsOnStage( false )
+  mFlags( 0 )
 {
 }
 
index c616669..3a5ccbb 100644 (file)
@@ -35,6 +35,12 @@ namespace Internal
 
 struct Internal::ControlRenderer::Impl
 {
+  enum Flags
+  {
+    IS_ON_STAGE = 1,
+    IS_FROM_CACHE = 1 << 1
+  };
+
   struct CustomShader
   {
     std::string mVertexShader;
@@ -47,7 +53,6 @@ struct Internal::ControlRenderer::Impl
     void CreatePropertyMap( Property::Map& map ) const;
   };
 
-  std::string mCachedRendererKey;  ///< The key to use for caching of the renderer. If it is empty then no caching will occur
   Renderer mRenderer;
 
   CustomShader* mCustomShader;
@@ -56,7 +61,7 @@ struct Internal::ControlRenderer::Impl
   Vector2   mOffset;
   Rect<int> mClipRect;
   float     mDepthIndex;
-  bool      mIsOnStage;
+  int       mFlags;
 
   Impl();
   ~Impl();
index 990182c..96f5066 100644 (file)
@@ -56,7 +56,7 @@ ControlRenderer::~ControlRenderer()
   delete mImpl;
 }
 
-void ControlRenderer::Initialize( const Property::Map& propertyMap )
+void ControlRenderer::Initialize( Actor& actor, const Property::Map& propertyMap )
 {
   if( mImpl->mCustomShader )
   {
@@ -74,12 +74,7 @@ void ControlRenderer::Initialize( const Property::Map& propertyMap )
       }
     }
   }
-  DoInitialize( propertyMap );
-
-  if( mImpl->mIsOnStage )
-  {
-    InitializeRenderer( mImpl->mRenderer );
-  }
+  DoInitialize( actor, propertyMap );
 }
 
 void ControlRenderer::SetSize( const Vector2& size )
@@ -121,67 +116,24 @@ float ControlRenderer::GetDepthIndex() const
   return mImpl->mDepthIndex;
 }
 
-void ControlRenderer::SetCachedRendererKey( const std::string& cachedRendererKey )
-{
-  if( mImpl->mCachedRendererKey == cachedRendererKey )
-  {
-    return;
-  }
-  if( !mImpl->mIsOnStage )
-  {
-    mImpl->mCachedRendererKey = cachedRendererKey;
-  }
-  else
-  {
-    //clean the renderer from the cache since it may no longer be in use
-    mFactoryCache.CleanRendererCache( mImpl->mCachedRendererKey );
-
-    //add the new renderer
-    mImpl->mCachedRendererKey = cachedRendererKey;
-    if( !mImpl->mCachedRendererKey.empty() && !mImpl->mCustomShader )
-    {
-      DALI_ASSERT_DEBUG( mImpl->mRenderer && "The control render is on stage but it doesn't have a valid renderer.");
-      mFactoryCache.SaveRenderer( mImpl->mCachedRendererKey, mImpl->mRenderer );
-    }
-  }
-}
-
 void ControlRenderer::SetOnStage( Actor& actor )
 {
-  if( !mImpl->mCachedRendererKey.empty() && !mImpl->mCustomShader )
-  {
-    mImpl->mRenderer = mFactoryCache.GetRenderer( mImpl->mCachedRendererKey );
-    if( !mImpl->mRenderer )
-    {
-      InitializeRenderer( mImpl->mRenderer );
-      mFactoryCache.SaveRenderer( mImpl->mCachedRendererKey, mImpl->mRenderer );
-    }
-  }
-
-  if( !mImpl->mRenderer )
-  {
-    InitializeRenderer( mImpl->mRenderer );
-  }
+  DoSetOnStage( actor );
 
   mImpl->mRenderer.SetDepthIndex( mImpl->mDepthIndex );
   actor.AddRenderer( mImpl->mRenderer );
-  mImpl->mIsOnStage = true;
-
-  DoSetOnStage( actor );
+  mImpl->mFlags |= Impl::IS_ON_STAGE;
 }
 
 void ControlRenderer::SetOffStage( Actor& actor )
 {
-  if( mImpl->mIsOnStage )
+  if( GetIsOnStage() )
   {
     DoSetOffStage( actor );
     actor.RemoveRenderer( mImpl->mRenderer );
     mImpl->mRenderer.Reset();
 
-    //clean the renderer from the cache since it may no longer be in use
-    mFactoryCache.CleanRendererCache( mImpl->mCachedRendererKey );
-
-    mImpl->mIsOnStage = false;
+    mImpl->mFlags &= ~Impl::IS_ON_STAGE;
   }
 }
 
@@ -202,6 +154,16 @@ void ControlRenderer::CreatePropertyMap( Property::Map& map ) const
   DoCreatePropertyMap( map );
 }
 
+bool ControlRenderer::GetIsOnStage() const
+{
+  return mImpl->mFlags & Impl::IS_ON_STAGE;
+}
+
+bool ControlRenderer::GetIsFromCache() const
+{
+  return mImpl->mFlags & Impl::IS_FROM_CACHE;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 10a13dc..7258e29 100644 (file)
@@ -67,9 +67,10 @@ public:
    *  request the geometry and shader from the cache, if not available, create and save to the cache for sharing;
    *  record the property values.
    *
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] propertyMap The properties for the requested ControlRenderer object.
    */
-  void Initialize( const Property::Map& propertyMap );
+  void Initialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
    * @copydoc Toolkit::ControlRenderer::SetSize
@@ -156,17 +157,10 @@ protected:
   /**
    * @brief Called by Initialize() allowing sub classes to respond to the Initialize event
    *
-   * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] propertyMap The properties for the requested ControlRenderer object.
    */
-  virtual void DoInitialize( const Property::Map& propertyMap ) = 0;
-
-  /**
-   * @brief Initialises a renderer ready to be put on stage.
-   *
-   * @param[inout] renderer The Renderer to initialise. If the renderer is not empty then re-initialise the renderer
-   */
-  virtual void InitializeRenderer( Renderer& renderer ) = 0;
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ) = 0;
 
 protected:
 
@@ -185,13 +179,19 @@ protected:
   virtual void DoSetOffStage( Actor& actor );
 
 protected:
+  /**
+   * @brief Gets the on stage state for this ControlRenderer
+   *
+   * @return Returns true if this ControlRenderer is on stage, false if it is off the stage
+   */
+  bool GetIsOnStage() const;
 
   /**
-   * @brief Sets the key to use for caching the renderer. If this is empty then no caching will occur
+   * @brief Gets whether the Dali::Renderer is from a shared cache (and therefore any modifications will affect other users of that renderer)
    *
-   * @param[in] cachedRendererKey The key to use for caching the renderer.
+   * @return Returns true if the renderer is from shared cache, false otherwise
    */
-  void SetCachedRendererKey( const std::string& cachedRendererKey );
+  bool GetIsFromCache() const;
 
 private:
 
index 6dc25ca..00a6050 100644 (file)
@@ -188,7 +188,7 @@ GradientRenderer::~GradientRenderer()
 {
 }
 
-void GradientRenderer::DoInitialize( const Property::Map& propertyMap )
+void GradientRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
   Gradient::GradientUnits gradientUnits = Gradient::OBJECT_BOUNDING_BOX;
   Property::Value* unitsValue = propertyMap.Find( GRADIENT_UNITS_NAME );
@@ -234,6 +234,11 @@ void GradientRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
+void GradientRenderer::DoSetOnStage( Actor& actor )
+{
+  InitializeRenderer();
+}
+
 void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
@@ -289,7 +294,7 @@ void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const
   }
 }
 
-void GradientRenderer::InitializeRenderer( Dali::Renderer& renderer )
+void GradientRenderer::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
   if( !geometry )
@@ -308,20 +313,8 @@ void GradientRenderer::InitializeRenderer( Dali::Renderer& renderer )
   }
 
   Material material;
-  if( !renderer )
-  {
-    material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
-  }
-  else
-  {
-    mImpl->mRenderer.SetGeometry( geometry );
-    material = mImpl->mRenderer.GetMaterial();
-    if( material )
-    {
-      material.SetShader( shader );
-    }
-  }
+  material = Material::New( shader );
+  mImpl->mRenderer = Renderer::New( geometry, material );
 
   Dali::BufferImage lookupTexture = mGradient->GenerateLookupTexture();
   Sampler sampler = Sampler::New();
@@ -330,7 +323,7 @@ void GradientRenderer::InitializeRenderer( Dali::Renderer& renderer )
 
   material.AddTexture( lookupTexture, UNIFORM_TEXTULRE_NAME, sampler );
 
-  renderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
+  mImpl->mRenderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform );
 }
 
 bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& propertyMap)
index deed3aa..0747a1c 100644 (file)
@@ -118,16 +118,21 @@ protected:
   /**
    * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void DoInitialize( const Property::Map& propertyMap );
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @copydoc ControlRenderer::InitializeRenderer
+   * @copydoc ControlRenderer::DoSetOnStage
    */
-  virtual void InitializeRenderer( Renderer& renderer );
+  virtual void DoSetOnStage( Actor& actor );
 
 private:
 
   /**
+   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   */
+  void InitializeRenderer();
+
+  /**
    * New a gradient object with the given property map.
    *
    * @return True if the property map provides valid properties to create a gradient. Otherwise, returns false.
index 8f02d85..ea055a4 100644 (file)
@@ -198,15 +198,16 @@ ImageRenderer::~ImageRenderer()
 {
 }
 
-void ImageRenderer::DoInitialize( const Property::Map& propertyMap )
+void ImageRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
+  std::string oldImageUrl = mImageUrl;
+
   Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
   if( imageURLValue )
   {
     imageURLValue->Get( mImageUrl );
     if( !mImageUrl.empty() )
     {
-      SetCachedRendererKey( mImageUrl );
       mImage.Reset();
     }
 
@@ -304,6 +305,37 @@ void ImageRenderer::DoInitialize( const Property::Map& propertyMap )
 
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
   }
+
+  if( mImpl->mRenderer )
+  {
+    //remove old renderer
+    if( actor )
+    {
+      actor.RemoveRenderer( mImpl->mRenderer );
+    }
+
+    //clean the cache
+    if( !oldImageUrl.empty() )
+    {
+      mFactoryCache.CleanRendererCache( oldImageUrl );
+    }
+
+    //Initialize the renderer
+    if( !mImageUrl.empty() )
+    {
+      InitializeRenderer( mImageUrl );
+    }
+    else if( mImage )
+    {
+      InitializeRenderer( mImage );
+    }
+
+    //add the new renderer to the actor
+    if( actor && mImpl->mRenderer )
+    {
+      actor.AddRenderer( mImpl->mRenderer );
+    }
+  }
 }
 
 void ImageRenderer::SetSize( const Vector2& size )
@@ -345,14 +377,14 @@ void ImageRenderer::SetOffset( const Vector2& offset )
 {
 }
 
-void ImageRenderer::InitializeRenderer( Renderer& renderer )
+Renderer ImageRenderer::CreateRenderer() const
 {
   Geometry geometry;
   Shader shader;
+
   if( !mImpl->mCustomShader )
   {
     geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
-
     shader = mFactoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
     if( !shader )
     {
@@ -363,7 +395,6 @@ void ImageRenderer::InitializeRenderer( Renderer& renderer )
   else
   {
     geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
-
     if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() )
     {
       shader = mFactoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
@@ -381,33 +412,82 @@ void ImageRenderer::InitializeRenderer( Renderer& renderer )
     }
   }
 
-  if( !renderer )
+  Material material = Material::New( shader );
+  return Renderer::New( geometry, material );
+}
+
+void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
+{
+  if( mImageUrl.empty() )
   {
-    Material material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
+    mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
+    return;
   }
-  else
+
+  mImpl->mRenderer.Reset();
+  if( !mImpl->mCustomShader )
   {
-    renderer.SetGeometry( geometry );
-    Material material = renderer.GetMaterial();
-    if( material )
+    mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl );
+    if( !mImpl->mRenderer )
     {
-      material.SetShader( shader );
+      mImpl->mRenderer = CreateRenderer();
+
+      ResourceImage image = Dali::ResourceImage::New( imageUrl );
+      image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+      Material material = mImpl->mRenderer.GetMaterial();
+      material.AddTexture( image, TEXTURE_UNIFORM_NAME );
+
+      mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer );
     }
+    mImpl->mFlags |= Impl::IS_FROM_CACHE;
+  }
+  else
+  {
+    mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
+    mImpl->mRenderer = CreateRenderer();
+    ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+    image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+    ApplyImageToSampler( image );
   }
 }
 
-void ImageRenderer::DoSetOnStage( Actor& actor )
+void ImageRenderer::InitializeRenderer( const Image& image )
 {
-  if( !mImageUrl.empty() && !mImage )
+  mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
+
+  if( !image )
   {
-    Dali::ResourceImage resourceImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
-    resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+    return;
+  }
+
+  mImpl->mRenderer = CreateRenderer();
+  ApplyImageToSampler( image );
+}
 
-    mImage = resourceImage;
+
+void ImageRenderer::DoSetOnStage( Actor& actor )
+{
+  if( !mImageUrl.empty() )
+  {
+    InitializeRenderer( mImageUrl );
   }
+  else if( mImage )
+  {
+    InitializeRenderer( mImage );
+  }
+
+  if( !GetIsFromCache() )
+  {
+    Image image = mImage;
+    if( !mImageUrl.empty() )
+    {
+      ResourceImage resourceImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+      resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+      image = resourceImage;
+    }
 
-  ApplyImageToSampler();
+    ApplyImageToSampler( image );
+  }
 }
 
 void ImageRenderer::DoSetOffStage( Actor& actor )
@@ -415,6 +495,9 @@ void ImageRenderer::DoSetOffStage( Actor& actor )
   //If we own the image then make sure we release it when we go off stage
   if( !mImageUrl.empty() )
   {
+    //clean the renderer from the cache since it may no longer be in use
+    mFactoryCache.CleanRendererCache( mImageUrl );
+
     mImage.Reset();
   }
 }
@@ -515,73 +598,114 @@ void ImageRenderer::DoCreatePropertyMap( Property::Map& map ) const
   }
 }
 
-void ImageRenderer::SetImage( const std::string& imageUrl )
+void ImageRenderer::SetImage( Actor& actor, const std::string& imageUrl )
 {
-  SetImage( imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT );
+  SetImage( actor, imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT );
 }
 
-void ImageRenderer::SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
+void ImageRenderer::SetImage( Actor& actor, const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
 {
   if( mImageUrl != imageUrl )
   {
+    if( mImpl->mRenderer )
+    {
+      if( GetIsFromCache() )
+      {
+        //remove old renderer
+        if( actor )
+        {
+          actor.RemoveRenderer( mImpl->mRenderer );
+        }
+
+        //clean the cache
+        if( !mImageUrl.empty() )
+        {
+          mFactoryCache.CleanRendererCache( mImageUrl );
+        }
+
+        //Initialize the renderer
+        InitializeRenderer( imageUrl );
+
+        //add the new renderer to the actor
+        if( actor && mImpl->mRenderer )
+        {
+          actor.AddRenderer( mImpl->mRenderer );
+        }
+      }
+      else
+      {
+        ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+        image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+        ApplyImageToSampler( image );
+      }
+    }
+
     mImageUrl = imageUrl;
-    SetCachedRendererKey( mImageUrl );
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
     mFittingMode = fittingMode;
     mSamplingMode = samplingMode;
-
-    if( !mImageUrl.empty() && mImpl->mIsOnStage )
-    {
-      Dali::ResourceImage resourceImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
-      resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
-      mImage = resourceImage;
-
-      ApplyImageToSampler();
-    }
-    else
-    {
-      mImage.Reset();
-    }
+    mImage.Reset();
   }
 }
 
-void ImageRenderer::SetImage( Image image )
+void ImageRenderer::SetImage( Actor& actor, const Image& image )
 {
   if( mImage != image )
   {
+    if( mImpl->mRenderer )
+    {
+      if( GetIsFromCache() )
+      {
+        //remove old renderer
+        if( actor )
+        {
+          actor.RemoveRenderer( mImpl->mRenderer );
+        }
+
+        //clean the cache
+        if( !mImageUrl.empty() )
+        {
+          mFactoryCache.CleanRendererCache( mImageUrl );
+        }
+
+        //Initialize the renderer
+        InitializeRenderer( image );
+
+        //add the new renderer to the actor
+        if( actor && mImpl->mRenderer )
+        {
+          actor.AddRenderer( mImpl->mRenderer );
+        }
+      }
+      else
+      {
+        ApplyImageToSampler( image );
+      }
+    }
+
+    mImage = image;
     mImageUrl.clear();
     mDesiredSize = ImageDimensions();
     mFittingMode = FittingMode::DEFAULT;
     mSamplingMode = SamplingMode::DEFAULT;
-    mImage = image;
-
-    if( mImage && mImpl->mIsOnStage )
-    {
-      ApplyImageToSampler();
-    }
   }
 }
 
-Image ImageRenderer::GetImage() const
-{
-  return mImage;
-}
-
-void ImageRenderer::ApplyImageToSampler()
+void ImageRenderer::ApplyImageToSampler( const Image& image )
 {
-  if( mImage )
+  if( image )
   {
     Material material = mImpl->mRenderer.GetMaterial();
     if( material )
     {
-      int index = material.GetTextureIndex(TEXTURE_UNIFORM_NAME);
+      int index = material.GetTextureIndex( TEXTURE_UNIFORM_NAME );
       if( index != -1 )
       {
-        material.SetTextureImage( index, mImage );
+        material.SetTextureImage( index, image );
         return;
       }
 
-      material.AddTexture( mImage,TEXTURE_UNIFORM_NAME );
+      material.AddTexture( image, TEXTURE_UNIFORM_NAME );
     }
   }
 }
@@ -590,10 +714,10 @@ void ImageRenderer::OnImageLoaded( ResourceImage image )
 {
   if( image.GetLoadingState() == Dali::ResourceLoadingFailed )
   {
-    mImage = RendererFactory::GetBrokenRendererImage();
-    if( mImpl->mIsOnStage )
+    Image image = RendererFactory::GetBrokenRendererImage();
+    if( mImpl->mRenderer )
     {
-      ApplyImageToSampler();
+      ApplyImageToSampler( image );
     }
   }
 }
index efcbf53..e01efd0 100644 (file)
@@ -116,7 +116,7 @@ protected:
   /**
    * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void DoInitialize( const Property::Map& propertyMap );
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::DoSetOnStage
@@ -128,53 +128,67 @@ protected:
    */
   virtual void DoSetOffStage( Actor& actor );
 
-  /**
-   * @copydoc ControlRenderer::InitializeRenderer
-   */
-  virtual void InitializeRenderer( Renderer& renderer );
-
 public:
 
   /**
    * @brief Sets the image of this renderer to the resource at imageUrl
    * The renderer will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
    *
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] imageUrl The URL to to image resource to use
    */
-  void SetImage( const std::string& imageUrl );
+  void SetImage( Actor& actor, const std::string& imageUrl );
 
   /**
    * @brief Sets the image of this renderer to the resource at imageUrl
    * The renderer will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
    *
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] imageUrl The URL to to image resource to use
    * @param[in] desiredWidth The desired width of the resource to load
    * @param[in] desiredHeight The desired height of the resource to load
    * @param[in] fittingMode The FittingMode of the resource to load
    * @param[in] samplingMode The SamplingMode of the resource to load
    */
-  void SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode );
+  void SetImage( Actor& actor, const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode );
 
   /**
    * @brief Sets the image of this renderer to use
    *
+   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
    * @param[in] image The image to use
    */
-  void SetImage( Image image );
+  void SetImage( Actor& actor, const Image& image );
+
+private:
 
   /**
-   * @brief Gets the image this renderer uses
+   * @brief Applies the image to the material used for this renderer
    *
-   * @return The image this renderer uses, which may be null if the image is set from a URL string and the renderer is not set as onstage
+   * @param[in] image The Image to apply to the material used for this renderer
    */
-  Image GetImage() const;
+  void ApplyImageToSampler( const Image& image );
 
-private:
+  /**
+   * @brief Initializes the Dali::Renderer from an image url string
+   *
+   * @param[in] imageUrl The image url string to intialize this ImageRenderer from
+   */
+  void InitializeRenderer( const std::string& imageUrl );
 
   /**
-   * @brief Applies this renderer's image to the sampler to the material used for this renderer
+   * @brief Initializes the Dali::Renderer from an image handle
+   *
+   * @param[in] image The image handle to intialize this ImageRenderer from
+   */
+  void InitializeRenderer( const Image& image );
+
+  /**
+   * @brief Creates the Dali::Renderer (potentially from the renderer cache), initializing it
+   *
+   * @return Returns the created Dali::Renderer
    */
-  void ApplyImageToSampler();
+  Renderer CreateRenderer() const;
 
   /**
    * Callback function of image resource loading succeed
index 8e509a9..64a1763 100644 (file)
@@ -217,7 +217,7 @@ NPatchRenderer::~NPatchRenderer()
 {
 }
 
-void NPatchRenderer::DoInitialize( const Property::Map& propertyMap )
+void NPatchRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 {
   Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
   if( imageURLValue )
@@ -272,10 +272,9 @@ void NPatchRenderer::SetOffset( const Vector2& offset )
   //ToDo: renderer applies the offset
 }
 
-void NPatchRenderer::InitializeRenderer( Renderer& renderer )
+Geometry NPatchRenderer::CreateGeometry()
 {
   Geometry geometry;
-  Shader shader;
   if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
   {
     if( !mBorderOnly )
@@ -296,7 +295,21 @@ void NPatchRenderer::InitializeRenderer( Renderer& renderer )
         mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry );
       }
     }
+  }
+  else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+  {
+    Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1,  2 * mStretchPixelsY.Size() + 1 );
+    geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize );
+  }
+
+  return geometry;
+}
 
+Shader NPatchRenderer::CreateShader()
+{
+  Shader shader;
+  if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
+  {
     shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
     if( !shader )
     {
@@ -306,9 +319,6 @@ void NPatchRenderer::InitializeRenderer( Renderer& renderer )
   }
   else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
   {
-    Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1,  2 * mStretchPixelsY.Size() + 1 );
-    geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize );
-
     std::stringstream vertexShader;
     vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
                  << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
@@ -316,28 +326,25 @@ void NPatchRenderer::InitializeRenderer( Renderer& renderer )
 
     shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
   }
-  else
+  return shader;
+}
+
+void NPatchRenderer::InitializeRenderer()
+{
+  Geometry geometry = CreateGeometry();
+  Shader shader = CreateShader();
+
+  if( !geometry || !shader )
   {
     DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() );
     InitializeFromBrokenImage();
   }
 
-  if( !renderer )
-  {
-    Material material = Material::New( shader );
-    renderer = Renderer::New( geometry, material );
-  }
-  else
-  {
-    mImpl->mRenderer.SetGeometry( geometry );
-    Material material = mImpl->mRenderer.GetMaterial();
-    if( material )
-    {
-      material.SetShader( shader );
-    }
-  }
+  Material material = Material::New( shader );
+  mImpl->mRenderer = Renderer::New( geometry, material );
 }
 
+
 void NPatchRenderer::DoSetOnStage( Actor& actor )
 {
   if( !mCroppedImage )
@@ -351,10 +358,11 @@ void NPatchRenderer::DoSetOnStage( Actor& actor )
     {
       InitializeFromImage( mImage );
     }
-
-    InitializeRenderer( mImpl->mRenderer );
   }
 
+  //initialize the renderer after initializing from the image since we need to know the grid size from the image before creating the geometry
+  InitializeRenderer();
+
   if( mCroppedImage )
   {
     ApplyImageToSampler();
@@ -381,8 +389,52 @@ void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( BORDER_ONLY, mBorderOnly );
 }
 
+void NPatchRenderer::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY )
+{
+  //check to see if the border style has changed
+
+  bool borderOnlyChanged = oldBorderOnly != mBorderOnly;
+  bool gridChanged = oldGridX != mStretchPixelsX.Size() || oldGridY != mStretchPixelsY.Size();
+
+  if( borderOnlyChanged || gridChanged )
+  {
+    Geometry geometry = CreateGeometry();
+    if( geometry )
+    {
+      mImpl->mRenderer.SetGeometry( geometry );
+    }
+    else
+    {
+      InitializeFromBrokenImage();
+    }
+  }
+
+  if( gridChanged )
+  {
+    Shader shader = CreateShader();
+    Material material;
+    if( shader )
+    {
+      material = mImpl->mRenderer.GetMaterial();
+      if( material )
+      {
+        material.SetShader( shader );
+      }
+    }
+
+    if( !material )
+    {
+      InitializeFromBrokenImage();
+    }
+  }
+}
+
 void NPatchRenderer::SetImage( const std::string& imageUrl, bool borderOnly )
 {
+  bool oldBorderOnly = mBorderOnly;
+  size_t oldGridX = mStretchPixelsX.Size();
+  size_t oldGridY = mStretchPixelsY.Size();
+
   mBorderOnly = borderOnly;
   mImage.Reset();
   if( mImageUrl == imageUrl )
@@ -391,17 +443,26 @@ void NPatchRenderer::SetImage( const std::string& imageUrl, bool borderOnly )
   }
 
   mImageUrl = imageUrl;
-  NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
-  InitializeFromImage( nPatch );
-
-  if( mCroppedImage && mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
-    ApplyImageToSampler();
+    NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
+    InitializeFromImage( nPatch );
+
+    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
+
+    if( mCroppedImage )
+    {
+      ApplyImageToSampler();
+    }
   }
 }
 
 void NPatchRenderer::SetImage( NinePatchImage image, bool borderOnly )
 {
+  bool oldBorderOnly = mBorderOnly;
+  size_t oldGridX = mStretchPixelsX.Size();
+  size_t oldGridY = mStretchPixelsY.Size();
+
   mBorderOnly = borderOnly;
   mImageUrl.empty();
   if( mImage == image )
@@ -410,11 +471,15 @@ void NPatchRenderer::SetImage( NinePatchImage image, bool borderOnly )
   }
 
   mImage = image;
-  InitializeFromImage( mImage );
-
-  if( mCroppedImage && mImpl->mIsOnStage )
+  if( mImpl->mRenderer )
   {
-    ApplyImageToSampler();
+    InitializeFromImage( mImage );
+    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
+
+    if( mCroppedImage )
+    {
+      ApplyImageToSampler();
+    }
   }
 }
 
index c17b167..0844e7b 100644 (file)
@@ -92,12 +92,7 @@ protected:
   /**
    * @copydoc ControlRenderer::DoInitialize
    */
-  virtual void DoInitialize( const Property::Map& propertyMap );
-
-  /**
-   * @copydoc ControlRenderer::InitializeRenderer
-   */
-  virtual void InitializeRenderer( Renderer& renderer );
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
    * @copydoc ControlRenderer::DoSetOnStage
@@ -131,9 +126,28 @@ public:
 private:
 
   /**
+   * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing.
+   */
+  void InitializeRenderer();
+
+  /**
+   * @brief Creates a geometry for this renderer's grid size
+   *
+   * @return Returns the created geometry for this renderer's grid size
+   */
+  Geometry CreateGeometry();
+
+  /**
+   * @brief Creates a shader for this renderer's grid size
+   *
+   * @return Returns the created shader for this renderer's grid size
+   */
+  Shader CreateShader();
+
+  /**
    * @brief Creates a geometry for the grid size to be used by this renderers' shaders
    *
-   * @param gridSize The grid size of the solid geometry to create
+   * @param[in] gridSize The grid size of the solid geometry to create
    * @return Returns the created geometry for the grid size
    */
   Geometry CreateGeometry( Uint16Pair gridSize );
@@ -156,7 +170,7 @@ private:
    *   |/  |/  |/  |/  |/  |
    *   ---------------------
    *
-   * @param gridSize The grid size of the solid geometry to create
+   * @param[in] gridSize The grid size of the solid geometry to create
    * @return Returns the created geometry for the grid size
    */
   Geometry CreateGeometryBorder( Uint16Pair gridSize );
@@ -164,7 +178,7 @@ private:
   /**
    * @brief Creates Image from the image url and parses the image for the stretch borders. Will create a error image if the n patch image is invalid
    *
-   * @param nPatchImage The NinePatchImage to base our cropped images and stretch borders from
+   * @param[in] nPatchImage The NinePatchImage to base our cropped images and stretch borders from
    */
   void InitializeFromImage( NinePatchImage nPatchImage );
 
@@ -179,6 +193,15 @@ private:
    */
   void ApplyImageToSampler();
 
+  /**
+   * @brief Changes the current renderer if the n-patch meta data has changed
+   *
+   * @param[in] oldBorderOnly The old flag indicating if the image should omit the centre of the n-patch and only render the border
+   * @param[in] oldGridX The old horizontal grid size of the solid geometry
+   * @param[in] oldGridY The old vertical grid size of the solid geometry
+   */
+  void ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY );
+
 private:
 
   NinePatchImage mImage; ///< The image to render if the renderer was set from an NinePatchImage, empty otherwise
index ddac18e..a91aa71 100644 (file)
@@ -114,7 +114,8 @@ Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Ma
 
   if( rendererPtr )
   {
-    rendererPtr->Initialize( propertyMap );
+    Actor actor;
+    rendererPtr->Initialize( actor, propertyMap );
   }
   else
   {
@@ -137,18 +138,22 @@ Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Vector4& col
   return Toolkit::ControlRenderer( rendererPtr );
 }
 
-bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color )
+void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Vector4& color )
 {
   ColorRenderer* rendererPtr = dynamic_cast< ColorRenderer* >( &GetImplementation( renderer ) );
   if( rendererPtr )
   {
     rendererPtr->SetColor( color );
-    return false;
   }
   else
   {
+    renderer.RemoveAndReset( actor );
     renderer = GetControlRenderer( color );
-    return true;
+
+    if( actor.OnStage() )
+    {
+      renderer.SetOnStage( actor );
+    }
   }
 }
 
@@ -189,36 +194,44 @@ Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Image& image
   else
   {
     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ) );
-    rendererPtr->SetImage( image );
+    Actor actor;
+    rendererPtr->SetImage( actor, image );
 
     return Toolkit::ControlRenderer( rendererPtr );
   }
 }
 
-bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image )
+void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Image& image )
 {
-  NinePatchImage npatchImage = NinePatchImage::DownCast( image );
-  if( npatchImage )
+  if( renderer )
   {
-    NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
-    if( rendererPtr )
+    NinePatchImage npatchImage = NinePatchImage::DownCast( image );
+    if( npatchImage )
     {
-      rendererPtr->SetImage( npatchImage );
-      return false;
+      NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
+      if( rendererPtr )
+      {
+        rendererPtr->SetImage( npatchImage );
+        return;
+      }
     }
-  }
-  else
-  {
-    ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
-    if( rendererPtr )
+    else
     {
-      rendererPtr->SetImage( image );
-      return false;
+      ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
+      if( rendererPtr )
+      {
+        rendererPtr->SetImage( actor, image );
+        return;
+      }
     }
   }
 
+  renderer.RemoveAndReset( actor );
   renderer = GetControlRenderer( image );
-  return true;
+  if( actor.OnStage() )
+  {
+    renderer.SetOnStage( actor );
+  }
 }
 
 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const std::string& url )
@@ -238,75 +251,88 @@ Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const std::string&
   else
   {
     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ) );
-    rendererPtr->SetImage( url );
+    Actor actor;
+    rendererPtr->SetImage( actor, url );
 
     return Toolkit::ControlRenderer( rendererPtr );
   }
 }
 
-bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const std::string& url )
+void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const std::string& url )
 {
-  if( NinePatchImage::IsNinePatchUrl( url ) )
+  if( renderer )
   {
-    NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
-    if( rendererPtr )
+    if( NinePatchImage::IsNinePatchUrl( url ) )
     {
-      rendererPtr->SetImage( url );
-      return false;
+      NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
+      if( rendererPtr )
+      {
+        rendererPtr->SetImage( url );
+        return;
+      }
     }
-  }
-  else
-  {
-    ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
-    if( rendererPtr )
+    else
     {
-      rendererPtr->SetImage( url );
-      return false;
+      ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
+      if( rendererPtr )
+      {
+        rendererPtr->SetImage( actor, url );
+        return;
+      }
     }
   }
 
+  renderer.RemoveAndReset( actor );
+  renderer = GetControlRenderer( url );
+  if( actor.OnStage() )
   {
-    renderer = GetControlRenderer( url );
-    return true;
+    renderer.SetOnStage( actor );
   }
 }
 
-bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap )
+void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap )
 {
-  Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
-  std::string typeValue ;
-  if( type && type->Get( typeValue ))
+  if( renderer )
   {
-    //If there's been a renderer type change then we have to return a new shader
-    if( typeValue ==  COLOR_RENDERER && typeid( renderer ) != typeid( ColorRenderer ) )
-    {
-      renderer = GetControlRenderer( propertyMap );
-      return true;
-    }
-    else if( typeValue ==  GRADIENT_RENDERER && typeid( renderer ) != typeid( GradientRenderer ) )
-    {
-      renderer = GetControlRenderer( propertyMap );
-      return true;
-    }
-    else if( typeValue ==  IMAGE_RENDERER && typeid( renderer ) != typeid( ImageRenderer ) )
+    Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
+    std::string typeValue ;
+    if( type && type->Get( typeValue ))
     {
-      renderer = GetControlRenderer( propertyMap );
-      return true;
-    }
-    else if( typeValue ==  N_PATCH_RENDERER && typeid( renderer ) != typeid( NPatchRenderer ) )
-    {
-      renderer = GetControlRenderer( propertyMap );
-      return true;
-    }
-    else if( typeValue ==  BORDER_RENDERER && typeid( renderer ) != typeid( BorderRenderer ) )
-    {
-      renderer = GetControlRenderer( propertyMap );
-      return true;
+      //If there's been a renderer type change then we have to return a new shader
+      if( typeValue ==  COLOR_RENDERER && typeid( renderer ) != typeid( ColorRenderer ) )
+      {
+        renderer = GetControlRenderer( propertyMap );
+        return;
+      }
+      else if( typeValue ==  GRADIENT_RENDERER && typeid( renderer ) != typeid( GradientRenderer ) )
+      {
+        renderer = GetControlRenderer( propertyMap );
+        return;
+      }
+      else if( typeValue ==  IMAGE_RENDERER && typeid( renderer ) != typeid( ImageRenderer ) )
+      {
+        renderer = GetControlRenderer( propertyMap );
+        return;
+      }
+      else if( typeValue ==  N_PATCH_RENDERER && typeid( renderer ) != typeid( NPatchRenderer ) )
+      {
+        renderer = GetControlRenderer( propertyMap );
+        return;
+      }
+      else if( typeValue ==  BORDER_RENDERER && typeid( renderer ) != typeid( BorderRenderer ) )
+      {
+        renderer = GetControlRenderer( propertyMap );
+        return;
+      }
     }
+
+    GetImplementation( renderer ).Initialize( actor, propertyMap );
+  }
+  else
+  {
+    renderer = GetControlRenderer( propertyMap );
   }
 
-  GetImplementation( renderer ).Initialize( propertyMap );
-  return false;
 }
 
 Image RendererFactory::GetBrokenRendererImage()
index a76c572..fed299a 100644 (file)
@@ -55,9 +55,9 @@ public:
   Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap );
 
   /**
-   * @copydoc Toolkit::RenderFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap )
+   * @copydoc Toolkit::RenderFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap )
    */
-  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap );
+  void ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap );
 
   /**
    * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Vector4& )
@@ -65,9 +65,9 @@ public:
   Toolkit::ControlRenderer GetControlRenderer( const Vector4& color );
 
   /**
-   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Vector4& )
+   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, Actor& actor, const Vector4& )
    */
-  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Vector4& color );
+  void ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Vector4& color );
 
   /**
    * @copydoc Toolkit::RenderFactory::GetControlRenderer( float, const Vector4& )
@@ -80,9 +80,9 @@ public:
   Toolkit::ControlRenderer GetControlRenderer( const Image& image );
 
   /**
-   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const Image& )
+   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, Actor& actor, const Image& )
    */
-  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Image& image );
+  void ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Image& image );
 
   /**
    * @copydoc Toolkit::RenderFactory::GetControlRenderer( const std::string& )
@@ -90,9 +90,9 @@ public:
   Toolkit::ControlRenderer GetControlRenderer( const std::string& image );
 
   /**
-   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, const std::string& )
+   * @copydoc Toolkit::RendererFactory::ResetRenderer( Toolkit::ControlRenderer&, Actor& actor, const std::string& )
    */
-  bool ResetRenderer( Toolkit::ControlRenderer& renderer, const std::string& image );
+  void ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const std::string& image );
 
 public:
   /**
index a009273..771114b 100644 (file)
@@ -406,24 +406,17 @@ void Control::SetBackgroundColor( const Vector4& color )
 
   if( mImpl->mBackgroundRenderer )
   {
-    Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer );
-    // if ResetRenderer returns false, we continue to use the current renderer with a new color set to it.
-    if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, color ) )
-    {
-      return;
-    }
-    // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset.
-    currentRenderer.RemoveAndReset( self );
+    factory.ResetRenderer( mImpl->mBackgroundRenderer, self, color );
   }
   else
   {
     mImpl->mBackgroundRenderer = factory.GetControlRenderer( color );
-  }
 
-  if( self.OnStage() )
-  {
-    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
-    mImpl->mBackgroundRenderer.SetOnStage( self );
+    if( self.OnStage() )
+    {
+      mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+      mImpl->mBackgroundRenderer.SetOnStage( self );
+    }
   }
 }
 
@@ -463,30 +456,23 @@ void Control::SetBackgroundImage( Image image )
 
   if(  mImpl->mBackgroundRenderer  )
   {
-    Toolkit::ControlRenderer currentRenderer( mImpl->mBackgroundRenderer );
-    // if ResetRenderer returns false, we continue to use the current renderer with a new image set to it.
-    if( ! factory.ResetRenderer( mImpl->mBackgroundRenderer, image )  )
-    {
-      return;
-    }
-    // ResetRenderer returns true, a new renderer is created. Remove the current renderer and reset.
-    currentRenderer.RemoveAndReset( self );
+    factory.ResetRenderer( mImpl->mBackgroundRenderer, self, image );
   }
   else
   {
     mImpl->mBackgroundRenderer = factory.GetControlRenderer( image );
-  }
 
-  if( self.OnStage() )
-  {
-    mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
-    mImpl->mBackgroundRenderer.SetOnStage( self );
+    if( self.OnStage() )
+    {
+      mImpl->mBackgroundRenderer.SetDepthIndex( BACKGROUND_DEPTH_INDEX );
+      mImpl->mBackgroundRenderer.SetOnStage( self );
+    }
   }
 }
 
 void Control::ClearBackground()
 {
-  Actor self(Self());
+  Actor self( Self() );
   mImpl->mBackgroundRenderer.RemoveAndReset( self );
 }