- We don't need to 'ignore' the cached size.
- We don't know last rasterized size at immediate loading time
- We don't need to re-load as desired size when visual is scene-on again.
-> Actually, It will re-load after OnSetTransform(). But anyway,
it will return cached texture and don't re-load any images.
- Bug fix if mLoadState become NOT_START but mTextures exist.
TODO : Send ResourceReady at OnRelayout callback is not a good idea.
Shouldn't we re-load at Idle, or PostProcess time?
Change-Id: Ia13a03feaf0f3909c75196472cc865b15a6fca2d
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
application.GetScene().Add(imageView);
- // Wait for image loading(1)
+ // load image as size 0x0 (Since we cannot ensure the size of actor yet)
// (Texture size is its original size, not the actor size.)
DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ // Check (current image texture size != actor size)
+ Renderer renderer = imageView.GetRendererAt(0);
+ TextureSet textures = renderer.GetTextures();
+ DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION);
+
+ Texture texture = textures.GetTexture(0);
+ DALI_TEST_EQUALS(texture.GetWidth(), 128u, TEST_LOCATION);
+ DALI_TEST_EQUALS(texture.GetHeight(), 128u, TEST_LOCATION);
+
application.SendNotification();
application.Render();
DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION);
+ // load image as size 200x200 (Now we can ensure the size of actor is 200x200)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
// Set size again
imageView.SetProperty(Actor::Property::SIZE, size);
- // Wait for image loading(2)
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
-
// Check (reloaded image texture size == actor size)
- Renderer renderer = imageView.GetRendererAt(0);
- TextureSet textures = renderer.GetTextures();
+ renderer = imageView.GetRendererAt(0);
+ textures = renderer.GetTextures();
DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION);
- Texture texture = textures.GetTexture(0);
+ texture = textures.GetTexture(0);
DALI_TEST_EQUALS(texture.GetWidth(), width, TEST_LOCATION);
DALI_TEST_EQUALS(texture.GetHeight(), height, TEST_LOCATION);
DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
application.GetScene().Add(actor);
+
+ // load image as size 0x0 (Since we cannot ensure the size of actor yet)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification(); // require to load size(1)
+
+ // load image as size 200x200 (Now we can ensure the size of actor is 200x200)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
application.SendNotification();
- application.Render(); // require to load size(1)
+ application.Render();
actor.SetProperty(Actor::Property::SIZE, Vector2(100.f, 100.f)); // set size(2), no renderer yet
visual.GetNaturalSize(size); // get size(1)
DALI_TEST_EQUALS(size, Vector2(200.0f, 200.0f), 0.001f, TEST_LOCATION);
- // load image
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
-
- application.SendNotification();
- application.Render(); // require to load size(2)
+ application.SendNotification(); // require to load size(2)
+ application.Render();
// reload image
DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
END_TEST;
}
+
+int UtcDaliImageVisualSynchronousSizing03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliImageVisualSynchronousSizing03");
+
+ Property::Map imagePropertyMap;
+ imagePropertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE);
+ imagePropertyMap.Insert(Toolkit::ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME);
+ imagePropertyMap.Insert("synchronousSizing", true);
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Visual::Base visual1 = factory.CreateVisual(imagePropertyMap); // Create duplicated visuals, to check whether cache system works well.
+ Visual::Base visual2 = factory.CreateVisual(imagePropertyMap);
+ Visual::Base visual3 = factory.CreateVisual(imagePropertyMap);
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual1);
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 2, visual2);
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 3, visual3);
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); // set size(1), no renderer yet
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+
+ // load image as size 0x0 (Since we cannot ensure the size of actor yet)
+ // NOTE : This behavior might be changed in future.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ application.SendNotification(); // require to load size(1)
+
+ // load image as size 200x200 (Now we can ensure the size of actor is 200x200)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 2, TEST_LOCATION);
+
+ textureTrace.Reset();
+
+ // Unparent and Add again. Check whether the texture is cached.
+ actor.Unparent();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION);
+
+ textureTrace.Reset();
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(100.f, 100.f)); // set size(2)
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 3u, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION);
+
+ application.SendNotification(); // require to load size(2)
+
+ // load image as size 100x100 (Now we can ensure the size of actor is 100x100)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION);
+
+ END_TEST;
+}
{
mStartTimeNanoSceonds = GetNanoseconds();
std::ostringstream oss;
- oss << "[u:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetEllipsedUrl()) << "]";
+ oss << "[";
+ if(dimensions.GetWidth() > 0 || dimensions.GetHeight() > 0)
+ {
+ oss << "d:" << dimensions.GetWidth() << "x" << dimensions.GetHeight() << " ";
+ }
+ oss << "u:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetEllipsedUrl()) << "]";
// DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
}
oss << "s:" << pixelBuffers[0].GetWidth() << "x" << pixelBuffers[0].GetHeight() << " ";
oss << "p:" << pixelBuffers[0].IsAlphaPreMultiplied() << " ";
}
+ if(dimensions.GetWidth() > 0 || dimensions.GetHeight() > 0)
+ {
+ oss << "d:" << dimensions.GetWidth() << "x" << dimensions.GetHeight() << " ";
+ }
oss << "u:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetEllipsedUrl()) << "]";
// DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
// 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, 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));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, prevTextureId=%d, frameindex=%d, premultiplied=%d, refCount=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), 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
// Cache new texutre, and get cacheIndex.
cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
- 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);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
}
// The below code path is common whether we are using the cache or not.
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, prevTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d, prevTextureId=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId);
textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
}
void TextureManager::LoadTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
{
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::LoadTexture(): url:%s sync:%s\n", textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::LoadTexture(): size:%hux%hu url:%s sync:%s\n", textureInfo.desiredSize.GetWidth(), textureInfo.desiredSize.GetHeight(), textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
textureInfo.loadState = TextureManager::LoadState::LOADING;
if(!textureInfo.loadSynchronously)
{
void TextureManager::ObserveTexture(TextureManager::TextureInfo& textureInfo,
TextureUploadObserver* observer)
{
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ObserveTexture(): url:%s observer:%p\n", textureInfo.url.GetUrl().c_str(), observer);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ObserveTexture(): size:%hux%hu url:%s observer:%p\n", textureInfo.desiredSize.GetWidth(), textureInfo.desiredSize.GetHeight(), textureInfo.url.GetUrl().c_str(), observer);
if(observer)
{
{
TextureInfo& textureInfo(mTextureCacheManager[cacheIndex]);
- 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));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, " textureId:%d size:%hux%hu Url:%s CacheIndex:%d LoadState: %s\n", textureInfo.textureId, textureInfo.desiredSize.GetWidth(), textureInfo.desiredSize.GetHeight(), textureInfo.url.GetUrl().c_str(), cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
if(textureInfo.loadState != TextureManager::LoadState::CANCELLED && textureInfo.loadState != TextureManager::LoadState::MASK_CANCELLED)
{
// textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
Devel::PixelBuffer pixelBuffer = textureInfo.pixelBuffer;
textureInfo.pixelBuffer.Reset();
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): url:%s sync:%s\n", textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): size:%hux%hu url:%s sync:%s\n", textureInfo.desiredSize.GetWidth(), textureInfo.desiredSize.GetHeight(), textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
textureInfo.loadState = TextureManager::LoadState::MASK_APPLYING;
auto premultiplyOnLoad = textureInfo.preMultiplyOnLoad ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
// 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() observer:%p textureId:%d url:%s loadState:%s\n", observer, textureId, info->url.GetUrl().c_str(), GET_LOAD_STATE_STRING(info->loadState));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::NotifyObservers() observer:%p textureId:%d size:%hux%hu url:%s loadState:%s\n", observer, textureId, info->desiredSize.GetWidth(), info->desiredSize.GetHeight(), 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);
{RELEASE_POLICY_NAME, Toolkit::ImageVisual::Property::RELEASE_POLICY},
{ORIENTATION_CORRECTION_NAME, Toolkit::ImageVisual::Property::ORIENTATION_CORRECTION},
{FAST_TRACK_UPLOADING_NAME, Toolkit::DevelImageVisual::Property::FAST_TRACK_UPLOADING},
+ {SYNCHRONOUS_SIZING, Toolkit::DevelImageVisual::Property::SYNCHRONOUS_SIZING},
};
const int NAME_INDEX_MATCH_TABLE_SIZE = sizeof(NAME_INDEX_MATCH_TABLE) / sizeof(NAME_INDEX_MATCH_TABLE[0]);
// Load image immediately if LOAD_POLICY requires it
if(mLoadPolicy == Toolkit::ImageVisual::LoadPolicy::IMMEDIATE)
{
- Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize;
- auto attemptAtlasing = AttemptAtlasing();
- LoadTexture(attemptAtlasing, mAtlasRect, mTextures, size, TextureManager::ReloadPolicy::CACHED);
+ auto attemptAtlasing = AttemptAtlasing();
+ LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mDesiredSize, TextureManager::ReloadPolicy::CACHED);
}
}
{
if(mTextureId == TextureManager::INVALID_TEXTURE_ID)
{
- LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mDesiredSize, TextureManager::ReloadPolicy::CACHED);
+ LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize, TextureManager::ReloadPolicy::CACHED);
}
else
{
ResourceReady(Toolkit::Visual::ResourceStatus::PREPARING);
mLoadState = TextureManager::LoadState::NOT_STARTED;
+ // Need to reset textureset after change load state.
+ mTextures.Reset();
+
Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize;
LoadTexture(attemptAtlasing, mAtlasRect, mTextures, size, TextureManager::ReloadPolicy::FORCED);
break;
if(mLastRequiredSize != visualSize)
{
RemoveTexture();
+ mLoadState = TextureManager::LoadState::NOT_STARTED;
+
+ // Need to reset textureset after change load state.
+ mTextures.Reset();
- mLoadState = TextureManager::LoadState::NOT_STARTED;
bool attemptAtlasing = AttemptAtlasing();
- LoadTexture(attemptAtlasing, mAtlasRect, mTextures, visualSize, TextureManager::ReloadPolicy::FORCED);
+ LoadTexture(attemptAtlasing, mAtlasRect, mTextures, visualSize, TextureManager::ReloadPolicy::CACHED);
}
}
}
ComputeTextureSize();
mLoadState = TextureManager::LoadState::NOT_STARTED;
+
+ // Need to reset textureset after change load state.
+ mTextures.Reset();
}
void ImageVisual::ShowBrokenImage()