END_TEST;
}
+ int UtcDaliImageViewEncodedBufferWithSvg(void)
+ {
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ const std::vector<GLuint>& textures = gl.GetBoundTextures();
+ size_t numTextures = textures.size();
+
+ // Get encoded raw-buffer svg image and generate url
+ EncodedImageBuffer buffer = ConvertFileToEncodedImageBuffer(TEST_SVG_FILE_NAME, EncodedImageBuffer::ImageType::VECTOR_IMAGE);
+ ImageUrl url = Toolkit::Image::GenerateUrl(buffer);
+
+ // Async loading, no atlasing for big size image
+ ImageView imageView = ImageView::New(url.GetUrl());
+
+ // By default, Aysnc loading is used
+ application.GetScene().Add(imageView);
+ imageView.SetProperty(Actor::Property::SIZE, Vector2(100, 100));
+ imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Load svg image + rasterize.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+
+ const std::vector<GLuint>& textures2 = gl.GetBoundTextures();
+ DALI_TEST_GREATER(textures2.size(), numTextures, TEST_LOCATION);
+
+ // Remove visual, for line coverage.
+ imageView.Unparent();
+ application.SendNotification();
+ application.Render(16);
+
+ END_TEST;
+ }
+
+ int UtcDaliImageViewEncodedBufferWithAnimatedVectorImage(void)
+ {
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ const std::vector<GLuint>& textures = gl.GetBoundTextures();
+ size_t numTextures = textures.size();
+
+ // Get encoded raw-buffer lottie image and generate url
+ EncodedImageBuffer buffer = ConvertFileToEncodedImageBuffer(TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME, EncodedImageBuffer::ImageType::ANIMATED_VECTOR_IMAGE);
+ ImageUrl url = Toolkit::Image::GenerateUrl(buffer);
+
+ // Async loading, no atlasing for big size image
+ ImageView imageView = ImageView::New(url.GetUrl());
+
+ // By default, Aysnc loading is used
+ application.GetScene().Add(imageView);
+ imageView.SetProperty(Actor::Property::SIZE, Vector2(100, 100));
+ imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Load lottie image is sync. Only wait rasterize.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+
+ const std::vector<GLuint>& textures2 = gl.GetBoundTextures();
+ DALI_TEST_GREATER(textures2.size(), numTextures, TEST_LOCATION);
+
+ // Remove visual, for line coverage.
+ imageView.Unparent();
+ application.SendNotification();
+ application.Render(16);
+
+ END_TEST;
+ }
+
int UtcDaliImageViewAddedTexture(void)
{
ToolkitTestApplication application;
END_TEST;
}
+ int UtcDaliImageViewLoadRemoteLottie(void)
+ {
+ tet_infoline("Test load from a remote server. (Note we don't support real download now. Just for line coverage)");
+
+ ToolkitTestApplication application;
+
+ {
+ Toolkit::ImageView imageView;
+ imageView = Toolkit::ImageView::New();
+ imageView.SetImage("https://lottie.json");
+ imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ imageView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+ imageView.SetProperty(Actor::Property::POSITION, Vector3(150.0f, 150.0f, 0.0f));
+
+ application.GetScene().Add(imageView);
+
+ DALI_TEST_CHECK(imageView);
+
+ application.SendNotification();
+ application.Render();
+
+ // Do not check anything for here.
+ }
+
+ END_TEST;
+ }
+
int UtcDaliImageViewSyncSVGLoading(void)
{
ToolkitTestApplication application;
}
}
+void OnResourceReadySignal11(Control control)
+{
+ gResourceReadySignalCounter++;
+
+ if(!gImageView2)
+ {
+ auto scene = gImageView1.GetParent();
+
+ // Try to load animated image visual here which is already cached, and then ignore forcely.
+
+ Property::Map map1;
+ map1[Toolkit::ImageVisual::Property::URL] = TEST_GIF_FILE_NAME;
+
+ gImageView2 = ImageView::New();
+ gImageView2.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+
+ gImageView3 = ImageView::New();
+ gImageView3.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+
+ scene.Add(gImageView2);
+ gImageView2.Unparent();
+
+ scene.Add(gImageView3);
+ gImageView3.Unparent();
+ gImageView3.Reset(); // Destroy visual
+ }
+}
+
} // namespace
int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
END_TEST;
}
+int UtcDaliImageViewSetImageOnResourceReadySignal11(void)
+{
+ tet_infoline("Test ResourceReady Add AnimatedImageVisual and then Remove immediately.");
+
+ ToolkitTestApplication application;
+
+ gResourceReadySignalCounter = 0;
+
+ // Clear image view for clear test
+
+ if(gImageView1)
+ {
+ gImageView1.Reset();
+ }
+ if(gImageView2)
+ {
+ gImageView2.Reset();
+ }
+ if(gImageView3)
+ {
+ gImageView3.Reset();
+ }
+
+ try
+ {
+ gImageView1 = ImageView::New();
+ gImageView1.SetProperty(Toolkit::ImageView::Property::IMAGE, TEST_GIF_FILE_NAME);
+ gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal11);
+ application.GetScene().Add(gImageView1); // It will call resourceReady signal 1 time.
+
+ tet_printf("ResourceReady called %d times\n", gResourceReadySignalCounter);
+
+ DALI_TEST_EQUALS(gResourceReadySignalCounter, 0, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ // Load gImageView1
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ tet_printf("ResourceReady called %d times\n", gResourceReadySignalCounter);
+
+ DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION);
+
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ // Exception should not happened
+ DALI_TEST_CHECK(false);
+ }
+
+ // Clear cache.
+ application.SendNotification();
+ application.Render();
+
+ gResourceReadySignalCounter = 0;
+
+ // Clear image view for clear test
+
+ if(gImageView1)
+ {
+ gImageView1.Reset();
+ }
+ if(gImageView2)
+ {
+ gImageView2.Reset();
+ }
+ if(gImageView3)
+ {
+ gImageView3.Reset();
+ }
+
+ END_TEST;
+}
+
int UtcDaliImageViewUseSameUrlWithAnimatedImageVisual(void)
{
tet_infoline("Test multiple views with same image in animated image visual");
{
std::ostringstream oss;
oss << "[url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
- DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK");
+ // DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
}
#endif
oss << "premult:" << pixelBuffers[0].IsAlphaPreMultiplied() << " ";
}
oss << "url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
- DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK");
+ // DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
}
#endif
else if(encodedImageBuffer)
{
pixelBuffer = Dali::LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), dimensions, fittingMode, samplingMode, orientationCorrection);
+
+ // We don't need to hold image buffer anymore.
+ encodedImageBuffer.Reset();
}
else if(url.IsValid() && url.IsLocalResource())
{
{
if(!mCoreShutdown)
{
+ if(mImageUrl.IsBufferResource())
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl());
+ }
+
auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
vectorAnimationManager.RemoveObserver(*this);
mVectorAnimationTask->GetLayerInfo(layerInfo);
map.Insert(Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo);
+ Property::Map markerInfo;
+ mVectorAnimationTask->GetMarkerInfo(markerInfo);
+ map.Insert(Toolkit::DevelImageVisual::Property::MARKER_INFO, markerInfo);
+
map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
mVectorAnimationTask->ResourceReadySignal().Connect(this, &AnimatedVectorImageVisual::OnResourceReady);
mVectorAnimationTask->SetAnimationFinishedCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnAnimationFinished));
- mVectorAnimationTask->RequestLoad(mImageUrl, IsSynchronousLoadingRequired());
+ EncodedImageBuffer encodedImageBuffer;
+
+ if(mImageUrl.IsBufferResource())
+ {
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer.
+ // Reference count will be decreased at destructor of the visual.
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.UseExternalResource(mImageUrl.GetUrl());
+
+ encodedImageBuffer = textureManager.GetEncodedImageBuffer(mImageUrl.GetUrl());
+ }
+
+ mVectorAnimationTask->RequestLoad(mImageUrl, encodedImageBuffer, IsSynchronousLoadingRequired());
auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
vectorAnimationManager.AddObserver(*this);
#include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h>
// EXTERNAL INCLUDES
+ #include <dali/devel-api/adaptor-framework/file-loader.h>
#include <dali/integration-api/debug.h>
#include <dali/integration-api/trace.h>
#include <dali/public-api/math/math-utils.h>
VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
: AsyncTask(MakeCallback(this, &VectorAnimationTask::TaskCompleted), AsyncTask::PriorityType::HIGH, AsyncTask::ThreadType::WORKER_THREAD),
mImageUrl(),
+ mEncodedImageBuffer(),
mVectorRenderer(VectorAnimationRenderer::New()),
mAnimationData(),
mVectorAnimationThread(factoryCache.GetVectorAnimationManager().GetVectorAnimationThread()),
{
std::ostringstream oss;
oss << "[url:" << mImageUrl.GetUrl() << "]";
- DALI_TRACE_BEGIN(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+ // DALI_TRACE_BEGIN(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("BEGIN: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
}
#endif
- if(!mVectorRenderer.Load(mImageUrl.GetUrl()))
+ if(mEncodedImageBuffer)
{
- DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mImageUrl.GetUrl().c_str());
- mLoadFailed = true;
+ if(!mVectorRenderer.Load(mEncodedImageBuffer.GetRawBuffer()))
+ {
+ mLoadFailed = true;
+ }
+
+ // We don't need to hold image buffer anymore.
+ mEncodedImageBuffer.Reset();
+ }
+ else if(mImageUrl.IsLocalResource())
+ {
+ if(!mVectorRenderer.Load(mImageUrl.GetUrl()))
+ {
+ mLoadFailed = true;
+ }
+ }
+ else
+ {
+ Dali::Vector<uint8_t> remoteData;
+ if(!Dali::FileLoader::DownloadFileSynchronously(mImageUrl.GetUrl(), remoteData) || // Failed if we fail to download json file,
+ !mVectorRenderer.Load(remoteData)) // or download data is not valid vector animation file.
+ {
+ mLoadFailed = true;
+ }
}
if(mLoadFailed)
{
+ DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mImageUrl.GetUrl().c_str());
mLoadRequest = false;
if(!synchronousLoading && mLoadCompletedCallback)
{
{
std::ostringstream oss;
oss << "[url:" << mImageUrl.GetUrl() << "]";
- DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+ // DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("END: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
}
#endif
{
std::ostringstream oss;
oss << "[url:" << mImageUrl.GetUrl() << "]";
- DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+ // DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("END: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
}
#endif
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetRenderer [%p]\n", this);
}
- void VectorAnimationTask::RequestLoad(const VisualUrl& url, bool synchronousLoading)
+ void VectorAnimationTask::RequestLoad(const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, bool synchronousLoading)
{
- mImageUrl = url;
+ mImageUrl = url;
+ mEncodedImageBuffer = encodedImageBuffer;
if(!synchronousLoading)
{
mVectorRenderer.GetLayerInfo(map);
}
+void VectorAnimationTask::GetMarkerInfo(Property::Map& map) const
+{
+ mVectorRenderer.GetMarkerInfo(map);
+}
+
VectorAnimationTask::ResourceReadySignalType& VectorAnimationTask::ResourceReadySignal()
{
return mResourceReadySignal;
#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
#include <dali/devel-api/threading/conditional-wait.h>
#include <dali/public-api/adaptor-framework/async-task-manager.h>
+ #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/property-array.h>
#include <chrono>
* @brief Requests to load the animation file.
*
* @param[in] url The url of the vector animation file
+ * @param[in] encodedImageBuffer The resource buffer if required.
* @param[in] synchronousLoading True if the url should be loaded synchronously
*/
- void RequestLoad(const VisualUrl& url, bool synchronousLoading);
+ void RequestLoad(const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, bool synchronousLoading);
/**
* @brief Queries whether loading is requested.
void GetLayerInfo(Property::Map& map) const;
/**
+ * @brief Gets the all marker information.
+ * @param[out] map The marker information
+ */
+ void GetMarkerInfo(Property::Map& map) const;
+
+ /**
* @brief Connect to this signal to be notified when the resource is ready.
* @return The signal to connect to.
*/
};
VisualUrl mImageUrl;
+ EncodedImageBuffer mEncodedImageBuffer;
VectorAnimationRenderer mVectorRenderer;
std::vector<AnimationData> mAnimationData[2];
VectorAnimationThread& mVectorAnimationThread;
*/
// CLASS HEADER
- #include "svg-task.h"
+ #include <dali-toolkit/internal/visuals/svg/svg-task.h>
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/file-loader.h>
return mVectorRenderer;
}
- SvgLoadingTask::SvgLoadingTask(VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, CallbackBase* callback)
+ SvgLoadingTask::SvgLoadingTask(VectorImageRenderer vectorRenderer, const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, float dpi, CallbackBase* callback)
: SvgTask(vectorRenderer, callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
mImageUrl(url),
+ mEncodedImageBuffer(encodedImageBuffer),
mDpi(dpi)
{
}
{
std::ostringstream oss;
oss << "[url:" << mImageUrl.GetUrl() << "]";
- DALI_TRACE_BEGIN(gTraceFilter, "DALI_SVG_LOADING_TASK");
+ // DALI_TRACE_BEGIN(gTraceFilter, "DALI_SVG_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("BEGIN: DALI_SVG_LOADING_TASK %s", oss.str().c_str());
}
#endif
Dali::Vector<uint8_t> buffer;
- if(!mImageUrl.IsLocalResource())
+ if(mEncodedImageBuffer)
{
- if(!Dali::FileLoader::DownloadFileSynchronously(mImageUrl.GetUrl(), buffer))
+ // Copy raw buffer.
+ // TODO : Can't we load svg without copy buffer in future?
+ buffer = mEncodedImageBuffer.GetRawBuffer();
+
+ // We don't need to hold image buffer anymore.
+ mEncodedImageBuffer.Reset();
+ }
+ else if(mImageUrl.IsLocalResource())
+ {
+ if(!Dali::FileLoader::ReadFile(mImageUrl.GetUrl(), buffer))
{
- DALI_LOG_ERROR("Failed to download file! [%s]\n", mImageUrl.GetUrl().c_str());
+ DALI_LOG_ERROR("Failed to read file! [%s]\n", mImageUrl.GetUrl().c_str());
loadFailed = true;
}
}
else
{
- if(!Dali::FileLoader::ReadFile(mImageUrl.GetUrl(), buffer))
+ if(!Dali::FileLoader::DownloadFileSynchronously(mImageUrl.GetUrl(), buffer))
{
- DALI_LOG_ERROR("Failed to read file! [%s]\n", mImageUrl.GetUrl().c_str());
+ DALI_LOG_ERROR("Failed to download file! [%s]\n", mImageUrl.GetUrl().c_str());
loadFailed = true;
}
}
if(!loadFailed)
{
+ buffer.Reserve(buffer.Count() + 1u);
buffer.PushBack('\0');
if(!mVectorRenderer.Load(buffer, mDpi))
std::ostringstream oss;
oss << "[success:" << mHasSucceeded << " ";
oss << "url:" << mImageUrl.GetUrl() << "]";
- DALI_TRACE_END(gTraceFilter, "DALI_SVG_LOADING_TASK");
+ // DALI_TRACE_END(gTraceFilter, "DALI_SVG_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
DALI_LOG_RELEASE_INFO("END: DALI_SVG_LOADING_TASK %s", oss.str().c_str());
}
#endif