Visual bases checks if visual already staged before adding to stage 93/97593/4
authorAgnelo Vaz <agnelo.vaz@samsung.com>
Mon, 14 Nov 2016 20:17:08 +0000 (20:17 +0000)
committerAgnelo Vaz <agnelo.vaz@samsung.com>
Tue, 15 Nov 2016 11:40:05 +0000 (11:40 +0000)
Fixes bug in which a stage visual can be staged again, caused a new renderer to be created and lost the handle to prevous renderer.
  Meant stray renderers could exist in the control. Leak!

Visual bases checks if visual already staged before adding to stage Fixes bug in which a staged visual can be staged again, caused a new renderer to be created and lost the handle to previous renderer. Meant stray a renderer could exist in the control. Leak! Can occur in control development or with direct use of Visual::SetOnStage. Control Example. Button:Setup { register visual A register visual B } Button::OnStageConnection { enable visual A (call 1) enable visual B Control::OnStageConnection; (call 2) } Call 1 initializes a renderer and puts it on stage. Call 2 initializes and puts on stage all registered visuals without checking if already staged.

Logging in control increased

Change-Id: I98383cac66e833b13765d8aef88767a3e09946b2

dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/public-api/controls/control-impl.cpp

index 54527de..084491a 100644 (file)
@@ -522,7 +522,7 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
 
 void ImageVisual::InitializeRenderer( const std::string& imageUrl )
 {
-  mImpl->mRenderer.Reset();
+  DALI_ASSERT_DEBUG( !mImpl->mRenderer && "Renderer should have been removed from stage and already reset before initialization" );
 
   mImageUrl = imageUrl;
   mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
@@ -586,8 +586,9 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
 
 void ImageVisual::InitializeRenderer( const Image& image )
 {
+  DALI_ASSERT_DEBUG( !mImpl->mRenderer && "Renderer should have been removed from stage and already reset before initialization" );
+
   mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
-  mImpl->mRenderer.Reset();
 
   // don't reuse CreateTextureSet
   TextureSet textures = TextureSet::New();
index 9cd41e0..e8ed4a3 100644 (file)
@@ -130,15 +130,18 @@ float Visual::Base::GetDepthIndex() const
 
 void Visual::Base::SetOnStage( Actor& actor )
 {
-  // To display the actor correctly, renderer should not be added to actor until all required resources are ready.
-  // Thus the calling of actor.AddRenderer() should happen inside derived class as base class does not know the exact timing.
-  DoSetOnStage( actor );
-
-  if( mImpl->mRenderer )
+  if( !IsOnStage() )
   {
-    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
-    mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
-    mImpl->mFlags |= Impl::IS_ON_STAGE; // Only sets the flag if renderer exists
+    // To display the actor correctly, renderer should not be added to actor until all required resources are ready.
+    // Thus the calling of actor.AddRenderer() should happen inside derived class as base class does not know the exact timing.
+    DoSetOnStage( actor );
+
+    if( mImpl->mRenderer )
+    {
+      mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
+      mImpl->mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex );
+      mImpl->mFlags |= Impl::IS_ON_STAGE; // Only sets the flag if renderer exists
+    }
   }
 }
 
index a01cc5e..90b3bb6 100644 (file)
@@ -803,6 +803,7 @@ void Control::EnableVisual( Property::Index index, bool enable )
   {
     if (  (*iter)->enabled == enable )
     {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Visual Already enabled set (%s) \n", enable?"enabled":"disabled");
       return;
     }
 
@@ -812,11 +813,12 @@ void Control::EnableVisual( Property::Index index, bool enable )
     {
       if ( enable )
       {
-
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting Visual(%d) on stage \n", index );
         Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
       }
       else
       {
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting Visual(%d) off stage \n", index );
         Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor );  // No need to call if control not staged.
       }
     }
@@ -1084,11 +1086,14 @@ void Control::EmitKeyInputFocusSignal( bool focusGained )
 
 void Control::OnStageConnection( int depth )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection number of registered visuals(%d)\n",  mImpl->mVisuals.Size() );
+
   for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
     // Check whether the visual is empty and enabled
     if( (*iter)->visual && (*iter)->enabled )
     {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection Setting visual(%d) on stage\n", (*iter)->index );
       Actor self( Self() );
       Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
     }
@@ -1102,6 +1107,7 @@ void Control::OnStageDisconnection()
     // Check whether the visual is empty
     if( (*iter)->visual )
     {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageDisconnection Setting visual(%d) off stage\n", (*iter)->index );
       Actor self( Self() );
       Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
     }