From: jmm Date: Wed, 12 Jun 2024 08:14:21 +0000 (+0900) Subject: Reload ImageVisual texture on visual size updates X-Git-Tag: dali_2.3.34~4^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F11%2F312611%2F8;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Reload ImageVisual texture on visual size updates Change-Id: I4135b0fb427b7fff2319079389050d91e38556a7 --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index 01d5b21..62df55a 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -4299,4 +4299,109 @@ int UtcDaliImageVisualDebugImageVisualShaderN2(void) DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); END_TEST; -} \ No newline at end of file +} + +int UtcDaliImageVisualSynchronousSizing01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualSynchronousSizing01"); + + Vector2 size = Vector2(64.0f, 64.0f); + uint32_t width = 64; + uint32_t height = 64; + + Property::Map imagePropertyMap; + imagePropertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); + imagePropertyMap.Insert(Toolkit::ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + imagePropertyMap.Insert(Toolkit::DevelImageVisual::Property::SYNCHRONOUS_SIZING, true); + + Toolkit::ImageView imageView = Toolkit::ImageView::New(); + imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, imagePropertyMap); + imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + imageView.SetProperty(Actor::Property::SIZE, size); + + DALI_TEST_EQUALS(imageView.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(imageView); + + // Wait for image loading(1) + // (Texture size is its original size, not the actor size.) + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, 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(); + DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION); + + Texture texture = textures.GetTexture(0); + DALI_TEST_EQUALS(texture.GetWidth(), width, TEST_LOCATION); + DALI_TEST_EQUALS(texture.GetHeight(), height, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualSynchronousSizing02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualSynchronousSizing02"); + + Property::Map imagePropertyMap; + imagePropertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); + imagePropertyMap.Insert(Toolkit::ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + imagePropertyMap.Insert(Toolkit::DevelImageVisual::Property::SYNCHRONOUS_SIZING, true); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Visual::Base visual = factory.CreateVisual(imagePropertyMap); + + Vector2 size; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + 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); + application.SendNotification(); + application.Render(); // require to load size(1) + + 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) + + // reload image + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + visual.GetNaturalSize(size); // get size(2) + DALI_TEST_EQUALS(size, Vector2(100.0f, 100.0f), 0.001f, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h index 90e868e..500f86e 100644 --- a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h @@ -210,7 +210,15 @@ enum Type * This flag is useful if given resource has low fps, so we don't need to render every frame. * @note It is used in the AnimatedVectorImageVisual. The default is false. */ - NOTIFY_AFTER_RASTERIZATION = ORIENTATION_CORRECTION + 17 + NOTIFY_AFTER_RASTERIZATION = ORIENTATION_CORRECTION + 17, + + /** + * @brief Whether to synchronize image texture size to visual size. + * @details Name "synchronousSizing", type Property::BOOLEAN. + * If this property is true, ImageVisual ignores mDesiredSize. + * @note Used by the ImageVisual. The default is false. + */ + SYNCHRONOUS_SIZING = ORIENTATION_CORRECTION + 18 }; } //namespace Property diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 147e617..c8c7375 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -188,6 +188,7 @@ ImageVisual::ImageVisual(VisualFactoryCache& factoryCache, mImageUrl(imageUrl), mMaskingData(), mDesiredSize(size), + mLastRequiredSize(size), mTextureId(TextureManager::INVALID_TEXTURE_ID), mTextures(), mImageVisualShaderFactory(shaderFactory), @@ -263,8 +264,9 @@ void ImageVisual::DoSetProperties(const Property::Map& propertyMap) // Load image immediately if LOAD_POLICY requires it if(mLoadPolicy == Toolkit::ImageVisual::LoadPolicy::IMMEDIATE) { - auto attemptAtlasing = AttemptAtlasing(); - LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, TextureManager::ReloadPolicy::CACHED); + Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize; + auto attemptAtlasing = AttemptAtlasing(); + LoadTexture(attemptAtlasing, mAtlasRect, mTextures, size, TextureManager::ReloadPolicy::CACHED); } } @@ -457,6 +459,12 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va value.Get(mUseFastTrackUploading); break; } + + case Toolkit::DevelImageVisual::Property::SYNCHRONOUS_SIZING: + { + value.Get(mUseSynchronousSizing); + break; + } } } @@ -474,7 +482,30 @@ void ImageVisual::AllocateMaskData() void ImageVisual::GetNaturalSize(Vector2& naturalSize) { - if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0) + if(mUseSynchronousSizing && (mLastRequiredSize.GetWidth() > 0 && mLastRequiredSize.GetHeight() > 0)) + { + if(mImpl->mRenderer) + { + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + if(mTextureSize != Vector2::ZERO) + { + naturalSize = mTextureSize; + return; + } + } + } + } + + naturalSize.x = mLastRequiredSize.GetWidth(); + naturalSize.y = mLastRequiredSize.GetHeight(); + return; + } + else if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0) { if(mImpl->mRenderer) { @@ -596,10 +627,12 @@ void ImageVisual::OnInitialize() } } -void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload) +void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, const Dali::ImageDimensions& size, TextureManager::ReloadPolicy forceReload) { TextureManager& textureManager = mFactoryCache.GetTextureManager(); + mLastRequiredSize = size; + ImageAtlasManagerPtr atlasManager = nullptr; AtlasUploadObserver* atlasUploadObserver = nullptr; auto textureObserver = this; @@ -643,6 +676,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te forceReload == TextureManager::ReloadPolicy::CACHED && (mImageUrl.GetProtocolType() == VisualUrl::LOCAL || mImageUrl.GetProtocolType() == VisualUrl::REMOTE) && !synchronousLoading && + !mUseSynchronousSizing && !atlasing && !mImpl->mCustomShader && !(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid())) @@ -651,13 +685,14 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te } else if(mUseFastTrackUploading) { - DALI_LOG_DEBUG_INFO("FastTrack : Fail to load fast track. mUrl : [%s]%s%s%s%s%s%s%s%s\n", + DALI_LOG_DEBUG_INFO("FastTrack : Fail to load fast track. mUrl : [%s]%s%s%s%s%s%s%s%s%s\n", mImageUrl.GetEllipsedUrl().c_str(), (mLoadPolicy != Toolkit::ImageVisual::LoadPolicy::ATTACHED) ? "/ mLoadPolicy != ATTACHED" : "", (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::DETACHED) ? "/ mReleasePolicy != DETACHED" : "", (forceReload != TextureManager::ReloadPolicy::CACHED) ? "/ forceReload != CACHED" : "", (!(mImageUrl.GetProtocolType() == VisualUrl::LOCAL || mImageUrl.GetProtocolType() == VisualUrl::REMOTE)) ? "/ url is not image" : "", (synchronousLoading) ? "/ synchronousLoading" : "", + (mUseSynchronousSizing) ? "/ useSynchronousSizing " : "", (atlasing) ? "/ atlasing" : "", (mImpl->mCustomShader) ? "/ use customs shader" : "", (mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid()) ? "/ use masking url" : ""); @@ -671,7 +706,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD); // Set new TextureSet with fast track loading task - mFastTrackLoadingTask = new FastTrackLoadingTask(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mOrientationCorrection, preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF, mFactoryCache.GetLoadYuvPlanes(), MakeCallback(this, &ImageVisual::FastLoadComplete)); + mFastTrackLoadingTask = new FastTrackLoadingTask(mImageUrl, size, mFittingMode, mSamplingMode, mOrientationCorrection, preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF, mFactoryCache.GetLoadYuvPlanes(), MakeCallback(this, &ImageVisual::FastLoadComplete)); TextureSet textureSet = TextureSet::New(); if(!mFastTrackLoadingTask->mLoadPlanesAvaliable) @@ -699,7 +734,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te } else { - textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad); + textures = textureManager.LoadTexture(mImageUrl, size, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad); } if(textures) @@ -759,7 +794,7 @@ void ImageVisual::InitializeRenderer() { if(mTextureId == TextureManager::INVALID_TEXTURE_ID) { - LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, TextureManager::ReloadPolicy::CACHED); + LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mDesiredSize, TextureManager::ReloadPolicy::CACHED); } else { @@ -897,9 +932,11 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, sync); if(mImageUrl.IsValid()) { + Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize; + map.Insert(Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl()); - map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); - map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, size.GetWidth()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, size.GetHeight()); } map.Insert(Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode); @@ -934,6 +971,7 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::ImageVisual::Property::ORIENTATION_CORRECTION, mOrientationCorrection); map.Insert(Toolkit::DevelImageVisual::Property::FAST_TRACK_UPLOADING, mUseFastTrackUploading); + map.Insert(Toolkit::DevelImageVisual::Property::SYNCHRONOUS_SIZING, mUseSynchronousSizing); } void ImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const @@ -942,8 +980,9 @@ void ImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); if(mImageUrl.IsValid()) { - map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); - map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); + Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize; + map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, size.GetWidth()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, size.GetHeight()); } } @@ -961,7 +1000,8 @@ void ImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::P ResourceReady(Toolkit::Visual::ResourceStatus::PREPARING); mLoadState = TextureManager::LoadState::NOT_STARTED; - LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, TextureManager::ReloadPolicy::FORCED); + Dali::ImageDimensions size = mUseSynchronousSizing ? mLastRequiredSize : mDesiredSize; + LoadTexture(attemptAtlasing, mAtlasRect, mTextures, size, TextureManager::ReloadPolicy::FORCED); break; } } @@ -973,6 +1013,28 @@ void ImageVisual::OnSetTransform() { mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } + + if(mUseSynchronousSizing) + { + // Get current visual size + Vector2 size = mImpl->mTransform.GetVisualSize(mImpl->mControlSize); + uint32_t maximumNumber = std::numeric_limits::max(); + uint32_t sizeWidth = static_cast(roundf(size.width)); + sizeWidth = std::min(sizeWidth, maximumNumber); + uint32_t sizeHeight = static_cast(roundf(size.height)); + sizeHeight = std::min(sizeHeight, maximumNumber); + Dali::ImageDimensions visualSize = Dali::ImageDimensions(sizeWidth, sizeHeight); + + // Reload if visual size is updated + if(mLastRequiredSize != visualSize) + { + RemoveTexture(); + + mLoadState = TextureManager::LoadState::NOT_STARTED; + bool attemptAtlasing = AttemptAtlasing(); + LoadTexture(attemptAtlasing, mAtlasRect, mTextures, visualSize, TextureManager::ReloadPolicy::FORCED); + } + } } void ImageVisual::UpdateShader() diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index 445218b..dd1c6b1 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -275,10 +275,10 @@ private: * @param[in, out] atlasing flag if the image has been put in a atlas (true), passing false will not atlas even if possible. * @param[out] atlasRect if atlasing is used this the texture area of the image in the atlas. * @param[out] textures resulting texture set from the image loading. - * @param[in] orientationCorrection flag determines if orientation correction should be performed + * @param[in] size if mUseSynchronousSizing is true this is the size of visual, else it is mDesiredSize * @param[in] forceReload flag determines if the texture should be reloaded from its source or use the cached texture. */ - void LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload); + void LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, const Dali::ImageDimensions& size, TextureManager::ReloadPolicy forceReload); /** * @brief Checks if atlasing should be attempted @@ -369,6 +369,7 @@ private: TextureManager::MaskingDataPointer mMaskingData; Dali::ImageDimensions mDesiredSize; + Dali::ImageDimensions mLastRequiredSize; TextureManager::TextureId mTextureId; TextureSet mTextures; Vector2 mTextureSize; @@ -395,6 +396,7 @@ private: bool mUseFastTrackUploading{false}; ///< True if we use fast tack feature. bool mRendererAdded{false}; ///< True if renderer added into actor. bool mUseBrokenImageRenderer{false}; ///< True if renderer changed as broken image. + bool mUseSynchronousSizing{false}; ///< True if we need to synchronize image texture size to visual size, otherwise use mDesiredSize. }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index ae39540..d4df78c 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -213,6 +213,7 @@ const char* const FAST_TRACK_UPLOADING_NAME("fastTrackUploading"); const char* const ENABLE_BROKEN_IMAGE("enableBrokenImage"); const char* const ENABLE_FRAME_CACHE("enableFrameCache"); const char* const NOTIFY_AFTER_RASTERIZATION("notifyAfterRasterization"); +const char* const SYNCHRONOUS_SIZING("synchronousSizing"); // Text visual const char* const TEXT_PROPERTY("text"); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index 9835299..1e7eea9 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -115,6 +115,7 @@ extern const char* const FAST_TRACK_UPLOADING_NAME; extern const char* const ENABLE_BROKEN_IMAGE; extern const char* const ENABLE_FRAME_CACHE; extern const char* const NOTIFY_AFTER_RASTERIZATION; +extern const char* const SYNCHRONOUS_SIZING; // Text visual extern const char* const TEXT_PROPERTY;