From 7ef1a5ec75af08827cb02a1e2f0bbedd5230f898 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Thu, 22 Oct 2020 16:52:59 +0900 Subject: [PATCH] [Tizen] Fix a texture manager crash 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 --- .../src/dali-toolkit/utc-Dali-ImageView.cpp | 42 ++++++++++++++++++- .../internal/visuals/texture-manager-impl.cpp | 16 +++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index f31da7c8d8..2be7c5a762 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -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; +} diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index 1de8a806a2..6da900c524 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -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; + } + } } -- 2.34.1