[Tizen] Fix a texture manager crash 58/251458/1 accepted/tizen/6.0/unified/20210114.121919 submit/tizen_6.0/20210114.052723
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 22 Oct 2020 07:52:59 +0000 (16:52 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 14 Jan 2021 04:42:21 +0000 (13:42 +0900)
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 f31da7c8d8765ed78272e14d719fcf0a4ee3ce2f..2be7c5a76232a09d3ac4be7e61e2aa77261c598a 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 1de8a806a21bba90be9b8176e2cd6c725f4e9315..6da900c524ae7bf593c63cd4f6c3963308a280ee 100644 (file)
@@ -824,6 +824,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 )
@@ -858,6 +860,11 @@ void TextureManager::ProcessQueuedTextures()
 {
   for( auto&& element : mLoadQueue )
   {
+    if( !element.mObserver )
+    {
+      continue;
+    }
+
     int cacheIndex = GetCacheIndexFromId( element.mTextureId );
     if( cacheIndex != INVALID_CACHE_INDEX )
     {
@@ -1298,6 +1305,15 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer )
       }
     }
   }
+
+  // Remove element from the LoadQueue
+  for( auto&& element : mLoadQueue )
+  {
+    if( element.mObserver == observer )
+    {
+      element.mObserver = nullptr;
+    }
+  }
 }