/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
END_TEST;
}
+
+int UtcDaliControlDoActionMultipleWhenNotStage01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("DoAction on a visual registered with a control multiple times but not staged");
+
+ // Set up trace debug
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ //Created AnimatedImageVisual
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION);
+ textureTrace.Reset();
+
+ Property::Map attributes;
+ const uint32_t repeatMax = 10u;
+ for(uint32_t repeatCnt = 0u; repeatCnt < repeatMax; ++repeatCnt)
+ {
+ // DoAction multiple times.
+ DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelImageVisual::Action::RELOAD, attributes);
+ }
+
+ tet_infoline("Perform RELOAD action. should reload Image and generate a texture");
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
+ textureTrace.Reset();
+
+ tet_infoline("Do not load image on more time even we request reload multiple times.");
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 1), false, TEST_LOCATION);
+
+ tet_infoline("Adding control to stage will in turn add the visual to the stage");
+
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+ tet_infoline("No change in textures could occurs as already loaded and cached texture will be used");
+
+ DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION);
+ textureTrace.Reset();
+
+ dummyControl.Unparent();
+ dummyControl.Reset();
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
+
+int UtcDaliControlDoActionMultipleWhenNotStage02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("DoAction on a visual registered with a control multiple times but not staged");
+
+ // Set up trace debug
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ //Created AnimatedImageVisual
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+ Visual::Base imageVisual2 = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+
+ gResourceReadySignalFired = false;
+
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ dummyControl.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+ application.SendNotification();
+ application.Render();
+
+ // Dummy control to keep cache
+ DummyControl keepCacheControl = DummyControl::New(true);
+ Impl::DummyControl& keepCacheImpl = static_cast<Impl::DummyControl&>(keepCacheControl.GetImplementation());
+
+ keepCacheImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2);
+ keepCacheControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+
+ // Load request for keep cache control.
+ application.GetScene().Add(keepCacheControl);
+
+ Property::Map attributes;
+ const uint32_t repeatMax = 10u;
+ for(uint32_t repeatCnt = 0u; repeatCnt < repeatMax; ++repeatCnt)
+ {
+ // DoAction multiple times.
+ DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelImageVisual::Action::RELOAD, attributes);
+ }
+
+ application.SendNotification();
+ application.Render();
+
+ try
+ {
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("Async load completed. Sigabort should not be occured");
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("ResourceReady signal must be fired!");
+ DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
+
+ tet_infoline("Texture generation occured");
+ DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
+ textureTrace.Reset();
+
+ tet_result(TET_PASS);
+ }
+ catch(...)
+ {
+ // Must not be throw exception.
+ tet_infoline("Exception occured!");
+ tet_result(TET_FAIL);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliControlDoActionMultipleWhenNotStage03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("DoAction on a visual registered with a control multiple times but not staged");
+
+ // Set up trace debug
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ //Created AnimatedImageVisual
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+ Visual::Base imageVisual2 = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+
+ gResourceReadySignalFired = false;
+
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ dummyControl.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+ application.SendNotification();
+ application.Render();
+
+ // Dummy control to keep cache
+ DummyControl keepCacheControl = DummyControl::New(true);
+ Impl::DummyControl& keepCacheImpl = static_cast<Impl::DummyControl&>(keepCacheControl.GetImplementation());
+
+ keepCacheImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2);
+ keepCacheControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+
+ // Load request for keep cache control.
+ application.GetScene().Add(keepCacheControl);
+
+ Property::Map attributes;
+ const uint32_t repeatMax = 10u;
+ for(uint32_t repeatCnt = 0u; repeatCnt < repeatMax; ++repeatCnt)
+ {
+ // DoAction multiple times.
+ DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelImageVisual::Action::RELOAD, attributes);
+ }
+
+ application.SendNotification();
+ application.Render();
+
+ try
+ {
+ tet_infoline("Destroy control without stage on. And create new object that as same visual pointer as previous control");
+
+ const auto* imageVisualObjectPtr = imageVisual.GetObjectPtr();
+ const uint32_t tryCountMax = 100u;
+ uint32_t tryCount = 0u;
+ do
+ {
+ dummyControl.Reset();
+ imageVisual.Reset();
+
+ imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions());
+ dummyControl = DummyControl::New(true);
+
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+ } while(++tryCount < tryCountMax && imageVisualObjectPtr != imageVisual.GetObjectPtr());
+
+ tet_printf("Luck-trial count : %u. Success? %d\n", tryCount, imageVisualObjectPtr == imageVisual.GetObjectPtr());
+
+ // Connect signal
+ dummyControl.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("Async load completed after control destroyed. Sigabort should not be occured");
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline("ResourceReady signal must not be fired!");
+ DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION);
+
+ tet_infoline("Texture generation occured");
+ DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
+ textureTrace.Reset();
+
+ tet_result(TET_PASS);
+ }
+ catch(...)
+ {
+ // Must not be throw exception.
+ tet_infoline("Exception occured!");
+ tet_result(TET_FAIL);
+ }
+
+ END_TEST;
+}
\ No newline at end of file
}
}
- textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
+ textureId = RequestLoadInternal(url, alphaMaskId, textureId, contentScaleFactor, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
}
else
{
- RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, StorageType::RETURN_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, false);
+ RequestLoadInternal(url, INVALID_TEXTURE_ID, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, StorageType::RETURN_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, false);
}
return pixelBuffer;
auto externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(id);
if(externalTextureInfo.textureSet)
{
- textureId = id;
-
if(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
{
// Change preMultiplyOnLoad value so make caller determine to preMultiplyAlpha or not.
{
maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, StorageType::KEEP_TEXTURE, synchronousLoading);
alphaMaskId = maskInfo->mAlphaMaskId;
- textureId = RequestLoad(url, alphaMaskId, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, textureObserver, orientationCorrection, reloadPolicy, preMultiplyOnLoad, synchronousLoading);
+
+ // Create new textureId. this textureId is not same as location
+ textureId = RequestLoad(url, alphaMaskId, textureId, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, textureObserver, orientationCorrection, reloadPolicy, preMultiplyOnLoad, synchronousLoading);
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
}
else
{
+ // TextureId is same as location
+ textureId = id;
+
textureSet = TextureSet::New();
textureSet.SetTexture(TEXTURE_INDEX, externalTextureInfo.textureSet.GetTexture(TEXTURE_INDEX));
}
textureId = RequestLoad(
url,
alphaMaskId,
+ textureId,
contentScaleFactor,
desiredSize,
fittingMode,
TextureManager::MultiplyOnLoad& preMultiplyOnLoad,
const bool& synchronousLoading)
{
- return RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
+ return RequestLoadInternal(url, INVALID_TEXTURE_ID, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
}
TextureManager::TextureId TextureManager::RequestLoad(
const VisualUrl& url,
const TextureManager::TextureId& maskTextureId,
+ const TextureManager::TextureId& previousTextureId,
const float& contentScale,
const Dali::ImageDimensions& desiredSize,
const Dali::FittingMode::Type& fittingMode,
TextureManager::MultiplyOnLoad& preMultiplyOnLoad,
const bool& synchronousLoading)
{
- return RequestLoadInternal(url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
+ return RequestLoadInternal(url, maskTextureId, previousTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
}
TextureManager::TextureId TextureManager::RequestMaskLoad(
{
// Use the normal load procedure to get the alpha mask.
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, storageType, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
+ return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, storageType, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
}
TextureManager::TextureId TextureManager::RequestLoadInternal(
const VisualUrl& url,
const TextureManager::TextureId& maskTextureId,
+ const TextureManager::TextureId& previousTextureId,
const float& contentScale,
const Dali::ImageDimensions& desiredSize,
const Dali::FittingMode::Type& fittingMode,
// Check if the requested Texture exists in the cache.
if(cacheIndex != INVALID_CACHE_INDEX)
{
- if(TextureManager::ReloadPolicy::CACHED == reloadPolicy)
+ if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || TextureManager::INVALID_TEXTURE_ID == previousTextureId)
{
- // Mark this texture being used by another client resource. Forced reload would replace the current texture
+ // Mark this texture being used by another client resource, or Reload forced without request load before.
+ // Forced reload which have current texture before, would replace the current texture.
// without the need for incrementing the reference count.
++(mTextureCacheManager[cacheIndex].referenceCount);
}
// 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, maskTextureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, 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, prevTextureId=%d, frameindex=%d, premultiplied=%d, refCount=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0, static_cast<int>(mTextureCacheManager[cacheIndex].referenceCount));
}
if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
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, maskTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d, prevTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId);
textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
}
case TextureManager::LoadState::MASK_APPLYING:
case TextureManager::LoadState::MASK_APPLIED:
{
- ObserveTexture(textureInfo, observer);
+ // Do not observe even we reload forced when texture is already loading state.
+ if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || TextureManager::INVALID_TEXTURE_ID == previousTextureId)
+ {
+ ObserveTexture(textureInfo, observer);
+ }
break;
}
case TextureManager::LoadState::UPLOADED:
}
}
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d ) cacheIndex:%d removal maskTextureId=%d, loadState=%s\n", textureId, textureCacheIndex.GetIndex(), maskTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
// Remove textureId in CacheManager. Now, textureInfo is invalidate.
mTextureCacheManager.RemoveCache(textureInfo);
if(maskCacheIndex != INVALID_CACHE_INDEX)
{
TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove mask texture( maskTextureId=%d ) cacheIndex:%d, loadState=%s\n", maskTextureId, maskCacheIndex.GetIndex(), GET_LOAD_STATE_STRING(maskTextureInfo.loadState));
+
mTextureCacheManager.RemoveCache(maskTextureInfo);
}
}
{
// The Texture has already loaded. The other observers have already been notified.
// We need to send a "late" loaded notification for this observer.
- EmitLoadComplete(observer, textureInfo, true);
+ if(observer)
+ {
+ EmitLoadComplete(observer, textureInfo, true);
+ }
}
break;
}
if(observer)
{
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Connect DestructionSignal to observer:%p\n", observer);
observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed);
}
}
if(cacheIndex != INVALID_CACHE_INDEX)
{
TextureInfo& textureInfo(mTextureCacheManager[cacheIndex]);
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::ProcessLoadQueue() textureId=%d, observer=%p, cacheIndex=@%d, loadState:%s\n", element.mTextureId, element.mObserver, cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
+
if((textureInfo.loadState == LoadState::UPLOADED) || (textureInfo.loadState == LoadState::LOAD_FINISHED && textureInfo.storageType == StorageType::RETURN_PIXEL_BUFFER))
{
if(element.mObserver)
if(observer)
{
textureInfo.observerList.PushBack(observer);
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Connect DestructionSignal to observer:%p\n", observer);
observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed);
}
}
// invalidating the reference to the textureInfo struct.
// Texture load requests for the same URL are deferred until the end of this
// method.
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::NotifyObservers() textureId:%d url:%s loadState:%s\n", textureId, info->url.GetUrl().c_str(), GET_LOAD_STATE_STRING(info->loadState));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::NotifyObservers() observer:%p textureId:%d url:%s loadState:%s\n", observer, textureId, info->url.GetUrl().c_str(), GET_LOAD_STATE_STRING(info->loadState));
// It is possible for the observer to be deleted.
// Disconnect and remove the observer first.
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
info->observerList.Erase(info->observerList.End() - 1u);
void TextureManager::ObserverDestroyed(TextureUploadObserver* observer)
{
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::ObserverDestroyed() observer:%p\n", observer);
+
const std::size_t size = mTextureCacheManager.size();
for(TextureCacheIndex cacheIndex = TextureCacheIndex(TextureManagerType::TEXTURE_CACHE_INDEX_TYPE_LOCAL, 0u); cacheIndex.GetIndex() < size; ++cacheIndex.detailValue.index)
{
if(iter != iterEnd)
{
// Disconnect and remove the observer.
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
textureInfo.observerList.Erase(iter);
}
* @param[in] samplingMode The SamplingMode to use
* @param[in, out] maskInfo Mask info structure
* @param[in] synchronousLoading true if the URL should be loaded synchronously
- * @param[out] textureId, The textureId of the URL
+ * @param[in, out] textureId The textureId of the URL. It is also be used to check the previous textureId
+ * what requestor had. It will be used only ReloadPolicy::FORCED for now.
* @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
* this is the rectangle in normalized coordinates.
* @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
TextureManager::MultiplyOnLoad& preMultiplyOnLoad,
const bool& synchronousLoading = false);
+private: // Internal Load Request API
/**
* @brief Requests an image load of the given URL, when the texture has
* have loaded, it will perform a blend with the image mask, and upload
* @param[in] url The URL of the image to load
* @param[in] maskTextureId The texture id of an image to mask this with
* (can be INVALID if no masking required)
+ * @param[in] previousTextureId The texture id of an image which the requestor already has before
* @param[in] contentScale The scale factor to apply to the image before masking
* @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
* @param[in] fittingMode The FittingMode to use
TextureId RequestLoad(
const VisualUrl& url,
const TextureManager::TextureId& maskTextureId,
+ const TextureManager::TextureId& previousTextureId,
const float& contentScale,
const ImageDimensions& desiredSize,
const Dali::FittingMode::Type& fittingMode,
StorageType storageType,
const bool& synchronousLoading = false);
-private:
/**
* @brief Requests an image load of the given URL, when the texture has
* have loaded, if there is a valid maskTextureId, it will perform a
* @param[in] url The URL of the image to load
* @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
* to INVALID_TEXTURE_ID
+ * @param[in] previousTextureId The texture id of an image which the requestor already has before. It will be used
+ * when reloadPolicy is FORCED.
* @param[in] contentScale The scaling factor to apply to the content when masking
* @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
* @param[in] fittingMode The FittingMode to use
TextureId RequestLoadInternal(
const VisualUrl& url,
const TextureManager::TextureId& maskTextureId,
+ const TextureManager::TextureId& previousTextureId,
const float& contentScale,
const Dali::ImageDimensions& desiredSize,
const Dali::FittingMode::Type& fittingMode,