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 54527ded5998451197b6d50762112e7cfdb7bf3d..084491aef8b16b8b79486400f10167ee4ef94b8e 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 9cd41e074869c0c48a41277f5506dc23b68b3a5e..e8ed4a32f950f85a3637813717db1193fd70d75c 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 a01cc5e0788264b1d1709ab868691ad613f30750..90b3bb624ca08760f716bf86a5c5a3bc721cd146 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 );
     }