END_TEST;
}
+int UtcDaliImageViewReloadAlphaMaskImage(void)
+{
+ ToolkitTestApplication application;
+
+ gResourceReadySignalFired = false;
+
+ ImageView dummy = ImageView::New();
+ ImageView imageView = ImageView::New();
+ Property::Map propertyMap;
+
+ // To keep alpha mask cached, scene on some dummy image.
+ // Note : If we don't cache alpha mask image, the reference count of mask image become zero.
+ // In this case, we might need to wait mask image loading, which is not neccesary & can be changed behavior.
+ propertyMap[ImageVisual::Property::URL] = gImage_600_RGB;
+ propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+ dummy.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+ application.GetScene().Add(dummy);
+
+ application.SendNotification();
+ application.Render(16);
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+
+ propertyMap.Clear();
+ propertyMap[ImageVisual::Property::URL] = gImage_34_RGBA;
+ propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+ imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+ DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION);
+
+ imageView.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Load image and use cached mask. Now we try to apply masking.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION);
+
+ // Cancel apply masking.
+ imageView.Unparent();
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Reload same image again.
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Finish apply masking.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
void OnRelayoutOverride(Size size)
{
gNaturalSize = size; // Size Relayout is using
loadState == TextureManagerType::LoadState::MASK_APPLIED ? "MASK_APPLIED" : \
loadState == TextureManagerType::LoadState::UPLOADED ? "UPLOADED" : \
loadState == TextureManagerType::LoadState::CANCELLED ? "CANCELLED" : \
+ loadState == TextureManagerType::LoadState::MASK_CANCELLED ? "MASK_CANCELLED" : \
loadState == TextureManagerType::LoadState::LOAD_FAILED ? "LOAD_FAILED" : \
"Unknown"
// clang-format on
Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex)
{
- Texture texture; // empty handle
+ Texture texture; // empty handle
TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureInfo)
{
- TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
- bool removeTextureInfo = false;
+ TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
+ bool removeTextureInfo = false;
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::Remove(textureId:%d) url:%s\n cacheIdx:%d loadState:%s reference count = %d\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), textureInfoIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState), textureInfo.referenceCount);
}
removeTextureInfo = true;
}
- else if(textureInfo.loadState == LoadState::LOADING || textureInfo.loadState == LoadState::MASK_APPLYING)
+ else if(textureInfo.loadState == LoadState::LOADING)
{
// We mark the textureInfo for removal.
// Once the load has completed, this method will be called again.
textureInfo.loadState = LoadState::CANCELLED;
}
+ else if(textureInfo.loadState == LoadState::MASK_APPLYING)
+ {
+ // We mark the textureInfo for removal.
+ // Once the load has completed, this method will be called again.
+ textureInfo.loadState = LoadState::MASK_CANCELLED;
+ }
else
{
// In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
loadState == TextureManagerType::LoadState::MASK_APPLIED ? "MASK_APPLIED" : \
loadState == TextureManagerType::LoadState::UPLOADED ? "UPLOADED" : \
loadState == TextureManagerType::LoadState::CANCELLED ? "CANCELLED" : \
+ loadState == TextureManagerType::LoadState::MASK_CANCELLED ? "MASK_CANCELLED" : \
loadState == TextureManagerType::LoadState::LOAD_FAILED ? "LOAD_FAILED" : \
"Unknown"
// clang-format on
// Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
}
if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
// Cache new texutre, and get cacheIndex.
cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, preMultiply);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
}
// The below code path is common whether we are using the cache or not.
TextureManager::LoadState::WAITING_FOR_MASK != textureInfo.loadState &&
TextureManager::LoadState::MASK_APPLYING != textureInfo.loadState &&
TextureManager::LoadState::MASK_APPLIED != textureInfo.loadState &&
- TextureManager::LoadState::CANCELLED != textureInfo.loadState)
+ TextureManager::LoadState::CANCELLED != textureInfo.loadState &&
+ TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState)
{
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId);
textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
}
ObserveTexture(textureInfo, observer);
break;
}
+ case TextureManager::LoadState::MASK_CANCELLED:
+ {
+ // A cancelled texture hasn't finished mask applying yet. Treat as a mask applying texture
+ // (it's ref count has already been incremented, above)
+ textureInfo.loadState = TextureManager::LoadState::MASK_APPLYING;
+ ObserveTexture(textureInfo, observer);
+ break;
+ }
case TextureManager::LoadState::LOAD_FINISHED:
{
// Loading has already completed.
{
TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
- // We only need to consider maskTextureId when texture's loadState is not CANCELLED. Because it is already deleted.
- if(textureInfo.loadState != LoadState::CANCELLED)
+ // We only need to consider maskTextureId when texture's loadState is not cancelled. Because it is already deleted.
+ if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
{
if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
{
}
}
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d observer=%p ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, observer, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
+
// the case that LoadingQueue is working.
if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
{
}
case LoadState::LOADING:
case LoadState::CANCELLED:
+ case LoadState::MASK_CANCELLED:
case LoadState::LOAD_FINISHED:
case LoadState::WAITING_FOR_MASK:
case LoadState::MASK_APPLYING:
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, " textureId:%d Url:%s CacheIndex:%d LoadState: %s\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
- if(textureInfo.loadState != LoadState::CANCELLED)
+ if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
{
// textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
PostLoad(textureInfo, pixelBuffers);
UploadTextures(pixelBuffers, maskTextureInfo);
}
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): maskTextureId=%d, maskTextureUrl=%s\n", maskTextureInfo.textureId, maskTextureInfo.url.GetUrl().c_str());
+
// Search the cache, checking if any texture has this texture id as a maskTextureId
const std::size_t size = mTextureCacheManager.size();
maskTextureInfo.referenceCount++;
textureInfo.referenceCount++;
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
}
- else
+ else // maskTextureInfo.loadState == LoadState::LOAD_FAILED
{
// Url texture load success, But alpha mask texture load failed. Run as normal image upload.
DALI_LOG_ERROR("Alpha mask image loading failed! Image will not be masked\n");
maskTextureInfo.referenceCount++;
textureInfo.referenceCount++;
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
}