Reload forces reloading causing the texture to be reloaded even if cached.
It updates all uses of this texture (same id) across all image visuals.
The texture is replaced hence the renderer gets updated
as already references the TextureSet.
Change-Id: Idb484d18373d54083727c80f563b7a5f7fb2be8c
// 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 )
{
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;
SamplingMode::BOX_THEN_LINEAR,
TextureManager::NO_ATLAS,
&observer,
- true );
+ true,
+ TextureManager::ReloadPolicy::CACHED );
const VisualUrl& url = textureManager.GetVisualUrl( textureId );
#include <dali-toolkit/public-api/align-enumerations.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
+
+
#include <toolkit-event-thread-callback.h>
#include "dummy-control.h"
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<Impl::DummyControl&>(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<Impl::DummyControl&>(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;
+}
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
--- /dev/null
+#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
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 ) &&
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;
}
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;
}
// INTERNAL HEADERS
#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
}
}
}
-
// 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 );
}
}
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();
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 );
}
}
+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 )
// 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 )
{
}
// 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();
*/
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:
/**
/**
* @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
* @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
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;
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
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
{
TextureManager::NO_ATLAS,
maskInfo->mCropToMask,
textureObserver,
- orientationCorrection);
+ orientationCorrection,
+ reloadPolicy );
}
TextureManager::LoadState loadState = GetTextureState( textureId );
}
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
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.
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 );
}
case TextureManager::LOAD_FINISHED:
case TextureManager::WAITING_FOR_MASK:
- case TextureManager::LOAD_FAILED:
// Loading has already completed. Do nothing.
break;
}
}
}
-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 );
{
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 );
}
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 )
{
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
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.
* @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
* 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,
* 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.
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
};
* @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,
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
}
* @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: