From: Heeyong Song Date: Thu, 22 Oct 2020 07:52:59 +0000 (+0900) Subject: Fix a texture manager crash X-Git-Tag: dali_2.0.1~3^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=d1bd21955128a99337f9a377d524bf6ef1a1b8e4 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 --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index f31da7c..2be7c5a 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 64bbb5b..5e0b506 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -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; + } + } }