// 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: