X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=automated-tests%2Fsrc%2Fdali-toolkit-internal%2Futc-Dali-TextureManager.cpp;h=a4e177c1f45c54da8c39546f3b4e511f4c0a3d45;hb=b4d1395ea5d996b13d3f655c767bf909c3595b36;hp=f12b096ef705e32a87bef1be9a76960d7ae482b1;hpb=b37f87135b28813d5d43ed891f5e1d72ad2d9694;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp index f12b096..a4e177c 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -28,6 +29,8 @@ #include #include #include ///< For VisualFactory's member TextureManager. +#include +#include #include #include @@ -60,6 +63,9 @@ const char* TEST_IMAGE_3_FILE_NAME = TEST_RESOURCE_DIR "/icon-edit.png"; const char* TEST_IMAGE_4_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-20.png"; const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png"; +const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg"; +const char* TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json"; + class TestObserver : public Dali::Toolkit::TextureUploadObserver { public: @@ -124,7 +130,7 @@ public: mTextureSet = textureInformation.textureSet; // Remove during LoadComplete - mTextureManagerPtr->Remove(textureInformation.textureId, nullptr); + mTextureManagerPtr->RequestRemove(textureInformation.textureId, nullptr); // ...And generate string which using texture id. mGeneratedExternalUrl = mTextureManagerPtr->AddExternalTexture(mTextureSet); @@ -202,7 +208,6 @@ int UtcTextureManagerRequestLoad(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer, true, TextureManager::ReloadPolicy::CACHED, @@ -229,7 +234,6 @@ int UtcTextureManagerGenerateHash(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer, true, TextureManager::ReloadPolicy::CACHED, @@ -256,7 +260,7 @@ int UtcTextureManagerEncodedImageBuffer(void) std::string url1 = textureManager.AddEncodedImageBuffer(buffer1); std::string url2 = textureManager.AddEncodedImageBuffer(buffer1); - std::string url3 = VisualUrl::CreateBufferUrl(""); ///< Impossible Buffer URL. for coverage + std::string url3 = VisualUrl::CreateBufferUrl("", ""); ///< Impossible Buffer URL. for coverage // Check if same EncodedImageBuffer get same url DALI_TEST_CHECK(url1 == url2); @@ -277,7 +281,6 @@ int UtcTextureManagerEncodedImageBuffer(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer1, true, ///< orientationCorrection TextureManager::ReloadPolicy::CACHED, @@ -351,7 +354,6 @@ int UtcTextureManagerEncodedImageBuffer(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer3, true, ///< orientationCorrection TextureManager::ReloadPolicy::CACHED, @@ -368,7 +370,6 @@ int UtcTextureManagerEncodedImageBuffer(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer4, true, ///< orientationCorrection TextureManager::ReloadPolicy::FORCED, @@ -435,6 +436,325 @@ int UtcTextureManagerEncodedImageBuffer(void) END_TEST; } +int UtcTextureManagerEncodedImageBufferWithImageType(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerEncodedImageBufferWithImageType"); + + auto visualFactory = Toolkit::VisualFactory::Get(); + auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager + + // Get encoded raw-buffer image and generate url + EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_SVG_FILE_NAME); + EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME); + + std::string url1 = textureManager.AddEncodedImageBuffer(buffer1); + std::string url2 = textureManager.AddEncodedImageBuffer(buffer1); + + // Check if same EncodedImageBuffer get same url + DALI_TEST_CHECK(url1 == url2); + // Reduce reference count + textureManager.RemoveEncodedImageBuffer(url1); + // Check whethere url1 still valid + DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1)); + + url2 = textureManager.AddEncodedImageBuffer(buffer2); + // Check if difference EncodedImageBuffer get difference url + DALI_TEST_CHECK(url1 != url2); + + buffer1.SetImageType(EncodedImageBuffer::ImageType::VECTOR_IMAGE); + buffer2.SetImageType(EncodedImageBuffer::ImageType::ANIMATED_VECTOR_IMAGE); + + std::string url1AfterType = textureManager.AddEncodedImageBuffer(buffer1); + std::string url2AfterType = textureManager.AddEncodedImageBuffer(buffer2); + + // Check if EncodedImageBuffer with imagetype get difference url. + DALI_TEST_CHECK(url1 != url1AfterType); + DALI_TEST_CHECK(url2 != url2AfterType); + DALI_TEST_CHECK(url1AfterType != url2AfterType); + + int bufferId = std::atoi(VisualUrl::GetLocationWithoutExtension(url1AfterType).c_str()); + auto urlFromBuffer = textureManager.GetVisualUrl(bufferId); + + // Check url from buffer id is equal with what we know. + DALI_TEST_CHECK(url1AfterType == urlFromBuffer.GetUrl()); + + // Reduce reference count + textureManager.RemoveEncodedImageBuffer(url1AfterType); + // Check whethere url1 still valid + DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1AfterType)); + + // Reduce reference count + textureManager.RemoveEncodedImageBuffer(url1AfterType); + // Check whethere url1 is invalid + DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1AfterType)); + + // Reduce reference count + textureManager.RemoveEncodedImageBuffer(url2); + // Check whethere url2 is still valid + DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url2)); + + // Reduce reference count + textureManager.RemoveEncodedImageBuffer(url2); + // Check whethere url2 is invalid + DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url2)); + + END_TEST; +} + +int UtcTextureManagerExternalTexture(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerExternalTexture check TextureManager using external texture works well"); + + auto visualFactory = Toolkit::VisualFactory::Get(); + auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager + + TestObserver observer1; + TestObserver observer2; + + auto textureId1(TextureManager::INVALID_TEXTURE_ID); + auto textureId2(TextureManager::INVALID_TEXTURE_ID); + std::string maskname(TEST_MASK_FILE_NAME); + TextureManager::MaskingDataPointer maskInfo = nullptr; + maskInfo.reset(new TextureManager::MaskingData()); + maskInfo->mAlphaMaskUrl = maskname; + maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + maskInfo->mCropToMask = true; + maskInfo->mContentScaleFactor = 1.0f; + Vector4 atlasRect(0.f, 0.f, 1.f, 1.f); + Dali::ImageDimensions atlasRectSize(0, 0); + bool synchronousLoading(false); + bool atlasingStatus(false); + bool loadingStatus(false); + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + ImageAtlasManagerPtr atlasManager = nullptr; + Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr; + + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); + + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url = imageUrl.GetUrl(); + + TextureSet texture1 = textureManager.LoadTexture( + url, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId1, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer1, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + TextureSet texture2 = textureManager.LoadTexture( + url, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId2, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer2, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + + DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + + DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION); + + texture1 = textureManager.LoadTexture( + url, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId1, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer1, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + texture2 = textureManager.LoadTexture( + url, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId2, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer2, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION); + DALI_TEST_EQUALS(texture1 != texture2, true, TEST_LOCATION); + + END_TEST; +} + +int UtcTextureManagerRemoveExternalTextureAndLoadAgain(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerRemoveExternalTextureAndLoadAgain check TextureManager RequestRemove and RemoveExternalTexture lifecycle works well"); + + auto visualFactory = Toolkit::VisualFactory::Get(); + auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager + + TestObserver observer1; + TestObserver observer2; + + auto textureId1(TextureManager::INVALID_TEXTURE_ID); + auto textureId2(TextureManager::INVALID_TEXTURE_ID); + TextureManager::MaskingDataPointer maskInfo = nullptr; + + Vector4 atlasRect(0.f, 0.f, 1.f, 1.f); + Dali::ImageDimensions atlasRectSize(0, 0); + bool synchronousLoading(false); + bool atlasingStatus(false); + bool loadingStatus(false); + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + ImageAtlasManagerPtr atlasManager = nullptr; + Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr; + + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); + + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url1 = imageUrl.GetUrl(); + std::string url2 = TEST_IMAGE_FILE_NAME; + + // Step 1 : Load request for external url + TextureSet texture1 = textureManager.LoadTexture( + url1, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId1, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer1, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_CHECK(textureId1 != TextureManager::INVALID_TEXTURE_ID); + + // Step 2 : Request remove for external url + textureManager.RequestRemove(textureId1, &observer1); + + // Step 3 : Reduce imageUrl reference count. + imageUrl.Reset(); + + // Step 4 : Request new load by normal image. + TextureSet texture2 = textureManager.LoadTexture( + url2, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId2, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer2, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_CHECK(textureId2 != TextureManager::INVALID_TEXTURE_ID); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + + DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + + END_TEST; +} + int UtcTextureManagerEncodedImageBufferReferenceCount(void) { ToolkitTestApplication application; @@ -483,7 +803,6 @@ int UtcTextureManagerEncodedImageBufferReferenceCount(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer1, true, ///< orientationCorrection TextureManager::ReloadPolicy::CACHED, @@ -562,7 +881,6 @@ int UtcTextureManagerCachingForDifferentLoadingType(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer1, true, TextureManager::ReloadPolicy::CACHED, @@ -791,10 +1109,7 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void) DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION); - application.SendNotification(); - application.Render(); - - // CAPTION : HARD-CODING for coverage. If you are a good boy, Do not follow this code. + // CAPTION : HARD-CODING for coverage. { Dali::Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer( filename, @@ -811,8 +1126,8 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void) textureManager.AsyncLoadComplete(textureId, pixelBuffers); std::vector maskBuffers; textureManager.AsyncLoadComplete(maskInfo->mAlphaMaskId, maskBuffers); - textureManager.Remove(maskInfo->mAlphaMaskId, nullptr); - textureManager.Remove(textureId, &observer); + textureManager.RequestRemove(maskInfo->mAlphaMaskId, nullptr); + textureManager.RequestRemove(textureId, &observer); } application.SendNotification(); @@ -1131,7 +1446,6 @@ int UtcTextureManagerQueueRemoveDuringObserve(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer, true, TextureManager::ReloadPolicy::CACHED, @@ -1232,22 +1546,18 @@ int UtcTextureManagerRemoveDuringApplyMasking(void) DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); // Remove current textureId1. and request new texture again. - textureManager.Remove(textureId1, &observer1); + textureManager.RequestRemove(textureId1, &observer1); auto textureId2 = textureManager.RequestLoad( filename, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, &observer2, true, ///< orientationCorrection TextureManager::ReloadPolicy::CACHED, preMultiply, synchronousLoading); - application.SendNotification(); - application.Render(); - DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); @@ -1259,7 +1569,7 @@ int UtcTextureManagerRemoveDuringApplyMasking(void) { std::vector pixelBuffers; textureManager.AsyncLoadComplete(textureId2, pixelBuffers); - textureManager.Remove(textureId2, &observer2); + textureManager.RequestRemove(textureId2, &observer2); } DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); ///< Note that we call AsyncLoadComplete hardly with empty pixelbuffer. @@ -1372,8 +1682,15 @@ int UtcTextureManagerMaskCacheTest(void) try { // Remove textureId1 first, and then remove textureId2. Check whether segfault occured. - textureManager.Remove(textureId1, &observer1); - textureManager.Remove(textureId2, &observer2); + textureManager.RequestRemove(textureId1, &observer1); + + application.SendNotification(); + application.Render(); + + textureManager.RequestRemove(textureId2, &observer2); + + application.SendNotification(); + application.Render(); TestObserver observer3; maskInfo.reset(new TextureManager::MaskingData()); @@ -1437,10 +1754,10 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) TextureManager textureManager; // Create new texture manager - TestObserverWithCustomFunction observer1; - TestObserverWithCustomFunction observer2; - TestObserver observer3; - TestObserver observer4; + TestObserverWithCustomFunction observer1; + TestObserverWithCustomFunction observer2; + TestObserverWithCustomFunction* observer3 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal + TestObserver observer4; std::string filename1(TEST_IMAGE_FILE_NAME); std::string filename2(TEST_IMAGE_2_FILE_NAME); @@ -1523,7 +1840,7 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) atlasRectSize, atlasingStatus, loadingStatus, - &observer3, + observer3, atlasUploadObserver, atlasManager, true, @@ -1534,8 +1851,8 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3->mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3->mObserverCalled, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION); @@ -1554,7 +1871,7 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) CustomData1 data1; data1.textureManagerPtr = &textureManager; data1.removeTextureId = textureId3; - data1.removeTextureObserver = &observer3; + data1.removeTextureObserver = observer3; observer1.mData = &data1; observer1.ConnectFunction( @@ -1566,8 +1883,11 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID); DALI_TEST_CHECK(data1.removeTextureObserver); - // Remove textureId3 - data1.textureManagerPtr->Remove(data1.removeTextureId, data1.removeTextureObserver); + // Remove textureId3. + data1.textureManagerPtr->RequestRemove(data1.removeTextureId, data1.removeTextureObserver); + + // Destroy observer3 + delete data1.removeTextureObserver; }); // Connect observer2 custom function @@ -1603,15 +1923,39 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, - TextureManager::UseAtlas::NO_ATLAS, data2.addTextureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply); }); - application.SendNotification(); - application.Render(); + // Connect observer3 custom function + struct CustomData3 + { + TestObserver* self{nullptr}; + bool* observerLoadedPtr{nullptr}; + bool* observerCalleddPtr{nullptr}; + }; + CustomData3 data3; + bool observer3Loaded = false; + bool observer3Called = false; + data3.self = observer3; + data3.observerLoadedPtr = &observer3Loaded; + data3.observerCalleddPtr = &observer3Called; + + observer3->mData = &data3; + observer3->ConnectFunction( + [](void* data) { + DALI_TEST_CHECK(data); + CustomData3 data3 = *(CustomData3*)data; + + DALI_TEST_CHECK(data3.self); + DALI_TEST_CHECK(data3.observerLoadedPtr); + DALI_TEST_CHECK(data3.observerCalleddPtr); + + *data3.observerLoadedPtr = data3.self->mLoaded; + *data3.observerCalleddPtr = data3.self->mObserverCalled; + }); tet_printf("Id info - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast(maskInfo[0]->mAlphaMaskId), static_cast(textureId1), static_cast(textureId2), static_cast(textureId3), static_cast(textureId4)); @@ -1630,12 +1974,14 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888)); textureManager.AsyncLoadComplete(textureId3, pixelBuffers); + // Ensure textureId3 remove request processed. + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION); @@ -1651,8 +1997,8 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION); @@ -1668,11 +2014,402 @@ int UtcTextureManagerRemoveDuringGPUMasking(void) DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); - DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mLoaded, true, TEST_LOCATION); DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION); } END_TEST; -} \ No newline at end of file +} + +int UtcTextureManagerDestroyObserverDuringObserve(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerDestroyObserverDuringObserve"); + tet_infoline("Request 3 different image."); + tet_infoline("Complete textureId1. After observer1 loaded done,"); + tet_infoline(" - Remove and destroy observer2"); + tet_infoline(" - Re-generate observer2 which has same address pointer with before."); + tet_infoline(" - Remove and Reqeust third file by observer3"); + tet_infoline("Complete textureId2. and check old observer2 not emmited, and newly observer2 works."); + tet_infoline("Complete textureId3. and check observer3 comes"); + + TextureManager textureManager; // Create new texture manager + + TestObserverWithCustomFunction observer1; + TestObserverWithCustomFunction* observer2 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal. + TestObserver observer3; + + std::string filename1(TEST_IMAGE_FILE_NAME); + std::string filename2(TEST_IMAGE_2_FILE_NAME); + std::string filename3(TEST_IMAGE_3_FILE_NAME); + std::string filename4(TEST_IMAGE_4_FILE_NAME); + + auto textureId1(TextureManager::INVALID_TEXTURE_ID); + auto textureId2(TextureManager::INVALID_TEXTURE_ID); + auto textureId3(TextureManager::INVALID_TEXTURE_ID); + auto textureId4(TextureManager::INVALID_TEXTURE_ID); + + // Dummy reference value + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + + // Request image 1, 2, 3. + textureId1 = textureManager.RequestLoad( + filename1, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + &observer1, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + textureId2 = textureManager.RequestLoad( + filename2, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + observer2, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + textureId3 = textureManager.RequestLoad( + filename3, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + &observer3, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + struct CustomData1 + { + TextureManager* textureManagerPtr{nullptr}; + TextureManager::TextureId removeTextureId{TextureManager::INVALID_TEXTURE_ID}; + TestObserverWithCustomFunction** removeTextureObserver{nullptr}; + std::string resendFilename{}; + TextureManager::TextureId resendTextureId{TextureManager::INVALID_TEXTURE_ID}; + TestObserver* resendTextureObserver{nullptr}; + std::string newlyFilename{}; + TextureManager::TextureId* newlyTextureIdPtr{nullptr}; + }; + struct CustomData2 + { + TextureManager* textureManagerPtr{nullptr}; + TestObserver* self{nullptr}; + bool* observerLoadedPtr{nullptr}; + bool* observerCalledPtr{nullptr}; + }; + + bool observer2Loaded = false; + bool observer2Called = false; + bool newObserver2Loaded = false; + bool newObserver2Called = false; + CustomData2 newData2; // Used on observer1 function + + // Connect observer1 custom function + CustomData1 data1; + data1.textureManagerPtr = &textureManager; + data1.removeTextureId = textureId2; + data1.removeTextureObserver = &observer2; + data1.resendFilename = filename3; + data1.resendTextureId = textureId3; + data1.resendTextureObserver = &observer3; + data1.newlyFilename = filename2; // Same as observer2 filename + data1.newlyTextureIdPtr = &textureId4; + + observer1.mData = &data1; + observer1.ConnectFunction( + [&](void* data) { + DALI_TEST_CHECK(data); + CustomData1 data1 = *(CustomData1*)data; + + DALI_TEST_CHECK(data1.textureManagerPtr); + DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID); + DALI_TEST_CHECK(data1.removeTextureObserver); + DALI_TEST_CHECK(*data1.removeTextureObserver); + DALI_TEST_CHECK(!data1.resendFilename.empty()); + DALI_TEST_CHECK(data1.resendTextureId != TextureManager::INVALID_TEXTURE_ID); + DALI_TEST_CHECK(data1.resendTextureObserver); + DALI_TEST_CHECK(!data1.newlyFilename.empty()); + DALI_TEST_CHECK(data1.newlyTextureIdPtr); + DALI_TEST_CHECK(*data1.newlyTextureIdPtr == TextureManager::INVALID_TEXTURE_ID); + + // Remove textureId2. + data1.textureManagerPtr->RequestRemove(data1.removeTextureId, *data1.removeTextureObserver); + + auto removedObserver = *data1.removeTextureObserver; + + // Destroy observer2. + delete removedObserver; + + // Create new observer. Make we use same pointer if we can. + uint32_t maxTryCount = 100u; + uint32_t tryCount = 0u; + + while(tryCount < maxTryCount) + { + *data1.removeTextureObserver = new TestObserverWithCustomFunction(); + if(removedObserver == *data1.removeTextureObserver) break; + ++tryCount; + delete *data1.removeTextureObserver; + } + + tet_printf("TryCount[%u] / Old observer2 : %p, newly observer2 : %p\n", tryCount, removedObserver, *data1.removeTextureObserver); + + // Connect new observer2 custom function + newData2.textureManagerPtr = &textureManager; + newData2.self = (*data1.removeTextureObserver); + newData2.observerLoadedPtr = &newObserver2Loaded; + newData2.observerCalledPtr = &newObserver2Called; + + (*data1.removeTextureObserver)->mData = &newData2; + (*data1.removeTextureObserver)->ConnectFunction([](void* data) { + DALI_TEST_CHECK(data); + CustomData2 data2 = *(CustomData2*)data; + + tet_printf("New created observer running\n"); + + DALI_TEST_CHECK(data2.self); + DALI_TEST_CHECK(data2.observerLoadedPtr); + DALI_TEST_CHECK(data2.observerCalledPtr); + + *data2.observerLoadedPtr = data2.self->mLoaded; + *data2.observerCalledPtr = data2.self->mObserverCalled; + }); + + // Dummy reference value + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + + // Resend textureId3 + data1.textureManagerPtr->RequestRemove(data1.resendTextureId, data1.resendTextureObserver); + + TextureManager::TextureId tempId; + tempId = data1.textureManagerPtr->RequestLoad( + data1.resendFilename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + data1.resendTextureObserver, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_CHECK(tempId == data1.resendTextureId); + + // Request new task + + tempId = data1.textureManagerPtr->RequestLoad( + data1.newlyFilename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + *data1.removeTextureObserver, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_CHECK(tempId != TextureManager::INVALID_TEXTURE_ID); + *data1.newlyTextureIdPtr = tempId; + }); + + // Connect observer2 custom function + CustomData2 data2; + data2.textureManagerPtr = &textureManager; + data2.self = observer2; + data2.observerLoadedPtr = &observer2Loaded; + data2.observerCalledPtr = &observer2Called; + + observer2->mData = &data2; + observer2->ConnectFunction( + [](void* data) { + DALI_TEST_CHECK(data); + CustomData2 data2 = *(CustomData2*)data; + + tet_printf("Old created observer running. Something error occured!\n"); + + DALI_TEST_CHECK(data2.self); + DALI_TEST_CHECK(data2.observerLoadedPtr); + DALI_TEST_CHECK(data2.observerCalledPtr); + + *data2.observerLoadedPtr = data2.self->mLoaded; + *data2.observerCalledPtr = data2.self->mObserverCalled; + }); + + tet_printf("Id info - 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast(textureId1), static_cast(textureId2), static_cast(textureId3), static_cast(textureId4)); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + + DALI_TEST_CHECK(textureId4 == TextureManager::INVALID_TEXTURE_ID); + + // CAPTION : HARD-CODING. + // Run codes without exception. + try + { + tet_printf("Complete async load 1 first.\n"); + std::vector pixelBuffers; + + pixelBuffers.clear(); + pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888)); + textureManager.AsyncLoadComplete(textureId1, pixelBuffers); + + tet_printf("Now observer2 deleted, observer3 resended, observer2 re-created.\n"); + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + + tet_printf("Id info - 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast(textureId1), static_cast(textureId2), static_cast(textureId3), static_cast(textureId4)); + + DALI_TEST_CHECK(textureId4 == textureId2); + + // Remove processor excute. + application.SendNotification(); + application.Render(); + + tet_printf("Complete async load 2. Let we check old version observer2 ignored and newly observer2 loaded.\n"); + pixelBuffers.clear(); + pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888)); + textureManager.AsyncLoadComplete(textureId2, pixelBuffers); + + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION); + // We don't check observer3 not loaded case because SendNotification can process AsyncTask. + //DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); + //DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + + tet_printf("Complete async load 3.\n"); + pixelBuffers.clear(); + pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888)); + textureManager.AsyncLoadComplete(textureId3, pixelBuffers); + + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION); + } + catch(...) + { + DALI_TEST_CHECK(false); + } + + END_TEST; +} + +int UtcTextureManagerCachingForDifferentMultiplyOnLoad(void) +{ + /// To insture the order of callback, Make we don't use mutiple thread loading for this UTC. + EnvironmentVariable::SetTestEnvironmentVariable("DALI_ASYNC_MANAGER_THREAD_POOL_SIZE", "1"); + EnvironmentVariable::SetTestEnvironmentVariable("DALI_ASYNC_MANAGER_LOW_PRIORITY_THREAD_POOL_SIZE", "1"); + + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerCachingForDifferentMultiplyOnLoad"); + tet_infoline("Observe1 multiply on load, and Observer2, 3 don't multiply on load."); + tet_infoline("We will use jpg image, with will not premultiply alpha even if we try to load without multiply."); + + tet_infoline("Let we request Observer1 and Observer2 sequencely."); + tet_infoline("After Observer1 complete, we will cache -premultiplyOnLoad = true, premultiplied = false;"); + tet_infoline("Before Observer2 complete, let we request Observer3. It will cache-hit with Observer1 item (since image is not premultiplied.)"); + tet_infoline("At this time, Observer1 and Observer3 loaded, but Observer2 still not."); + + TextureManager textureManager; // Create new texture manager + + TestObserver observer1; + TestObserver observer2; + TestObserver observer3; + std::string filename(TEST_IMAGE_FILE_NAME); + auto preMultiply = TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD; + textureManager.RequestLoad( + filename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + &observer1, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + + preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + textureManager.RequestLoad( + filename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + &observer2, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + tet_printf("We can ensure that observer1 loaded first. (since the number of thread pool is 1)\n"); + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); + + preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + textureManager.RequestLoad( + filename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + &observer3, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + tet_printf("Request Observer3. It will cache-hit with Observer1.\n"); + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION); + + END_TEST; +}