Fix a texture manager crash 63/246063/7
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 22 Oct 2020 07:52:59 +0000 (16:52 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 10 Nov 2020 02:32:30 +0000 (02:32 +0000)
In case of ReleasePolicy::NEVER,
Load an image in the UploadComplete callback, then it is inserted to the mLoadQueue
Delete the image visual before the queue is processed.
Then mObserver of LoadQueueElement has an invalid reference.

So reset the mObserver when the visual is deleted

Change-Id: Ie90e6374d419f614a1c08579b7591a7e21b43197

automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/visuals/texture-manager-impl.cpp

index f31da7c..2be7c5a 100644 (file)
@@ -2766,9 +2766,21 @@ void OnResourceReadySignal( Control control )
   }
 }
 
+void OnResourceReadySignal01( Control control )
+{
+  if(++gResourceReadySignalCounter == 1)
+  {
+    // It makes the first new visual be deleted immediately
+    // The first image will not be loaded.
+    control[ImageView::Property::IMAGE] = Property::Map().Add(ImageVisual::Property::URL, gImage_600_RGB)
+                                                         .Add(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER);
+    control[ImageView::Property::IMAGE] = TEST_IMAGE_1;
+  }
+}
+
 }
 
-int UtcDaliImageViewSetImageOnResourceReadySignal(void)
+int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
 {
   tet_infoline("Test setting image from within signal handler.");
 
@@ -2809,3 +2821,31 @@ int UtcDaliImageViewSetImageOnResourceReadySignal(void)
 
   END_TEST;
 }
+
+int UtcDaliImageViewSetImageOnResourceReadySignal02(void)
+{
+  tet_infoline("Test setting image from within signal handler.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalCounter = 0;
+
+  ImageView imageView = ImageView::New( gImage_34_RGBA );
+  imageView.ResourceReadySignal().Connect( &OnResourceReadySignal01 );
+
+  application.GetScene().Add( imageView );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for loading an image
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( gResourceReadySignalCounter, 2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( imageView.IsResourceReady(), true, TEST_LOCATION );
+
+  END_TEST;
+}
index 64bbb5b..5e0b506 100644 (file)
@@ -819,6 +819,8 @@ void TextureManager::QueueLoadTexture( TextureInfo& textureInfo, TextureUploadOb
 {
   auto textureId = textureInfo.textureId;
   mLoadQueue.PushBack( LoadQueueElement( textureId, observer) );
+
+  observer->DestructionSignal().Connect( this, &TextureManager::ObserverDestroyed );
 }
 
 void TextureManager::LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer )
@@ -853,6 +855,11 @@ void TextureManager::ProcessQueuedTextures()
 {
   for( auto&& element : mLoadQueue )
   {
+    if( !element.mObserver )
+    {
+      continue;
+    }
+
     int cacheIndex = GetCacheIndexFromId( element.mTextureId );
     if( cacheIndex != INVALID_CACHE_INDEX )
     {
@@ -1312,6 +1319,15 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer )
       }
     }
   }
+
+  // Remove element from the LoadQueue
+  for( auto&& element : mLoadQueue )
+  {
+    if( element.mObserver == observer )
+    {
+      element.mObserver = nullptr;
+    }
+  }
 }