From 93321d392ce358bff547eaf8fe02806ac2f62030 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 18 May 2021 14:42:26 +0900 Subject: [PATCH] [Tizen] 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 2be7c5a..5932129 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -2745,7 +2745,7 @@ namespace static int gResourceReadySignalCounter = 0; -void OnResourceReadySignal( Control control ) +void OnResourceReadySignal01( Control control ) { gResourceReadySignalCounter++; @@ -2766,7 +2766,7 @@ void OnResourceReadySignal( Control control ) } } -void OnResourceReadySignal01( Control control ) +void OnResourceReadySignal02( Control control ) { if(++gResourceReadySignalCounter == 1) { @@ -2778,6 +2778,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) @@ -2789,7 +2817,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 ); @@ -2831,7 +2859,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 ); @@ -2849,3 +2877,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 6da900c..64a874a 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -629,7 +629,8 @@ void TextureManager::Remove( const TextureManager::TextureId textureId, TextureU { 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