END_TEST;
}
+int UtcDaliImageViewSyncSVGLoading(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline("ImageView Testing SVG image sync loading");
+
+ // Sync loading, automatic atlasing for small size image
+ {
+ TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+ callStack.Reset();
+ callStack.Enable(true);
+
+ ImageView imageView = ImageView::New( );
+
+ // Sync loading is used
+ Property::Map syncLoadingMap;
+ syncLoadingMap.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::URL, TEST_RESOURCE_DIR "/svg1.svg" );
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+ imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap );
+
+ Stage::GetCurrent().Add( imageView );
+ DALI_TEST_CHECK( imageView );
+
+ application.SendNotification();
+ application.Render(16);
+ Vector3 naturalSize = imageView.GetNaturalSize();
+
+ DALI_TEST_EQUALS( naturalSize.width, 100.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( naturalSize.height, 100.0f, TEST_LOCATION );
+
+ }
+ END_TEST;
+}
+
+int UtcDaliImageViewAsyncSVGLoading(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline("ImageView Testing SVG image async loading");
+
+ // Sync loading, automatic atlasing for small size image
+ {
+ TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+ callStack.Reset();
+ callStack.Enable(true);
+
+ ImageView imageView = ImageView::New( );
+
+ // Sync loading is used
+ Property::Map syncLoadingMap;
+ syncLoadingMap.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::URL, TEST_RESOURCE_DIR "/svg1.svg" );
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+ imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap );
+
+ Stage::GetCurrent().Add( imageView );
+ DALI_TEST_CHECK( imageView );
+
+ application.SendNotification();
+ application.Render(16);
+ Vector3 naturalSize = imageView.GetNaturalSize();
+
+ DALI_TEST_EQUALS( naturalSize.width, 100.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( naturalSize.height, 100.0f, TEST_LOCATION );
+ }
+ END_TEST;
+}
+
+int UtcDaliImageViewSVGLoadingSyncSetInvalidValue(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline("ImageView Testing SVG image async loading");
+
+ // Sync loading, automatic atlasing for small size image
+ {
+ TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+ callStack.Reset();
+ callStack.Enable(true);
+
+ ImageView imageView = ImageView::New( );
+
+ // Sync loading is used
+ Property::Map syncLoadingMap;
+ syncLoadingMap.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::URL, TEST_RESOURCE_DIR "/svg1.svg" );
+
+ // Check to set invalid value
+ // The SYNCHRONOUS_LOADING property must be set to the bool value.
+ // Check if error log is outputted when setting other value like string.
+ // Even if the wrong value is set, the image will be shown normally, and the synchronous value should be the default value(false).
+ syncLoadingMap.Insert( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, std::to_string(5) );
+ imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap );
+
+ Stage::GetCurrent().Add( imageView );
+ DALI_TEST_CHECK( imageView );
+
+ application.SendNotification();
+ application.Render(16);
+ Vector3 naturalSize = imageView.GetNaturalSize();
+ DALI_TEST_EQUALS( naturalSize.width, 100.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( naturalSize.height, 100.0f, TEST_LOCATION );
+
+ Property::Value value = imageView.GetProperty( ImageView::Property::IMAGE );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ Property::Value* sync = map->Find( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING );
+ DALI_TEST_CHECK( sync );
+ DALI_TEST_EQUALS( false, sync->Get< bool >(), TEST_LOCATION );
+
+ }
+ END_TEST;
+}
+
int UtcDaliImageViewSvgLoadingFailure(void)
{
ToolkitTestApplication application;
mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
}
-bool ImageVisual::IsSynchronousResourceLoading() const
-{
- return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
-}
-
void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection,
TextureManager::ReloadPolicy forceReload )
{
: TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
- mMaskingData, IsSynchronousResourceLoading(), mTextureId,
+ mMaskingData, IsSynchronousLoadingRequired(), mTextureId,
atlasRect, mAtlasRectSize, atlasing, mLoading, mWrapModeU,
mWrapModeV, textureObserver, atlasUploadObserver, atlasManager,
mOrientationCorrection, forceReload, preMultiplyOnLoad);
map.Clear();
map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
- bool sync = IsSynchronousResourceLoading();
+ bool sync = IsSynchronousLoadingRequired();
map.Insert( SYNCHRONOUS_LOADING, sync );
if( mImageUrl.IsValid() )
{
void CreateNativeImageRenderer( NativeImage& nativeImage );
/**
- * @brief Query whether resources requires to be loaded synchronously.
- * @return Returns true if synchronous resource loading is required, false otherwise.
- */
- bool IsSynchronousResourceLoading() const;
-
- /**
* Creates the texture set and adds the texture to it
* @param[out] textureRect The texture area of the texture in the atlas.
* @param[in] url The URL of the image resource to use.
mWidth( width ),
mHeight( height )
{
+ mRasterizer = nsvgCreateRasterizer();
+}
+
+RasterizingTask::~RasterizingTask()
+{
+ nsvgDeleteRasterizer( mRasterizer );
}
void RasterizingTask::Load()
}
}
-void RasterizingTask::Rasterize( NSVGrasterizer* rasterizer )
+void RasterizingTask::Rasterize( )
{
if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u )
{
unsigned int bufferSize = bufferStride * mHeight;
unsigned char* buffer = new unsigned char [bufferSize];
- nsvgRasterize(rasterizer, mParsedSvg, 0.f,0.f,scale,
+ nsvgRasterize(mRasterizer, mParsedSvg, 0.f,0.f,scale,
buffer, mWidth, mHeight,
bufferStride );
: mTrigger( trigger ),
mIsThreadWaiting( false )
{
- mRasterizer = nsvgCreateRasterizer();
}
SvgRasterizeThread::~SvgRasterizeThread()
{
-
- nsvgDeleteRasterizer( mRasterizer );
delete mTrigger;
}
while( RasterizingTaskPtr task = NextTaskToProcess() )
{
task->Load( );
- task->Rasterize( mRasterizer );
+ task->Rasterize( );
AddCompletedTask( task );
}
}
RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
/**
- * Do the rasterization with the given rasterizer.
- *@param[in] rasterizer The rasterizer that rasterize the SVG to a buffer image
+ * Destructor.
+ */
+ ~RasterizingTask();
+
+ /**
+ * Do the rasterization with the mRasterizer.
*/
- void Rasterize( NSVGrasterizer* rasterizer );
+ void Rasterize( );
/**
* Get the svg visual
float mDpi;
unsigned int mWidth;
unsigned int mHeight;
+ NSVGrasterizer* mRasterizer;
};
/**
Dali::Mutex mMutex;
EventThreadCallback* mTrigger;
- NSVGrasterizer* mRasterizer;
bool mIsThreadWaiting;
};
// INTERNAL INCLUDES
#include <dali-toolkit/third-party/nanosvg/nanosvg.h>
+#include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
#include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
// EXTERNAL INCLUDES
#include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
namespace Dali
{
const char * const IMAGE_ATLASING( "atlasing" );
+const char * const SYNCHRONOUS_LOADING( "synchronousLoading" );
+
const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
+
}
SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
{
DoSetProperty( Toolkit::ImageVisual::Property::ATLASING, keyValue.second );
}
+ else if( keyValue.first == SYNCHRONOUS_LOADING )
+ {
+ DoSetProperty( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second );
+ }
}
}
value.Get( mAttemptAtlasing );
break;
}
+ case Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING:
+ {
+ bool sync = false;
+ if( value.Get( sync ) )
+ {
+ if( sync )
+ {
+ mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+ }
+ else
+ {
+ mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+ }
+ }
+ else
+ {
+ DALI_LOG_ERROR("ImageVisual: synchronousLoading property has incorrect type\n");
+ }
+ break;
+ }
}
}
float meanDpi = ( dpi.height + dpi.width ) * 0.5f;
RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, mImageUrl, meanDpi, width, height );
- mFactoryCache.GetSVGRasterizationThread()->AddTask( newTask );
+ if ( IsSynchronousLoadingRequired() )
+ {
+ newTask->Rasterize();
+ ApplyRasterizedImage( newTask->GetParsedImage(), newTask->GetPixelData() );
+ }
+ else
+ {
+ mFactoryCache.GetSVGRasterizationThread()->AddTask( newTask );
+ }
}
}
// which is ok, because they have a different key value range.
map.Insert( Toolkit::Visual::Property::MIX_COLOR, mImpl->mMixColor ); // vec4
map.Insert( Toolkit::Visual::Property::OPACITY, mImpl->mMixColor.a );
+ map.Insert( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired() );
auto fittingModeString = Scripting::GetLinearEnumerationName< FittingMode >(
mImpl->mFittingMode, VISUAL_FITTING_MODE_TABLE, VISUAL_FITTING_MODE_TABLE_COUNT );
return ( mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::READY );
}
+bool Visual::Base::IsSynchronousLoadingRequired() const
+{
+ return ( mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING );
+}
+
Toolkit::Visual::ResourceStatus Visual::Base::GetResourceStatus() const
{
return mImpl->mResourceStatus;
*/
virtual Base& GetVisualObject();
+ /**
+ * @brief Query whether resources requires to be loaded synchronously.
+ * @return Returns true if synchronous resource loading is required, false otherwise.
+ */
+ bool IsSynchronousLoadingRequired() const;
+
protected:
/**