const char* TEST_IMAGE_4_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-20.png";
const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
+const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
+const char* TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json";
+
class TestObserver : public Dali::Toolkit::TextureUploadObserver
{
public:
std::string url1 = textureManager.AddEncodedImageBuffer(buffer1);
std::string url2 = textureManager.AddEncodedImageBuffer(buffer1);
- std::string url3 = VisualUrl::CreateBufferUrl(""); ///< Impossible Buffer URL. for coverage
+ std::string url3 = VisualUrl::CreateBufferUrl("", ""); ///< Impossible Buffer URL. for coverage
// Check if same EncodedImageBuffer get same url
DALI_TEST_CHECK(url1 == url2);
END_TEST;
}
+int UtcTextureManagerEncodedImageBufferWithImageType(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcTextureManagerEncodedImageBufferWithImageType");
+
+ auto visualFactory = Toolkit::VisualFactory::Get();
+ auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
+
+ // Get encoded raw-buffer image and generate url
+ EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_SVG_FILE_NAME);
+ EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME);
+
+ std::string url1 = textureManager.AddEncodedImageBuffer(buffer1);
+ std::string url2 = textureManager.AddEncodedImageBuffer(buffer1);
+
+ // Check if same EncodedImageBuffer get same url
+ DALI_TEST_CHECK(url1 == url2);
+ // Reduce reference count
+ textureManager.RemoveEncodedImageBuffer(url1);
+ // Check whethere url1 still valid
+ DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
+
+ url2 = textureManager.AddEncodedImageBuffer(buffer2);
+ // Check if difference EncodedImageBuffer get difference url
+ DALI_TEST_CHECK(url1 != url2);
+
+ buffer1.SetImageType(EncodedImageBuffer::ImageType::VECTOR_IMAGE);
+ buffer2.SetImageType(EncodedImageBuffer::ImageType::ANIMATED_VECTOR_IMAGE);
+
+ std::string url1AfterType = textureManager.AddEncodedImageBuffer(buffer1);
+ std::string url2AfterType = textureManager.AddEncodedImageBuffer(buffer2);
+
+ // Check if EncodedImageBuffer with imagetype get difference url.
+ DALI_TEST_CHECK(url1 != url1AfterType);
+ DALI_TEST_CHECK(url2 != url2AfterType);
+ DALI_TEST_CHECK(url1AfterType != url2AfterType);
+
+ int bufferId = std::atoi(VisualUrl::GetLocationWithoutExtension(url1AfterType).c_str());
+ auto urlFromBuffer = textureManager.GetVisualUrl(bufferId);
+
+ // Check url from buffer id is equal with what we know.
+ DALI_TEST_CHECK(url1AfterType == urlFromBuffer.GetUrl());
+
+ // Reduce reference count
+ textureManager.RemoveEncodedImageBuffer(url1AfterType);
+ // Check whethere url1 still valid
+ DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1AfterType));
+
+ // Reduce reference count
+ textureManager.RemoveEncodedImageBuffer(url1AfterType);
+ // Check whethere url1 is invalid
+ DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1AfterType));
+
+ // Reduce reference count
+ textureManager.RemoveEncodedImageBuffer(url2);
+ // Check whethere url2 is still valid
+ DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url2));
+
+ // Reduce reference count
+ textureManager.RemoveEncodedImageBuffer(url2);
+ // Check whethere url2 is invalid
+ DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url2));
+
+ END_TEST;
+}
+
int UtcTextureManagerExternalTexture(void)
{
ToolkitTestApplication application;
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
END_TEST;
}
+int UtcDaliVisualUrlGetLocationWithoutExtensionP(void)
+{
+ tet_infoline("UtcDaliVisualUrl GetLocationWithoutExtension Positive");
+
+ DALI_TEST_EQUAL("a", VisualUrl("http://a.png").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("1", VisualUrl("dali://1.jpg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("4", VisualUrl("enbuf://4.svg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("", VisualUrl("ftp://.png").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("http://a.jpg", VisualUrl("http://http://a.jpg.jpg").GetLocationWithoutExtension());
+
+ END_TEST;
+}
+
int UtcDaliVisualUrlGetLocationN(void)
{
tet_infoline("UtcDaliVisualUrl GetLocation Negative");
END_TEST;
}
+int UtcDaliVisualUrlGetLocationWithoutExtensionN(void)
+{
+ tet_infoline("UtcDaliVisualUrl GetLocationWithoutExtension Negative");
+
+ DALI_TEST_EQUAL("", VisualUrl("").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("a", VisualUrl("a").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("dali:/1.jpg", VisualUrl("dali:/1.jpg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("dali//1.jpg", VisualUrl("dali//1.jpg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("enbuf:/2.png", VisualUrl("enbuf:/2.png").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("a.jpg", VisualUrl("http:/http://a.jpg.jpngif").GetLocationWithoutExtension());
+
+ END_TEST;
+}
+
int UtcDaliVisualUrlCreateTextureUrl(void)
{
tet_infoline("UtcDaliVisualUrl CreateTextureUrl");
{
tet_infoline("UtcDaliVisualUrl CreateBufferUrl");
- DALI_TEST_EQUAL("enbuf://a", VisualUrl::CreateBufferUrl("a"));
- DALI_TEST_EQUAL("enbuf://1234", VisualUrl::CreateBufferUrl("1234"));
- DALI_TEST_EQUAL("enbuf://", VisualUrl::CreateBufferUrl(""));
+ DALI_TEST_EQUAL("enbuf://a", VisualUrl::CreateBufferUrl("a", ""));
+ DALI_TEST_EQUAL("enbuf://1234", VisualUrl::CreateBufferUrl("1234", ""));
+ DALI_TEST_EQUAL("enbuf://", VisualUrl::CreateBufferUrl("", ""));
+
+ END_TEST;
+}
+
+int UtcDaliVisualUrlCreateBufferUrlWithExtension(void)
+{
+ tet_infoline("UtcDaliVisualUrl CreateBufferUrl with extension");
+
+ DALI_TEST_EQUAL("enbuf://a.jpg", VisualUrl::CreateBufferUrl("a", ".jpg"));
+ DALI_TEST_EQUAL("enbuf://1234567", VisualUrl::CreateBufferUrl("1234", "567"));
+ DALI_TEST_EQUAL("enbuf://b", VisualUrl::CreateBufferUrl("", "b"));
END_TEST;
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
namespace Dali
{
-EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url)
+EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url, EncodedImageBuffer::ImageType imageType)
{
EncodedImageBuffer buffer;
- FILE *fp;
+ FILE* fp;
fp = fopen(url, "rb");
if(fp != NULL)
{
fseek(fp, 0, SEEK_END);
- size_t size = ftell(fp);
+ size_t size = ftell(fp);
Dali::Vector<uint8_t> data;
data.Resize(size);
fseek(fp, 0, SEEK_SET);
size_t realSize = fread(data.Begin(), sizeof(uint8_t), size, fp);
fclose(fp);
data.Resize(realSize);
- buffer = EncodedImageBuffer::New(data);
+ buffer = EncodedImageBuffer::New(data, imageType);
}
return buffer;
}
#define TEST_ENCODED_IMAGE_BUFFER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
namespace Dali
{
-
// util function to convert local file to EncodedImageBuffer
-EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url);
+EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url, EncodedImageBuffer::ImageType imageType = EncodedImageBuffer::ImageType::DEFAULT);
} // namespace Dali
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;
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())
{
// EXTERNAL HEADERS
#include <dali/devel-api/common/hash.h>
#include <dali/integration-api/debug.h>
+#include <string_view>
+#include <unordered_map>
// INTERNAL HEADERS
{
namespace Internal
{
+namespace
+{
+const std::string_view& GetEncodedImageBufferExtensions(Dali::EncodedImageBuffer::ImageType imageType)
+{
+ static const std::unordered_map<Dali::EncodedImageBuffer::ImageType, const std::string_view> gEncodedImageBufferExtensionMap =
+ {
+ {Dali::EncodedImageBuffer::ImageType::REGULAR_IMAGE, ""},
+ {Dali::EncodedImageBuffer::ImageType::VECTOR_IMAGE, ".svg"},
+ {Dali::EncodedImageBuffer::ImageType::ANIMATED_VECTOR_IMAGE, ".json"},
+ };
+
+ const auto iter = gEncodedImageBufferExtensionMap.find(imageType);
+
+ DALI_ASSERT_DEBUG(iter != gEncodedImageBufferExtensionMap.end());
+
+ return iter->second;
+}
+} // namespace
#ifdef DEBUG_ENABLED
extern Debug::Filter* gTextureManagerLogFilter; ///< Define at texture-manager-impl.cpp
case TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_BUFFER:
{
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::GetVisualUrl. Using cached buffer index=%d, bufferId=%d\n", cacheIndex.GetIndex(), textureId);
- visualUrl = VisualUrl::CreateBufferUrl(std::to_string(textureId));
+
+ EncodedImageBufferInfo& cachedEncodedImageBufferInfo(mEncodedImageBuffers[cacheIndex.GetIndex()]);
+ const auto& encodedImageBuffer = cachedEncodedImageBufferInfo.encodedImageBuffer;
+ visualUrl = VisualUrl::CreateBufferUrl(std::to_string(textureId), GetEncodedImageBufferExtensions(encodedImageBuffer.GetImageType()));
break;
}
default:
EncodedImageBuffer encodedImageBuffer; // empty handle
if(url.IsValid() && VisualUrl::BUFFER == url.GetProtocolType())
{
- std::string location = url.GetLocation();
+ std::string location = url.GetLocationWithoutExtension();
if(location.size() > 0u)
{
TextureId bufferId = std::stoi(location);
// If same buffer added, increase reference count and return.
bufferInfo.referenceCount++;
- return VisualUrl::CreateBufferUrl(std::to_string(bufferInfo.bufferId));
+ return VisualUrl::CreateBufferUrl(std::to_string(bufferInfo.bufferId), GetEncodedImageBufferExtensions(encodedImageBuffer.GetImageType()));
}
TextureId bufferId = GenerateTextureId(TextureCacheIndex(TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_BUFFER, mEncodedImageBuffers.size()));
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::AddExternalEncodedImageBuffer() : New buffer regested. bufferId:%d\n", info.bufferId);
- return VisualUrl::CreateBufferUrl(std::to_string(info.bufferId));
+ return VisualUrl::CreateBufferUrl(std::to_string(info.bufferId), GetEncodedImageBufferExtensions(encodedImageBuffer.GetImageType()));
}
TextureSet TextureCacheManager::RemoveExternalTexture(const VisualUrl& url)
if(VisualUrl::BUFFER == url.GetProtocolType())
{
// get the location from the Url
- std::string location = url.GetLocation();
+ std::string location = url.GetLocationWithoutExtension();
if(location.size() > 0u)
{
TextureId bufferId = std::stoi(location);
}
else if(VisualUrl::BUFFER == url.GetProtocolType())
{
- std::string location = url.GetLocation();
+ std::string location = url.GetLocationWithoutExtension();
if(location.size() > 0u)
{
TextureId id = std::stoi(location);
{
if(!mCoreShutdown)
{
+ if(mImageUrl.IsBufferResource())
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl());
+ }
+
auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
vectorAnimationManager.RemoveObserver(*this);
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()),
}
#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)
{
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)
{
#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.
};
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)
{
}
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))
#include <dali/public-api/common/intrusive-ptr.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/images/pixel-data.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
#include <memory>
// INTERNAL INCLUDES
* Constructor
* @param[in] vectorRenderer The vector rasterizer.
* @param[in] url The URL to svg resource to use.
+ * @param[in] encodedImageBuffer The resource buffer if required.
* @param[in] dpi The DPI of the screen.
* @param[in] callback The callback that is called when the operation is completed.
*/
- SvgLoadingTask(VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, CallbackBase* callback);
+ SvgLoadingTask(VectorImageRenderer vectorRenderer, const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, float dpi, CallbackBase* callback);
/**
* Destructor.
SvgLoadingTask& operator=(const SvgLoadingTask& task) = delete;
private:
- VisualUrl mImageUrl;
- float mDpi;
+ VisualUrl mImageUrl;
+ EncodedImageBuffer mEncodedImageBuffer;
+ float mDpi;
};
class SvgRasterizingTask : public SvgTask
*/
// CLASS HEADER
-#include "svg-visual.h"
+#include <dali-toolkit/internal/visuals/svg/svg-visual.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
{
Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
}
+
+ if(mImageUrl.IsBufferResource())
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl());
+ }
}
}
Vector2 dpi = Stage::GetCurrent().GetDpi();
float meanDpi = (dpi.height + dpi.width) * 0.5f;
- mLoadingTask = new SvgLoadingTask(mVectorRenderer, mImageUrl, meanDpi, MakeCallback(this, &SvgVisual::ApplyRasterizedImage));
+ 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());
+ }
+
+ mLoadingTask = new SvgLoadingTask(mVectorRenderer, mImageUrl, encodedImageBuffer, meanDpi, MakeCallback(this, &SvgVisual::ApplyRasterizedImage));
- if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource())
+ if(IsSynchronousLoadingRequired() && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()))
{
mLoadingTask->Process();
if(!mLoadingTask->HasSucceeded())
if(!url.empty())
{
mLocation = ResolveLocation(url);
- if(VisualUrl::TEXTURE != mLocation && VisualUrl::BUFFER != mLocation)
+ if(VisualUrl::TEXTURE != mLocation)
{
- // TEXTURE and BUFFER location url doesn't need type resolving, REGULAR_IMAGE is fine
+ // TEXTURE location url doesn't need type resolving, REGULAR_IMAGE is fine
mType = ResolveType(url);
}
}
return GetLocation(mUrl);
}
+std::string VisualUrl::GetLocationWithoutExtension() const
+{
+ return GetLocationWithoutExtension(mUrl);
+}
+
std::string VisualUrl::CreateTextureUrl(const std::string& location)
{
return "dali://" + location;
}
-std::string VisualUrl::CreateBufferUrl(const std::string& location)
+std::string VisualUrl::CreateBufferUrl(const std::string& location, const std::string_view& extension)
{
- return "enbuf://" + location;
+ return "enbuf://" + location + std::string(extension);
}
VisualUrl::ProtocolType VisualUrl::GetProtocolType(const std::string& url)
return url;
}
+std::string VisualUrl::GetLocationWithoutExtension(const std::string& url)
+{
+ const auto location = url.find("://");
+ if(std::string::npos != location)
+ {
+ const auto extension = url.find_last_of("."); // Find last position of '.' keyword.
+ const auto locationLength = extension != std::string::npos ? extension - (location + 3u) : std::string::npos;
+ return url.substr(location + 3u, locationLength); // 3 characters forwards from the start of ://, and end of last '.' keyword.
+ }
+ return url;
+}
+
} // namespace Internal
} // namespace Toolkit
// EXTERNAL INCLUDES
#include <cstdint>
#include <string>
+#include <string_view>
namespace Dali
{
std::string GetLocation() const;
/**
+ * @return the location part of the url without extension
+ */
+ std::string GetLocationWithoutExtension() const;
+
+ /**
* Helper to create a URL of type TEXTURE
* @param location the location of the texture
* @return the Url
/**
* Helper to create a URL of type BUFFER
- * @param location the location of the texture
+ * @param[in] location the location of the texture
+ * @param[in] extension the extension of url
* @return the Url
*/
- static std::string CreateBufferUrl(const std::string& location);
+ static std::string CreateBufferUrl(const std::string& location, const std::string_view& extension);
/**
* Helper to get a ProtocolType from url
*/
static std::string GetLocation(const std::string& url);
+ /**
+ * Helper to get a location from url without extension
+ * @param[in] url the location of the texture
+ * @return the location without extension
+ */
+ static std::string GetLocationWithoutExtension(const std::string& url);
+
private:
std::string mUrl;
Type mType;