From 2d94f14d061ee4ecfc9e879d454e5b80a19bfd0b Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 18 May 2021 14:42:26 +0900 Subject: [PATCH] Fix texture manager crash mLoadQueue should not be changed in the range based loop. Change-Id: I7d469a650c78c4f1dfd3c7aa2bc01d0b432daa06 --- .../src/dali-toolkit/utc-Dali-ImageView.cpp | 65 ++++++++++++++++++++-- .../internal/visuals/texture-manager-impl.cpp | 3 +- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 29faa6d..1cd3de5 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -2743,7 +2743,7 @@ namespace static int gResourceReadySignalCounter = 0; -void OnResourceReadySignal( Control control ) +void OnResourceReadySignal01( Control control ) { gResourceReadySignalCounter++; @@ -2764,7 +2764,7 @@ void OnResourceReadySignal( Control control ) } } -void OnResourceReadySignal01( Control control ) +void OnResourceReadySignal02( Control control ) { if(++gResourceReadySignalCounter == 1) { @@ -2776,6 +2776,34 @@ void OnResourceReadySignal01( Control control ) } } +ImageView gImageView1; +ImageView gImageView2; +ImageView gImageView3; + +void OnResourceReadySignal03( Control control ) +{ + if(gResourceReadySignalCounter == 0) + { + // Queue loading + // 1. Use cached image, then UploadComplete will be called right after OnResourceReadySignal03. + gImageView2[ImageView::Property::IMAGE] = gImage_34_RGBA; + + // 2. Load a new image + gImageView3[ImageView::Property::IMAGE] = TEST_IMAGE_1; + + // 3. Use the new image again + gImageView1[ImageView::Property::IMAGE] = TEST_IMAGE_1; + gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal03); + } + else if(gResourceReadySignalCounter == 1) + { + // This is called from TextureManager::ProcessQueuedTextures(). + gImageView1.Unparent(); + gImageView1.Reset(); + } + gResourceReadySignalCounter++; +} + } int UtcDaliImageViewSetImageOnResourceReadySignal01(void) @@ -2787,7 +2815,7 @@ int UtcDaliImageViewSetImageOnResourceReadySignal01(void) gResourceReadySignalCounter = 0; ImageView imageView = ImageView::New( gImage_34_RGBA ); - imageView.ResourceReadySignal().Connect( &OnResourceReadySignal ); + imageView.ResourceReadySignal().Connect( &OnResourceReadySignal01 ); application.GetScene().Add( imageView ); @@ -2829,7 +2857,7 @@ int UtcDaliImageViewSetImageOnResourceReadySignal02(void) gResourceReadySignalCounter = 0; ImageView imageView = ImageView::New( gImage_34_RGBA ); - imageView.ResourceReadySignal().Connect( &OnResourceReadySignal01 ); + imageView.ResourceReadySignal().Connect( &OnResourceReadySignal02 ); application.GetScene().Add( imageView ); @@ -2847,3 +2875,32 @@ int UtcDaliImageViewSetImageOnResourceReadySignal02(void) END_TEST; } + +int UtcDaliImageViewSetImageOnResourceReadySignal03(void) +{ + tet_infoline("Test setting image from within signal handler."); + + ToolkitTestApplication application; + + gResourceReadySignalCounter = 0; + + gImageView1 = ImageView::New(gImage_34_RGBA); + application.GetScene().Add(gImageView1); + + // Wait for loading + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + gImageView2 = ImageView::New(gImage_600_RGB); + gImageView2.ResourceReadySignal().Connect(&OnResourceReadySignal03); + application.GetScene().Add(gImageView2); + + gImageView3 = ImageView::New(); + application.GetScene().Add(gImageView3); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + END_TEST; +} diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index 0d34d55..a449997 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -568,7 +568,8 @@ void TextureManager::Remove(const TextureManager::TextureId textureId, TextureUp { if(element.mObserver == observer) { - mLoadQueue.Erase(&element); + // Do not erase the item. We will clear it later in ProcessQueuedTextures(). + element.mObserver = nullptr; break; } } -- 2.7.4