From: Eunki Hong Date: Wed, 8 Nov 2023 04:56:41 +0000 (+0000) Subject: Merge "(Vector) Support EncodedImageBuffer can use for vector image" into devel/master X-Git-Tag: dali_2.2.52~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=10e5c8ad6f9df9e96803980da6201d3b2b81e514;hp=-c;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Merge "(Vector) Support EncodedImageBuffer can use for vector image" into devel/master --- 10e5c8ad6f9df9e96803980da6201d3b2b81e514 diff --combined automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 7448eba,0a82fb4..5ca6052 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@@ -879,6 -879,86 +879,86 @@@ int UtcDaliImageViewSyncLoadingEncodedB END_TEST; } + int UtcDaliImageViewEncodedBufferWithSvg(void) + { + ToolkitTestApplication application; + TestGlAbstraction& gl = application.GetGlAbstraction(); + const std::vector& 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& 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& 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& 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; @@@ -2789,6 -2869,34 +2869,34 @@@ int UtcDaliImageViewLoadRemoteSVG(void 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; @@@ -3773,34 -3881,6 +3881,34 @@@ void OnResourceReadySignal10(Control co } } +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) @@@ -4645,82 -4725,6 +4753,82 @@@ int UtcDaliImageViewSetImageOnResourceR 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"); diff --combined dali-toolkit/internal/image-loader/loading-task.cpp index dff50da,2c08799..e26a927 --- a/dali-toolkit/internal/image-loader/loading-task.cpp +++ b/dali-toolkit/internal/image-loader/loading-task.cpp @@@ -163,7 -163,7 +163,7 @@@ void LoadingTask::Process( { 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 @@@ -194,7 -194,7 +194,7 @@@ 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 @@@ -215,6 -215,9 +215,9 @@@ void LoadingTask::Load( 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()) { diff --combined dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index a2518d9,09c4418..699c281 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@@ -113,6 -113,12 +113,12 @@@ AnimatedVectorImageVisual::~AnimatedVec { if(!mCoreShutdown) { + if(mImageUrl.IsBufferResource()) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl()); + } + auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager(); vectorAnimationManager.RemoveObserver(*this); @@@ -204,10 -210,6 +210,10 @@@ void AnimatedVectorImageVisual::DoCreat 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()); @@@ -384,7 -386,20 +390,20 @@@ void AnimatedVectorImageVisual::OnIniti 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); diff --combined dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index 6c44eac,c1e9d56..c0d3802 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@@ -19,6 -19,7 +19,7 @@@ #include // EXTERNAL INCLUDES + #include #include #include #include @@@ -55,6 -56,7 +56,7 @@@ DALI_INIT_TRACE_FILTER(gTraceFilter, DA 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()), @@@ -148,19 -150,41 +150,41 @@@ bool VectorAnimationTask::Load(bool syn { 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 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) { @@@ -171,7 -195,7 +195,7 @@@ { 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 @@@ -198,7 -222,7 +222,7 @@@ { 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 @@@ -215,9 -239,10 +239,10 @@@ void VectorAnimationTask::SetRenderer(R 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) { @@@ -462,11 -487,6 +487,11 @@@ void VectorAnimationTask::GetLayerInfo( mVectorRenderer.GetLayerInfo(map); } +void VectorAnimationTask::GetMarkerInfo(Property::Map& map) const +{ + mVectorRenderer.GetMarkerInfo(map); +} + VectorAnimationTask::ResourceReadySignalType& VectorAnimationTask::ResourceReadySignal() { return mResourceReadySignal; diff --combined dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h index a115377,123d685..367fc8a --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h @@@ -22,6 -22,7 +22,7 @@@ #include #include #include + #include #include #include #include @@@ -162,9 -163,10 +163,10 @@@ public * @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. @@@ -216,12 -218,6 +218,12 @@@ 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. */ @@@ -363,6 -359,7 +365,7 @@@ private }; VisualUrl mImageUrl; + EncodedImageBuffer mEncodedImageBuffer; VectorAnimationRenderer mVectorRenderer; std::vector mAnimationData[2]; VectorAnimationThread& mVectorAnimationThread; diff --combined dali-toolkit/internal/visuals/svg/svg-task.cpp index 1c1cdb3,5f8ed8c..9939dc7 --- a/dali-toolkit/internal/visuals/svg/svg-task.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-task.cpp @@@ -16,7 -16,7 +16,7 @@@ */ // CLASS HEADER - #include "svg-task.h" + #include // EXTERNAL INCLUDES #include @@@ -64,9 -64,10 +64,10 @@@ VectorImageRenderer SvgTask::GetRendere 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) { } @@@ -89,7 -90,7 +90,7 @@@ void SvgLoadingTask::Process( { 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 @@@ -98,25 -99,35 +99,35 @@@ Dali::Vector 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)) @@@ -133,7 -144,7 +144,7 @@@ 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