From: HyunJu Shin Date: Thu, 30 Nov 2017 03:10:54 +0000 (+0000) Subject: Merge "Added text direction property" into devel/master X-Git-Tag: dali_1.3.2~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=4b7e732208c99260eb1f7a19864fcd8ad30ed12c;hp=77a31b18a427cfc72cb17f0b14925694ea638851 Merge "Added text direction property" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.cpp b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.cpp index f5c5aeb..d792609 100644 --- a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.cpp +++ b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.cpp @@ -70,7 +70,7 @@ void DummyVisual::DoSetOnStage( Actor& actor ) // Implement if required } -void DummyVisual::OnDoAction( const Property::Index actionName, const Property::Value attributes ) +void DummyVisual::OnDoAction( const Property::Index actionName, const Property::Value& attributes ) { if ( DummyVisual::TEST_ACTION == actionName ) { diff --git a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h index 73e8185..23334ba 100644 --- a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h +++ b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.h @@ -80,7 +80,7 @@ protected: virtual void DoSetProperties( const Property::Map& propertyMap ) override; virtual void OnSetTransform() override; virtual void DoSetOnStage( Actor& actor ) override; - virtual void OnDoAction( const Property::Index actionName, const Property::Value attributes ); + virtual void OnDoAction( const Property::Index actionName, const Property::Value& attributes ) override; private: unsigned int mActionCounter; diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp index c2161d1..e09dd06 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp @@ -61,7 +61,8 @@ int UtcTextureManagerRequestLoad(void) SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS, &observer, - true ); + true, + TextureManager::ReloadPolicy::CACHED ); const VisualUrl& url = textureManager.GetVisualUrl( textureId ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index 9869f21..d695e92 100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@ -27,6 +27,9 @@ #include #include #include +#include + + #include #include "dummy-control.h" @@ -952,3 +955,96 @@ int UtcDaliControlPaddingProperty(void) END_TEST; } + +int UtcDaliControlDoAction(void) +{ + ToolkitTestApplication application; + tet_infoline( "DoAction on a visual registered with a control" ); + + // 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(dummyControl.GetImplementation()); + + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual ); + dummyControl.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( dummyControl ); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION ); + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); + textureTrace.Reset(); + + Property::Map attributes; + 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.CountMethod("DeleteTextures"), 1, TEST_LOCATION ); + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliControlDoActionWhenNotStage(void) +{ + ToolkitTestApplication application; + tet_infoline( "DoAction on a visual registered with a control 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(dummyControl.GetImplementation()); + + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual ); + dummyControl.SetSize(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; + 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( "Adding control to stage will in turn add the visual to the stage" ); + + Stage::GetCurrent().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(); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 275e14d..d515119 100644 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -92,6 +92,7 @@ devel_api_visual_factory_header_files = \ devel_api_visuals_header_files = \ $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \ + $(devel_api_src_dir)/visuals/image-visual-actions-devel.h \ $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \ $(devel_api_src_dir)/visuals/visual-properties-devel.h diff --git a/dali-toolkit/devel-api/visuals/image-visual-actions-devel.h b/dali-toolkit/devel-api/visuals/image-visual-actions-devel.h new file mode 100644 index 0000000..f76e772 --- /dev/null +++ b/dali-toolkit/devel-api/visuals/image-visual-actions-devel.h @@ -0,0 +1,51 @@ +#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_ACTIONS_DEVEL_H +#define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_ACTIONS_DEVEL_H + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +namespace Dali +{ + +namespace Toolkit +{ + +namespace DevelImageVisual +{ + +/** + * @brief Actions that the image visual can perform. These actions are called through the Visual::Base::DoAction API. + */ +namespace Action +{ +/** + * @brief The available actions for this visual + */ +enum Type +{ + RELOAD = 0, ///< Force reloading of the image, all visuals using this image will get the latest one. +}; + +} // namespace Actions + +} // namespace DevelImageVisual + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_ACTIONS_DEVEL_H diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index 187e62f..b061268 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -486,9 +486,6 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base if( !visualReplaced ) // New registration entry { - // monitor when the visual resources are ready - StartObservingVisual( visual ); - // If we've not set the depth-index value, we have more than one visual and the visual does not have a depth index, then set it to be the highest if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) && ( mVisuals.Size() > 0 ) && diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp index 32f2bc0..03dbcbc 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp @@ -105,7 +105,7 @@ void FixedImageCache::LoadBatch() mImageUrls[ mUrlIndex ].mTextureId = mTextureManager.RequestLoad( url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS, - this, ENABLE_ORIENTATION_CORRECTION ); + this, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED ); mRequestingLoad = false; ++mUrlIndex; } diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index 847e681..9c3f82f 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@ -142,7 +142,7 @@ void RollingImageCache::LoadBatch() mImageUrls[ imageFrame.mUrlIndex ].mTextureId = mTextureManager.RequestLoad( url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS, - this, ENABLE_ORIENTATION_CORRECTION ); + this, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED ); mRequestingLoad = false; } diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 9afcb29..8845541 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -33,6 +33,7 @@ // INTERNAL HEADERS #include #include +#include #include #include #include @@ -411,12 +412,12 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap ) } } } - // Load image immediately if LOAD_POLICY requires it if ( mLoadPolicy == DevelImageVisual::LoadPolicy::IMMEDIATE ) { - auto attemptAtlasing = mAttemptAtlasing; - LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection ); + auto attemptAtlasing = AttemptAtlasing(); + LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, + TextureManager::ReloadPolicy::CACHED ); } } @@ -759,7 +760,8 @@ bool ImageVisual::IsSynchronousResourceLoading() const return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; } -void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection ) +void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, + TextureManager::ReloadPolicy forceReload ) { TextureManager& textureManager = mFactoryCache.GetTextureManager(); @@ -776,28 +778,35 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, IsSynchronousResourceLoading(), mTextureId, atlasRect, atlasing, mLoading, mWrapModeU, - mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection ); + mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, + mOrientationCorrection, + forceReload ); + + if( atlasing ) // Flag needs to be set before creating renderer + { + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + } + else + { + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + } } -void ImageVisual::InitializeRenderer() +bool ImageVisual::AttemptAtlasing() { - auto attemptAtlasing = ( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL && mAttemptAtlasing ); + return ( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL && mAttemptAtlasing ); +} +void ImageVisual::InitializeRenderer() +{ + auto attemptAtlasing = AttemptAtlasing(); // texture set has to be created first as we need to know if atlasing succeeded or not // when selecting the shader if( mTextureId == TextureManager::INVALID_TEXTURE_ID && ! mTextures ) // Only load the texture once { - LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection ); - } - - if( attemptAtlasing ) // Flag needs to be set before creating renderer - { - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; - } - else - { - mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, + TextureManager::ReloadPolicy::CACHED ); } CreateRenderer( mTextures ); @@ -960,6 +969,22 @@ void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const } } +void ImageVisual::OnDoAction( const Dali::Property::Index actionName, const Dali::Property::Value& attributes ) +{ + // Check if action is valid for this visual type and perform action if possible + + switch ( actionName ) + { + case DevelImageVisual::Action::RELOAD: + { + auto attemptAtlasing = AttemptAtlasing(); + LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, + TextureManager::ReloadPolicy::FORCED ); + break; + } + } +} + void ImageVisual::OnSetTransform() { if( mImpl->mRenderer ) @@ -1031,7 +1056,8 @@ void ImageVisual::ApplyImageToSampler( const Image& image ) // From existing atlas manager void ImageVisual::UploadCompleted() { - // Texture has been uploaded. If weak handle is holding a placement actor, it is the time to add the renderer to actor. + // Texture has been uploaded. If weak handle is holding a placement actor, + // it is the time to add the renderer to actor. Actor actor = mPlacementActor.GetHandle(); if( actor ) { @@ -1046,7 +1072,8 @@ void ImageVisual::UploadCompleted() } // From Texture Manager -void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle ) +void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas, + const Vector4& atlasRectangle ) { Toolkit::Visual::ResourceStatus resourceStatus; Actor actor = mPlacementActor.GetHandle(); diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index 729185a..3108b55 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -177,6 +177,11 @@ public: // from Visual */ virtual void DoCreateInstancePropertyMap( Property::Map& map ) const; + /** + * @copydoc Visual::Base::OnDoAction + */ + virtual void OnDoAction( const Dali::Property::Index actionName, const Dali::Property::Value& attributes ) override; + protected: /** @@ -222,12 +227,12 @@ protected: /** * @copydoc Visual::Base::DoSetOffStage */ - virtual void DoSetOffStage( Actor& actor ); + virtual void DoSetOffStage( Actor& actor ) ; /** * @copydoc Visual::Base::OnSetTransform */ - virtual void OnSetTransform(); + virtual void OnSetTransform() ; /** * @copydoc Visual::Base::IsResourceReady @@ -280,8 +285,15 @@ private: * @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] 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 ); + + /** + * @brief Checks if atlasing should be attempted + * @return bool returns true if atlasing can be attempted. */ - void LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection ); + bool AttemptAtlasing(); /** * @brief Initializes the Dali::Renderer from the image url diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index 308b1ee..b2e0d03 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -108,7 +108,8 @@ TextureSet TextureManager::LoadTexture( bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect, bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver, - AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection ) + AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ) { TextureSet textureSet; @@ -135,7 +136,8 @@ TextureSet TextureManager::LoadTexture( PixelData data; if( url.IsValid() ) { - Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection ); + Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode, + orientationCorrection ); if( pixelBuffer ) { data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer @@ -185,7 +187,8 @@ TextureSet TextureManager::LoadTexture( atlasingStatus = false; if( !maskInfo ) { - textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, textureObserver, orientationCorrection ); + textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, + textureObserver, orientationCorrection, reloadPolicy ); } else { @@ -197,7 +200,8 @@ TextureSet TextureManager::LoadTexture( TextureManager::NO_ATLAS, maskInfo->mCropToMask, textureObserver, - orientationCorrection); + orientationCorrection, + reloadPolicy ); } TextureManager::LoadState loadState = GetTextureState( textureId ); @@ -222,67 +226,80 @@ TextureSet TextureManager::LoadTexture( } TextureManager::TextureId TextureManager::RequestLoad( - const VisualUrl& url, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlas, - TextureUploadObserver* observer, - bool orientationCorrection ) + const VisualUrl& url, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlas, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ) { - return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, UPLOAD_TO_TEXTURE, observer, orientationCorrection ); + return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, + false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy ); } TextureManager::TextureId TextureManager::RequestLoad( - const VisualUrl& url, - TextureId maskTextureId, - float contentScale, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlas, - bool cropToMask, - TextureUploadObserver* observer, - bool orientationCorrection ) -{ - return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection ); + const VisualUrl& url, + TextureId maskTextureId, + float contentScale, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlas, + bool cropToMask, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ) +{ + return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, + cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy ); } TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl ) { // Use the normal load procedure to get the alpha mask. - return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true ); + return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, + SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true, + TextureManager::ReloadPolicy::CACHED ); } TextureManager::TextureId TextureManager::RequestLoadInternal( - const VisualUrl& url, - TextureId maskTextureId, - float contentScale, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - UseAtlas useAtlas, - bool cropToMask, - StorageType storageType, - TextureUploadObserver* observer, - bool orientationCorrection ) + const VisualUrl& url, + TextureId maskTextureId, + float contentScale, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + UseAtlas useAtlas, + bool cropToMask, + StorageType storageType, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ) { // First check if the requested Texture is cached. - const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId ); + const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, + maskTextureId ); TextureManager::TextureId textureId = INVALID_TEXTURE_ID; // Look up the texture by hash. Note: The extra parameters are used in case of a hash collision. - int cacheIndex = FindCachedTexture( textureHash, url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId ); + int cacheIndex = FindCachedTexture( textureHash, url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, + maskTextureId ); // Check if the requested Texture exists in the cache. if( cacheIndex != INVALID_CACHE_INDEX ) { - // Mark this texture being used by another client resource. - ++( mTextureInfoContainer[ cacheIndex ].referenceCount ); + if ( TextureManager::ReloadPolicy::CACHED == reloadPolicy ) + { + // Mark this texture being used by another client resource. Forced reload would replace the current texture + // without the need for incrementing the reference count. + ++( mTextureInfoContainer[ cacheIndex ].referenceCount ); + } textureId = mTextureInfoContainer[ cacheIndex ].textureId; - - DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture @%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId ); + DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d\n", + url.GetUrl().c_str(), observer, cacheIndex, textureId ); } if( textureId == INVALID_TEXTURE_ID ) // There was no caching, or caching not required @@ -294,7 +311,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( false, cropToMask, useAtlas, textureHash, orientationCorrection ) ); cacheIndex = mTextureInfoContainer.size() - 1u; - DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId ); + DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", + url.GetUrl().c_str(), observer, cacheIndex, textureId ); } // The below code path is common whether we are using the cache or not. @@ -311,9 +329,20 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( textureInfo.loadState == TextureManager::UPLOADED ? "UPLOADED" : textureInfo.loadState == TextureManager::CANCELLED ? "CANCELLED" : "Unknown" ); - // Check if we should add the observer. Only do this if we have not loaded yet and it will not have loaded by the end of this method. + // Force reloading of texture by setting loadState unless already loading or cancelled. + if ( TextureManager::ReloadPolicy::FORCED == reloadPolicy && TextureManager::LOADING != textureInfo.loadState && + TextureManager::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, textureId ); + textureInfo.loadState = TextureManager::NOT_STARTED; + } + + // Check if we should add the observer. + // Only do this if we have not loaded yet and it will not have loaded by the end of this method. switch( textureInfo.loadState ) { + case TextureManager::LOAD_FAILED: // Failed notifies observer which then stops observing. case TextureManager::NOT_STARTED: { LoadTexture( textureInfo ); @@ -346,7 +375,6 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( } case TextureManager::LOAD_FINISHED: case TextureManager::WAITING_FOR_MASK: - case TextureManager::LOAD_FAILED: // Loading has already completed. Do nothing. break; } @@ -511,7 +539,8 @@ void TextureManager::ObserveTexture( TextureInfo& textureInfo, } } -void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingContainer, uint32_t id, Devel::PixelBuffer pixelBuffer ) +void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingContainer, uint32_t id, + Devel::PixelBuffer pixelBuffer ) { DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::AsyncLoadComplete( id:%d )\n", id ); @@ -644,10 +673,14 @@ void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo { DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, " TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId ); - 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.textureSet = TextureSet::New(); + if ( ! textureInfo.textureSet ) + { + textureInfo.textureSet = TextureSet::New(); + } textureInfo.textureSet.SetTexture( 0u, texture ); } @@ -833,7 +866,8 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer ) for( unsigned int i = 0; i < count; ++i ) { TextureInfo& textureInfo( mTextureInfoContainer[i] ); - for( TextureInfo::ObserverListType::Iterator j = textureInfo.observerList.Begin(); j != textureInfo.observerList.End(); ) + for( TextureInfo::ObserverListType::Iterator j = textureInfo.observerList.Begin(); + j != textureInfo.observerList.End(); ) { if( *j == observer ) { diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.h b/dali-toolkit/internal/visuals/texture-manager-impl.h index b385344..d27b87f 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@ -104,6 +104,15 @@ public: LOAD_FAILED ///< Async loading failed, e.g. connection problem }; + /** + * @breif Types of reloading policies + */ + enum class ReloadPolicy + { + CACHED = 0, ///< Loads cached texture if it exists. + FORCED ///< Forces reloading of texture. + }; + public: struct MaskingData @@ -139,7 +148,8 @@ public: Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver, AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, - bool orientationCorrection ); + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ); /** * @brief Requests an image load of the given URL. @@ -158,15 +168,17 @@ public: * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual. * This is called when an image load completes (or fails). * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data + * @param[in] reloadPolicy Forces a reload of the texture even if already cached * @return A TextureId to use as a handle to reference this Texture */ - TextureId RequestLoad( const VisualUrl& url, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlasing, - TextureUploadObserver* observer, - bool orientationCorrection ); + TextureId RequestLoad( const VisualUrl& url, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlasing, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ); /** * @brief Requests an image load of the given URL, when the texture has @@ -179,29 +191,36 @@ public: * When the client has finished with the Texture, Remove() should be called. * * @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] maskTextureId The texture id of an image to mask this with + * (can be INVALID if no masking required) * @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 * @param[in] samplingMode The SamplingMode to use - * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful, - * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver. - * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size. If false, then the mask will be scaled to fit the image before being applied. - * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual. + * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still + * be loaded, and marked successful, + * but "useAtlasing" will be set to false in the "UploadCompleted" callback from + * the TextureManagerUploadObserver. + * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size. + * If false, then the mask will be scaled to fit the image before being applied. + * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" + * virtual. * This is called when an image load completes (or fails). * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data + * @param[in] reloadPolicy Forces a reload of the texture even if already cached * @return A TextureId to use as a handle to reference this Texture */ - TextureId RequestLoad( const VisualUrl& url, - TextureId maskTextureId, - float contentScale, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlasing, - bool cropToMask, - TextureUploadObserver* observer, - bool orientationCorrection ); + TextureId RequestLoad( const VisualUrl& url, + TextureId maskTextureId, + float contentScale, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlasing, + bool cropToMask, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ); /** * Requests a masking image to be loaded. This mask is not uploaded to GL, @@ -266,32 +285,38 @@ private: * When the client has finished with the Texture, Remove() should be called. * * @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] 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] 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 * @param[in] samplingMode The SamplingMode to use - * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful, - * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver. - * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before masking. + * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be + * loaded, and marked successful, but "useAtlasing" will be set to false in the + * "UploadCompleted" callback from the TextureManagerUploadObserver. + * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before + * masking. * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU - * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual. + * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" + * virtual. * This is called when an image load completes (or fails). * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data + * @param[in] reloadPolicy Forces a reload of the texture even if already cached * @return A TextureId to use as a handle to reference this Texture */ TextureId RequestLoadInternal( - const VisualUrl& url, - TextureId maskTextureId, - float contentScale, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - UseAtlas useAtlas, - bool cropToMask, - StorageType storageType, - TextureUploadObserver* observer, - bool orientationCorrection ); + const VisualUrl& url, + TextureId maskTextureId, + float contentScale, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + UseAtlas useAtlas, + bool cropToMask, + StorageType storageType, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy ); typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching. @@ -356,7 +381,8 @@ private: Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode StorageType storageType:1; ///< CPU storage / GPU upload; bool loadSynchronously:1; ///< True if synchronous loading was requested - UseAtlas useAtlas:1; ///< USE_ATLAS if an atlas was requested. This is updated to false if atlas is not used + UseAtlas useAtlas:1; ///< USE_ATLAS if an atlas was requested. + ///< This is updated to false if atlas is not used bool cropToMask:1; ///< true if the image should be cropped to the mask size. bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data }; @@ -537,10 +563,12 @@ private: * @brief Load a new texture. * @param[in] textureId TextureId to reference the texture that will be loaded * @param[in] url The URL of the image to load - * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic + * @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 * @param[in] samplingMode The SamplingMode to use - * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image, e.g., from portrait to landscape + * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image, + * e.g., from portrait to landscape */ void Load(TextureId textureId, const VisualUrl& url, diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 3473509..e4f12c8 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -342,7 +342,7 @@ bool Visual::Base::IsOnStage() const return mImpl->mFlags & Impl::IS_ON_STAGE; } -void Visual::Base::OnDoAction( const Property::Index actionId, const Property::Value attributes ) +void Visual::Base::OnDoAction( const Property::Index actionId, const Property::Value& attributes ) { // May be overriden by derived class } diff --git a/dali-toolkit/internal/visuals/visual-base-impl.h b/dali-toolkit/internal/visuals/visual-base-impl.h index 996fa3c..6fc777d 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-impl.h @@ -315,7 +315,7 @@ protected: * @param[in] actionId The action to perform * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) */ - virtual void OnDoAction( const Property::Index actionId, const Property::Value attributes ); + virtual void OnDoAction( const Property::Index actionId, const Property::Value& attributes ); protected: