namespace
{
-const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
-const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
+const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
+const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png";
+const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
class TestObserver : public Dali::Toolkit::TextureUploadObserver
{
Texture asyncTexture2 = asyncTextureSet2.GetTexture(0u);
DALI_TEST_CHECK(syncTexture);
DALI_TEST_CHECK(asyncTexture2);
- DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same.
+ DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same.
// observer is called synchronously because the texture is cached.
DALI_TEST_EQUALS(asyncObserver2.mLoaded, true, TEST_LOCATION);
END_TEST;
}
+
+int UtcTextureManagerMaskCacheTest(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcTextureManagerMaskCacheTest");
+
+ TextureManager textureManager; // Create new texture manager
+
+ TestObserver observer1;
+ TestObserver observer2;
+
+ std::string filename(TEST_IMAGE_FILE_NAME);
+ std::string filename2(TEST_IMAGE_2_FILE_NAME);
+ 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;
+
+ TextureManager::MaskingDataPointer maskInfo2 = nullptr;
+ maskInfo2.reset(new TextureManager::MaskingData());
+ maskInfo2->mAlphaMaskUrl = maskname;
+ maskInfo2->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo2->mCropToMask = true;
+ maskInfo2->mContentScaleFactor = 1.0f;
+
+ auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+ 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;
+
+ textureManager.LoadTexture(
+ filename,
+ 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_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ // Load image and mask image.
+ // Now, LoadState become MASK_APPLYING
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ tet_printf("Current textureId1:%d's state become MASK_APPLYING\n", static_cast<int>(textureId1));
+
+ textureManager.LoadTexture(
+ filename2,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo2,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ application.SendNotification();
+ application.Render();
+
+ // Load image2 + image1 apply mask + image2 apply mask = total 3 event trigger required.
+ // Note that we use cached mask image.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+
+ try
+ {
+ // Remove textureId1 first, and then remove textureId2. Check whether segfault occured.
+ textureManager.Remove(textureId1, &observer1);
+ textureManager.Remove(textureId2, &observer2);
+
+ TestObserver observer3;
+ maskInfo.reset(new TextureManager::MaskingData());
+ maskInfo->mAlphaMaskUrl = maskname;
+ maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo->mCropToMask = true;
+ maskInfo->mContentScaleFactor = 1.0f;
+
+ textureManager.LoadTexture(
+ filename,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer3,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ // Load image and mask image.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+ // Apply mask.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), 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;
+}
constexpr auto DEFAULT_NUMBER_OF_LOCAL_LOADER_THREADS = size_t{4u};
constexpr auto DEFAULT_NUMBER_OF_REMOTE_LOADER_THREADS = size_t{8u};
-constexpr auto TEXTURE_INDEX = 0u; ///< The Index for texture
-constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture
+constexpr auto TEXTURE_INDEX = 0u; ///< The Index for texture
+constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture
constexpr auto NUMBER_OF_LOCAL_LOADER_THREADS_ENV = "DALI_TEXTURE_LOCAL_THREADS";
constexpr auto NUMBER_OF_REMOTE_LOADER_THREADS_ENV = "DALI_TEXTURE_REMOTE_THREADS";
if(textureCacheIndex != INVALID_CACHE_INDEX)
{
TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
- TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+ TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
{
maskTextureId = textureInfo.maskTextureId;
// Remove its observer
RemoveTextureObserver(textureInfo, observer);
+ // Keep loadState due to the textureInfo validate problem.
+ auto textureLoadState = textureInfo.loadState;
+
+ // Remove textureId in CacheManager
+ mTextureCacheManager.RemoveCache(textureInfo);
+
// Remove maskTextureId in CacheManager
if(maskTextureId != INVALID_TEXTURE_ID)
{
TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
// Only Remove maskTexture when texture's loadState is not CANCELLED. because it is already deleted.
- if(textureInfo.loadState != LoadState::CANCELLED)
+ if(textureLoadState != LoadState::CANCELLED)
{
mTextureCacheManager.RemoveCache(maskTextureInfo);
}
}
}
-
- // Remove textureId in CacheManager
- mTextureCacheManager.RemoveCache(textureInfo);
}
}
for(auto&& pixelBuffer : pixelBuffers)
{
- Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
+ Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
texture.Upload(pixelData);
textureInfo.textures.push_back(texture);
TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId& textureId)
{
- TextureSet textureSet;
+ TextureSet textureSet;
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
// Remove its observer
if(observer)
{
- const auto iterEnd = textureInfo.observerList.End();
- const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
+ const auto iterEnd = textureInfo.observerList.End();
+ const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
if(iter != iterEnd)
{
// Disconnect and remove the observer.