Merge "Fix key event propagation in text controller" into devel/master
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 26 May 2022 09:38:52 +0000 (09:38 +0000)
committerGerrit Code Review <gerrit@review>
Thu, 26 May 2022 09:38:52 +0000 (09:38 +0000)
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h

index d809e66..3093fcb 100644 (file)
@@ -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};
 };
 
index edaeec1..cb46bd4 100644 (file)
@@ -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
index c65abbb..4383c1a 100644 (file)
@@ -271,6 +271,12 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
       mCurrentFocusActors.push_back(std::pair<WeakHandle<Layer>, WeakHandle<Actor> >(mCurrentFocusedWindow, actor));
     }
 
+    // Send notification for the change of focus actor
+    if(!mFocusChangedSignal.Empty())
+    {
+      mFocusChangedSignal.Emit(currentFocusedActor, actor);
+    }
+
     Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor);
     if(newlyFocusedControl)
     {
@@ -288,11 +294,6 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
       mFocusHistory.erase(beginPos);
     }
 
-    // Send notification for the change of focus actor
-    if(!mFocusChangedSignal.Empty())
-    {
-      mFocusChangedSignal.Emit(currentFocusedActor, actor);
-    }
     DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__);
     success = true;
   }
index 24f9981..c6e0a2c 100644 (file)
@@ -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<RasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
+      // Rasterizing task only, loading task is not duplicated.
+      for(std::vector<SvgTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
       {
         if((*it) && (*it)->GetSvgVisual() == task->GetSvgVisual())
         {
-          mRasterizeTasks.erase(it);
-          break;
+          SvgRasterizingTask* oldTask = dynamic_cast<SvgRasterizingTask*>(it->Get());
+          SvgRasterizingTask* newTask = dynamic_cast<SvgRasterizingTask*>(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<RasterizingTaskPtr>::iterator next     = mCompletedTasks.begin();
-  RasterizingTaskPtr                        nextTask = *next;
+  std::vector<SvgTaskPtr>::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<RasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
+    for(std::vector<SvgTaskPtr>::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<RasterizingTaskPtr>::iterator next     = mRasterizeTasks.begin();
-  RasterizingTaskPtr                        nextTask = *next;
+  std::vector<SvgTaskPtr>::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();
index c0cf726..13d284b 100644 (file)
@@ -42,8 +42,8 @@ namespace Internal
 {
 class SvgVisual;
 typedef IntrusivePtr<SvgVisual> SvgVisualPtr;
-class RasterizingTask;
-typedef IntrusivePtr<RasterizingTask> RasterizingTaskPtr;
+class SvgTask;
+typedef IntrusivePtr<SvgTask> SvgTaskPtr;
 
 /**
  * The svg rasterizing tasks to be processed in the worker thread.
@@ -54,34 +54,31 @@ typedef IntrusivePtr<RasterizingTask> 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<RasterizingTaskPtr> mRasterizeTasks; //The queue of the tasks waiting to rasterize the SVG image
-  std::vector<RasterizingTaskPtr> mCompletedTasks; //The queue of the tasks with the SVG rasterization completed
+  std::vector<SvgTaskPtr> mRasterizeTasks; //The queue of the tasks waiting to rasterize the SVG image
+  std::vector<SvgTaskPtr> mCompletedTasks; //The queue of the tasks with the SVG rasterization completed
 
   ConditionalWait                      mConditionalWait;
   Dali::Mutex                          mMutex;
index bddb7f0..a92f7f8 100644 (file)
@@ -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<unsigned int>(size.width);
     unsigned int height = static_cast<unsigned int>(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<float>(rasterizedPixelData.GetWidth());
-    mRasterizedSize.y = static_cast<float>(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<float>(rasterizedPixelData.GetWidth());
+      mRasterizedSize.y = static_cast<float>(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;
 
index 9dd6807..5c606f1 100644 (file)
@@ -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:
   /**