From e8a53a0a591085c6b7470feac4f9cea85cc8ae6e Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 17 May 2022 19:41:10 +0900 Subject: [PATCH] Trigger svg loading early Change-Id: Ie715e242d32ca68060c8503809222960f545ae60 --- .../toolkit-vector-image-renderer.cpp | 4 +- .../src/dali-toolkit/utc-Dali-ImageView.cpp | 120 +++++++++++++++---- .../internal/visuals/svg/svg-rasterize-thread.cpp | 116 ++++++++++++------- .../internal/visuals/svg/svg-rasterize-thread.h | 127 ++++++++++++++------ dali-toolkit/internal/visuals/svg/svg-visual.cpp | 128 ++++++++++++--------- dali-toolkit/internal/visuals/svg/svg-visual.h | 4 +- 6 files changed, 342 insertions(+), 157 deletions(-) diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp index d809e66..3093fcb 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp @@ -58,12 +58,13 @@ public: { mRasterizeSuccess = false; } + mLoadSuccess = true; return true; } bool IsLoaded() const { - return mLoadCount > 0 ? true : false; + return mLoadSuccess; } Dali::Devel::PixelBuffer Rasterize(uint32_t width, uint32_t height) @@ -86,6 +87,7 @@ public: uint32_t mWidth{0}; uint32_t mHeight{0}; uint32_t mLoadCount{0}; + bool mLoadSuccess{false}; bool mRasterizeSuccess{true}; }; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index edaeec1..cb46bd4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -2686,7 +2686,8 @@ int UtcDaliImageViewLoadRemoteSVG(void) application.SendNotification(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // Wait for loading & rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); application.SendNotification(); application.Render(); @@ -2711,7 +2712,8 @@ int UtcDaliImageViewLoadRemoteSVG(void) application.SendNotification(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // Wait for loading & rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); application.SendNotification(); application.Render(); @@ -2770,7 +2772,7 @@ int UtcDaliImageViewAsyncSVGLoading(void) application.SendNotification(); - // Wait for rasterization + // Wait for loading DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2810,7 +2812,7 @@ int UtcDaliImageViewSVGLoadingSyncSetInvalidValue(void) application.SendNotification(); - // Wait for rasterization + // Wait for loading DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2833,14 +2835,14 @@ int UtcDaliImageViewSVGLoadingSyncSetInvalidValue(void) int UtcDaliImageViewSvgLoadingFailure(void) { - ToolkitTestApplication application; - - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - // Local svg file - invalid file path { + ToolkitTestApplication application; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + gResourceReadySignalFired = false; ImageView imageView = ImageView::New(TEST_RESOURCE_DIR "/foo.svg"); @@ -2853,7 +2855,7 @@ int UtcDaliImageViewSvgLoadingFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread + // loading started, this waits for the loader thread - load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2870,6 +2872,12 @@ int UtcDaliImageViewSvgLoadingFailure(void) // Local svg file - invalid file path without size set { + ToolkitTestApplication application; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + gResourceReadySignalFired = false; textureTrace.Reset(); @@ -2882,7 +2890,7 @@ int UtcDaliImageViewSvgLoadingFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread + // loading started, this waits for the loader thread - load & rasterize DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2899,6 +2907,12 @@ int UtcDaliImageViewSvgLoadingFailure(void) // Local svg file - invalid file { + ToolkitTestApplication application; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + gResourceReadySignalFired = false; textureTrace.Reset(); @@ -2912,7 +2926,7 @@ int UtcDaliImageViewSvgLoadingFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread + // loading started, this waits for the loader thread - load & rasterize DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2929,6 +2943,12 @@ int UtcDaliImageViewSvgLoadingFailure(void) // Remote svg file { + ToolkitTestApplication application; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + gResourceReadySignalFired = false; textureTrace.Reset(); @@ -2942,7 +2962,7 @@ int UtcDaliImageViewSvgLoadingFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread + // loading started, this waits for the loader thread - load & rasterize DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -2959,6 +2979,12 @@ int UtcDaliImageViewSvgLoadingFailure(void) // Remote svg file without size set { + ToolkitTestApplication application; + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + gResourceReadySignalFired = false; textureTrace.Reset(); @@ -2971,7 +2997,7 @@ int UtcDaliImageViewSvgLoadingFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread + // loading started, this waits for the loader thread - load & rasterize DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -3009,8 +3035,8 @@ int UtcDaliImageViewSvgRasterizationFailure(void) application.SendNotification(); - // loading started, this waits for the loader thread - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // Wait for loading & rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); application.SendNotification(); application.Render(16); @@ -3039,8 +3065,8 @@ int UtcDaliImageViewSvgChageSize(void) application.SendNotification(); - // loading started, this waits for the loader thread - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // Wait for loading & rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); application.SendNotification(); application.Render(16); @@ -3052,7 +3078,7 @@ int UtcDaliImageViewSvgChageSize(void) application.SendNotification(); - // loading started, this waits for the loader thread + // Wait for rasterization DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); @@ -3064,6 +3090,58 @@ int UtcDaliImageViewSvgChageSize(void) END_TEST; } +int UtcDaliImageViewSvgAtlasing(void) +{ + ToolkitTestApplication application; + + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); + + Property::Map propertyMap; + propertyMap["url"] = TEST_SVG_FILE_NAME; + propertyMap["atlasing"] = true; + + ImageView imageView = ImageView::New(); + imageView.SetProperty(ImageView::Property::IMAGE, propertyMap); + imageView.SetProperty(Actor::Property::SIZE, Vector2(100.f, 100.f)); + application.GetScene().Add(imageView); + + application.SendNotification(); + + // Wait for loading & rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(16); + + // use atlas + TraceCallStack::NamedParams params1; + params1["width"] << 100; + params1["height"] << 100; + DALI_TEST_EQUALS(callStack.FindMethodAndParams("TexSubImage2D", params1), true, TEST_LOCATION); + + imageView.SetProperty(Actor::Property::SIZE, Vector2(600.f, 600.f)); + + application.SendNotification(); + + // Wait for rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + callStack.Reset(); + + application.SendNotification(); + application.Render(16); + + // not use atlas + TraceCallStack::NamedParams params2; + params2["width"] << 600; + params2["height"] << 600; + DALI_TEST_EQUALS(callStack.FindMethodAndParams("TexImage2D", params2), true, TEST_LOCATION); + + END_TEST; +} + int UtcDaliImageViewTVGLoading(void) { ToolkitTestApplication application; @@ -3645,7 +3723,7 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void) // Test normal case TestResourceReadyUrl(1, 0, 1, gImage_600_RGB, "", TEST_LOCATION); - TestResourceReadyUrl(1, 0, 1, TEST_SVG_FILE_NAME, "", TEST_LOCATION); // 1 rasterize + TestResourceReadyUrl(2, 0, 1, TEST_SVG_FILE_NAME, "", TEST_LOCATION); // load & rasterize TestResourceReadyUrl(1, 0, 1, TEST_BROKEN_IMAGE_L, "", TEST_LOCATION); TestResourceReadyUrl(2, 0, 1, TEST_GIF_FILE_NAME, "", TEST_LOCATION); // 2 image loading - batch size diff --git a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp index 24f9981..c6e0a2c 100644 --- a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp @@ -33,27 +33,45 @@ namespace Toolkit { namespace Internal { -RasterizingTask::RasterizingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height) +SvgTask::SvgTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer) : mSvgVisual(svgVisual), mVectorRenderer(vectorRenderer), + mHasSucceeded(false) +{ +} + +SvgVisual* SvgTask::GetSvgVisual() const +{ + return mSvgVisual.Get(); +} + +PixelData SvgTask::GetPixelData() const +{ + return PixelData(); +} + +bool SvgTask::HasSucceeded() const +{ + return mHasSucceeded; +} + +SvgLoadingTask::SvgLoadingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi) +: SvgTask(svgVisual, vectorRenderer), mUrl(url), - mDpi(dpi), - mWidth(width), - mHeight(height), - mLoadSuccess(false) + mDpi(dpi) { } -RasterizingTask::~RasterizingTask() +SvgLoadingTask::~SvgLoadingTask() { } -void RasterizingTask::Load() +void SvgLoadingTask::Process() { if(mVectorRenderer.IsLoaded()) { // Already loaded - mLoadSuccess = true; + mHasSucceeded = true; return; } @@ -84,32 +102,40 @@ void RasterizingTask::Load() return; } - mLoadSuccess = true; + mHasSucceeded = true; } -void RasterizingTask::Rasterize() +SvgRasterizingTask::SvgRasterizingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, unsigned int width, unsigned int height) +: SvgTask(svgVisual, vectorRenderer), + mWidth(width), + mHeight(height) { - Devel::PixelBuffer pixelBuffer = mVectorRenderer.Rasterize(mWidth, mHeight); - if(!pixelBuffer) - { - DALI_LOG_ERROR("Rasterize is failed! [%s]\n", mUrl.GetUrl().c_str()); - return; - } - - mPixelData = Devel::PixelBuffer::Convert(pixelBuffer); } -bool RasterizingTask::IsLoaded() const +SvgRasterizingTask::~SvgRasterizingTask() { - return mLoadSuccess; } -SvgVisual* RasterizingTask::GetSvgVisual() const +void SvgRasterizingTask::Process() { - return mSvgVisual.Get(); + if(!mVectorRenderer.IsLoaded()) + { + DALI_LOG_ERROR("File is not loaded!\n"); + return; + } + + Devel::PixelBuffer pixelBuffer = mVectorRenderer.Rasterize(mWidth, mHeight); + if(!pixelBuffer) + { + DALI_LOG_ERROR("Rasterize is failed!\n"); + return; + } + + mPixelData = Devel::PixelBuffer::Convert(pixelBuffer); + mHasSucceeded = true; } -PixelData RasterizingTask::GetPixelData() const +PixelData SvgRasterizingTask::GetPixelData() const { return mPixelData; } @@ -135,7 +161,7 @@ void SvgRasterizeThread::TerminateThread(SvgRasterizeThread*& thread) if(thread) { // add an empty task would stop the thread from conditional wait. - thread->AddTask(RasterizingTaskPtr()); + thread->AddTask(SvgTaskPtr()); // stop the thread thread->Join(); // delete the thread @@ -144,7 +170,7 @@ void SvgRasterizeThread::TerminateThread(SvgRasterizeThread*& thread) } } -void SvgRasterizeThread::AddTask(RasterizingTaskPtr task) +void SvgRasterizeThread::AddTask(SvgTaskPtr task) { bool wasEmpty = false; @@ -156,12 +182,18 @@ void SvgRasterizeThread::AddTask(RasterizingTaskPtr task) { // Remove the tasks with the same renderer. // Older task which waiting to rasterize and apply the svg to the same renderer is expired. - for(std::vector::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it) + // Rasterizing task only, loading task is not duplicated. + for(std::vector::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it) { if((*it) && (*it)->GetSvgVisual() == task->GetSvgVisual()) { - mRasterizeTasks.erase(it); - break; + SvgRasterizingTask* oldTask = dynamic_cast(it->Get()); + SvgRasterizingTask* newTask = dynamic_cast(task.Get()); + if(oldTask && newTask) + { + mRasterizeTasks.erase(it); + break; + } } } } @@ -181,18 +213,18 @@ void SvgRasterizeThread::AddTask(RasterizingTaskPtr task) } } -RasterizingTaskPtr SvgRasterizeThread::NextCompletedTask() +SvgTaskPtr SvgRasterizeThread::NextCompletedTask() { // Lock while popping task out from the queue Mutex::ScopedLock lock(mMutex); if(mCompletedTasks.empty()) { - return RasterizingTaskPtr(); + return SvgTaskPtr(); } - std::vector::iterator next = mCompletedTasks.begin(); - RasterizingTaskPtr nextTask = *next; + std::vector::iterator next = mCompletedTasks.begin(); + SvgTaskPtr nextTask = *next; mCompletedTasks.erase(next); return nextTask; @@ -204,12 +236,11 @@ void SvgRasterizeThread::RemoveTask(SvgVisual* visual) ConditionalWait::ScopedLock lock(mConditionalWait); if(!mRasterizeTasks.empty()) { - for(std::vector::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it) + for(std::vector::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it) { if((*it) && (*it)->GetSvgVisual() == visual) { mRasterizeTasks.erase(it); - break; } } } @@ -217,7 +248,7 @@ void SvgRasterizeThread::RemoveTask(SvgVisual* visual) UnregisterProcessor(); } -RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess() +SvgTaskPtr SvgRasterizeThread::NextTaskToProcess() { // Lock while popping task out from the queue ConditionalWait::ScopedLock lock(mConditionalWait); @@ -231,14 +262,14 @@ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess() mIsThreadWaiting = false; // pop out the next task from the queue - std::vector::iterator next = mRasterizeTasks.begin(); - RasterizingTaskPtr nextTask = *next; + std::vector::iterator next = mRasterizeTasks.begin(); + SvgTaskPtr nextTask = *next; mRasterizeTasks.erase(next); return nextTask; } -void SvgRasterizeThread::AddCompletedTask(RasterizingTaskPtr task) +void SvgRasterizeThread::AddCompletedTask(SvgTaskPtr task) { // Lock while adding task to the queue Mutex::ScopedLock lock(mMutex); @@ -253,19 +284,18 @@ void SvgRasterizeThread::Run() SetThreadName("SVGThread"); mLogFactory.InstallLogFunction(); - while(RasterizingTaskPtr task = NextTaskToProcess()) + while(SvgTaskPtr task = NextTaskToProcess()) { - task->Load(); - task->Rasterize(); + task->Process(); AddCompletedTask(task); } } void SvgRasterizeThread::ApplyRasterizedSVGToSampler() { - while(RasterizingTaskPtr task = NextCompletedTask()) + while(SvgTaskPtr task = NextCompletedTask()) { - task->GetSvgVisual()->ApplyRasterizedImage(task->GetPixelData(), task->IsLoaded()); + task->GetSvgVisual()->ApplyRasterizedImage(task->GetPixelData(), task->HasSucceeded()); } UnregisterProcessor(); diff --git a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h index c0cf726..13d284b 100644 --- a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h +++ b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h @@ -42,8 +42,8 @@ namespace Internal { class SvgVisual; typedef IntrusivePtr SvgVisualPtr; -class RasterizingTask; -typedef IntrusivePtr RasterizingTaskPtr; +class SvgTask; +typedef IntrusivePtr SvgTaskPtr; /** * The svg rasterizing tasks to be processed in the worker thread. @@ -54,34 +54,31 @@ typedef IntrusivePtr RasterizingTaskPtr; * 3. If this task gets its turn to do the rasterization, it triggers main thread to apply the rasterized image to material then been deleted in main thread call back * Or if this task is been removed ( new image/size set to the visual or actor off stage) before its turn to be processed, it then been deleted in the worker thread. */ -class RasterizingTask : public RefObject +class SvgTask : public RefObject { public: /** * Constructor * @param[in] svgVisual The visual which the rasterized image to be applied. * @param[in] vectorRenderer The vector rasterizer. - * @param[in] url The URL to svg resource to use. - * @param[in] dpi The DPI of the screen. - * @param[in] width The rasterization width. - * @param[in] height The rasterization height. */ - RasterizingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height); + SvgTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer); /** * Destructor. */ - ~RasterizingTask() override; + virtual ~SvgTask() = default; /** - * Load svg file + * Process the task */ - void Load(); + virtual void Process() = 0; /** - * Do the rasterization with the mRasterizer. + * Whether the task has succeeded. + * @return True if the task has succeeded. */ - void Rasterize(); + bool HasSucceeded() const; /** * Get the svg visual @@ -92,30 +89,94 @@ public: * Get the rasterization result. * @return The pixel data with the rasterized pixels. */ - PixelData GetPixelData() const; + virtual PixelData GetPixelData() const; + +private: + // Undefined + SvgTask(const SvgTask& task) = delete; + + // Undefined + SvgTask& operator=(const SvgTask& task) = delete; + +protected: + SvgVisualPtr mSvgVisual; + VectorImageRenderer mVectorRenderer; + bool mHasSucceeded; +}; + +class SvgLoadingTask : public SvgTask +{ +public: + /** + * Constructor + * @param[in] svgVisual The visual which the rasterized image to be applied. + * @param[in] vectorRenderer The vector rasterizer. + * @param[in] url The URL to svg resource to use. + * @param[in] dpi The DPI of the screen. + */ + SvgLoadingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi); /** - * Whether the resource is loaded. - * @return True if the resource is loaded. + * Destructor. */ - bool IsLoaded() const; + ~SvgLoadingTask() override; + + /** + * Process the task + */ + void Process() override; private: // Undefined - RasterizingTask(const RasterizingTask& task); + SvgLoadingTask(const SvgLoadingTask& task) = delete; // Undefined - RasterizingTask& operator=(const RasterizingTask& task); + SvgLoadingTask& operator=(const SvgLoadingTask& task) = delete; private: - SvgVisualPtr mSvgVisual; - VectorImageRenderer mVectorRenderer; - VisualUrl mUrl; - PixelData mPixelData; - float mDpi; - uint32_t mWidth; - uint32_t mHeight; - bool mLoadSuccess; + VisualUrl mUrl; + float mDpi; +}; + +class SvgRasterizingTask : public SvgTask +{ +public: + /** + * Constructor + * @param[in] svgVisual The visual which the rasterized image to be applied. + * @param[in] vectorRenderer The vector rasterizer. + * @param[in] width The rasterization width. + * @param[in] height The rasterization height. + */ + SvgRasterizingTask(SvgVisual* svgVisual, VectorImageRenderer vectorRenderer, unsigned int width, unsigned int height); + + /** + * Destructor. + */ + ~SvgRasterizingTask() override; + + /** + * Process the task accodring to the type + */ + void Process() override; + + /** + * Get the rasterization result. + * @return The pixel data with the rasterized pixels. + */ + PixelData GetPixelData() const override; + +private: + // Undefined + SvgRasterizingTask(const SvgRasterizingTask& task) = delete; + + // Undefined + SvgRasterizingTask& operator=(const SvgRasterizingTask& task) = delete; + +private: + PixelData mPixelData; + uint32_t mWidth; + uint32_t mHeight; }; /** @@ -141,14 +202,14 @@ public: * * @param[in] task The task added to the queue. */ - void AddTask(RasterizingTaskPtr task); + void AddTask(SvgTaskPtr task); /** * Pop the next task out from the completed queue, called by main thread. * * @return The next task in the completed queue. */ - RasterizingTaskPtr NextCompletedTask(); + SvgTaskPtr NextCompletedTask(); /** * Remove the task with the given visual from the waiting queue, called by main thread. @@ -170,14 +231,14 @@ private: * * @return The next task to be processed. */ - RasterizingTaskPtr NextTaskToProcess(); + SvgTaskPtr NextTaskToProcess(); /** * Add a task in to the queue * * @param[in] task The task added to the queue. */ - void AddCompletedTask(RasterizingTaskPtr task); + void AddCompletedTask(SvgTaskPtr task); /** * Applies the rasterized image to material @@ -210,8 +271,8 @@ private: SvgRasterizeThread& operator=(const SvgRasterizeThread& thread); private: - std::vector mRasterizeTasks; //The queue of the tasks waiting to rasterize the SVG image - std::vector mCompletedTasks; //The queue of the tasks with the SVG rasterization completed + std::vector mRasterizeTasks; //The queue of the tasks waiting to rasterize the SVG image + std::vector mCompletedTasks; //The queue of the tasks with the SVG rasterization completed ConditionalWait mConditionalWait; Dali::Mutex mMutex; diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index bddb7f0..a92f7f8 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -87,6 +87,20 @@ void SvgVisual::OnInitialize() Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); mImpl->mRenderer = VisualRenderer::New(geometry, shader); mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); + + Vector2 dpi = Stage::GetCurrent().GetDpi(); + float meanDpi = (dpi.height + dpi.width) * 0.5f; + + SvgTaskPtr newTask = new SvgLoadingTask(this, mVectorRenderer, mImageUrl, meanDpi); + + if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource()) + { + newTask->Process(); + } + else + { + mFactoryCache.GetSVGRasterizationThread()->AddTask(newTask); + } } void SvgVisual::DoSetProperties(const Property::Map& propertyMap) @@ -242,16 +256,12 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) unsigned int width = static_cast(size.width); unsigned int height = static_cast(size.height); - Vector2 dpi = Stage::GetCurrent().GetDpi(); - float meanDpi = (dpi.height + dpi.width) * 0.5f; - - RasterizingTaskPtr newTask = new RasterizingTask(this, mVectorRenderer, mImageUrl, meanDpi, width, height); + SvgTaskPtr newTask = new SvgRasterizingTask(this, mVectorRenderer, width, height); if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource()) { - newTask->Load(); - newTask->Rasterize(); - ApplyRasterizedImage(newTask->GetPixelData(), newTask->IsLoaded()); + newTask->Process(); + ApplyRasterizedImage(newTask->GetPixelData(), newTask->HasSucceeded()); } else { @@ -260,80 +270,84 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) } } -void SvgVisual::ApplyRasterizedImage(PixelData rasterizedPixelData, bool isLoaded) +void SvgVisual::ApplyRasterizedImage(PixelData rasterizedPixelData, bool success) { - if(isLoaded && rasterizedPixelData && IsOnScene()) + if(success) { if(mDefaultWidth == 0 || mDefaultHeight == 0) { mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight); } - mRasterizedSize.x = static_cast(rasterizedPixelData.GetWidth()); - mRasterizedSize.y = static_cast(rasterizedPixelData.GetHeight()); - - TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); - if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) + // Rasterization success + if(rasterizedPixelData && IsOnScene()) { - mFactoryCache.GetAtlasManager()->Remove(currentTextureSet, mAtlasRect); - } - - TextureSet textureSet; + mRasterizedSize.x = static_cast(rasterizedPixelData.GetWidth()); + mRasterizedSize.y = static_cast(rasterizedPixelData.GetHeight()); - if(mAttemptAtlasing && !mImpl->mCustomShader) - { - Vector4 atlasRect; - textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData); - if(textureSet) // atlasing + TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); + if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) { - if(textureSet != currentTextureSet) - { - mImpl->mRenderer.SetTextures(textureSet); - } - mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, atlasRect); - mAtlasRect = atlasRect; - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + mFactoryCache.GetAtlasManager()->Remove(currentTextureSet, mAtlasRect); } - } - if(!textureSet) // no atlasing - mAttemptAtlasing is false or adding to atlas is failed - { - Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight()); - texture.Upload(rasterizedPixelData); - mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + TextureSet textureSet; - if(mAtlasRect == FULL_TEXTURE_RECT) + if(mAttemptAtlasing && !mImpl->mCustomShader) { - textureSet = currentTextureSet; + Vector4 atlasRect; + textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData); + if(textureSet) // atlasing + { + if(textureSet != currentTextureSet) + { + mImpl->mRenderer.SetTextures(textureSet); + } + mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, atlasRect); + mAtlasRect = atlasRect; + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + } } - else + + if(!textureSet) // no atlasing - mAttemptAtlasing is false or adding to atlas is failed { - textureSet = TextureSet::New(); - mImpl->mRenderer.SetTextures(textureSet); + Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight()); + texture.Upload(rasterizedPixelData); + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + + if(mAtlasRect == FULL_TEXTURE_RECT) + { + textureSet = currentTextureSet; + } + else + { + textureSet = TextureSet::New(); + mImpl->mRenderer.SetTextures(textureSet); - mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT); - mAtlasRect = FULL_TEXTURE_RECT; + mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT); + mAtlasRect = FULL_TEXTURE_RECT; + } + + if(textureSet) + { + textureSet.SetTexture(0, texture); + } } - if(textureSet) + // Rasterized pixels are uploaded to texture. If weak handle is holding a placement actor, it is the time to add the renderer to actor. + Actor actor = mPlacementActor.GetHandle(); + if(actor) { - textureSet.SetTexture(0, texture); + actor.AddRenderer(mImpl->mRenderer); + // reset the weak handle so that the renderer only get added to actor once + mPlacementActor.Reset(); } - } - // Rasterized pixels are uploaded to texture. If weak handle is holding a placement actor, it is the time to add the renderer to actor. - Actor actor = mPlacementActor.GetHandle(); - if(actor) - { - actor.AddRenderer(mImpl->mRenderer); - // reset the weak handle so that the renderer only get added to actor once - mPlacementActor.Reset(); + // Svg loaded and ready to display + ResourceReady(Toolkit::Visual::ResourceStatus::READY); } - - // Svg loaded and ready to display - ResourceReady(Toolkit::Visual::ResourceStatus::READY); } - else if(!isLoaded || !rasterizedPixelData) + else if(!success && !mLoadFailed) { mLoadFailed = true; diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.h b/dali-toolkit/internal/visuals/svg/svg-visual.h index 9dd6807..5c606f1 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.h +++ b/dali-toolkit/internal/visuals/svg/svg-visual.h @@ -152,9 +152,9 @@ public: * @bried Apply the rasterized image to the visual. * * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels - * @param[in] bool Whether the resource is loaded + * @param[in] success Whether the task succeeds. */ - void ApplyRasterizedImage(PixelData rasterizedPixelData, bool isLoaded); + void ApplyRasterizedImage(PixelData rasterizedPixelData, bool success); private: /** -- 2.7.4