Refactor SvgVisual
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / svg / svg-rasterize-thread.h
1 #ifndef DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H
2 #define DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
22 #include <dali/devel-api/threading/conditional-wait.h>
23 #include <dali/devel-api/threading/mutex.h>
24 #include <dali/devel-api/threading/thread.h>
25 #include <dali/public-api/images/pixel-data.h>
26 #include <dali/public-api/common/intrusive-ptr.h>
27 #include <dali/public-api/common/vector-wrapper.h>
28 #include <dali/public-api/object/ref-object.h>
29 #include <dali/public-api/rendering/texture-set.h>
30 #include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
31 #include <dali/integration-api/adaptor-framework/log-factory-interface.h>
32 #include <memory>
33
34 // INTERNAL INCLUDES
35 #include <dali-toolkit/internal/visuals/visual-url.h>
36
37 namespace Dali
38 {
39
40 namespace Toolkit
41 {
42
43 namespace Internal
44 {
45
46 class SvgVisual;
47 typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
48 class RasterizingTask;
49 typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
50
51 /**
52  * The svg rasterizing tasks to be processed in the worker thread.
53  *
54  * Life cycle of a rasterizing task is as follows:
55  * 1. Created by SvgVisual in the main thread
56  * 2. Queued in the worked thread waiting to be processed.
57  * 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
58  *    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.
59  */
60 class RasterizingTask : public RefObject
61 {
62 public:
63   /**
64    * Constructor
65    * @param[in] svgRenderer The renderer which the rasterized image to be applied.
66    * @param[in] url The URL to svg resource to use.
67    * @param[in] width The rasterization width.
68    * @param[in] height The rasterization height.
69    * @param[in] loaded The svg resource is loaded or not.
70    */
71   RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded );
72
73   /**
74    * Destructor.
75    */
76   ~RasterizingTask() override;
77
78   /**
79    * Do the rasterization with the mRasterizer.
80    */
81   void Rasterize();
82
83   /**
84    * Get the svg visual
85    */
86   SvgVisual* GetSvgVisual() const;
87
88   /**
89    * Get the rasterization result.
90    * @return The pixel data with the rasterized pixels.
91    */
92   PixelData GetPixelData() const;
93
94   /**
95    * Get the VectorRenderer.
96    * @return VectorRenderer.
97    */
98   VectorImageRenderer GetVectorRenderer() const;
99   /**
100    * Whether the resource is loaded.
101    * @return True if the resource is loaded.
102    */
103   bool IsLoaded() const;
104
105   /**
106    * Load svg file
107    */
108   void Load();
109
110 private:
111   // Undefined
112   RasterizingTask( const RasterizingTask& task );
113
114   // Undefined
115   RasterizingTask& operator=( const RasterizingTask& task );
116
117 private:
118   SvgVisualPtr    mSvgVisual;
119   VectorImageRenderer mVectorRenderer;
120   VisualUrl       mUrl;
121   PixelData       mPixelData;
122   float           mDpi;
123   unsigned int    mWidth;
124   unsigned int    mHeight;
125   bool            mLoaded;
126 };
127
128 /**
129  * The worker thread for SVG rasterization.
130  */
131 class SvgRasterizeThread : public Thread
132 {
133 public:
134
135   /**
136    * Constructor.
137    *
138    * @param[in] trigger The trigger to wake up the main thread.
139    */
140   SvgRasterizeThread( EventThreadCallback* trigger );
141
142   /**
143    * Terminate the svg rasterize thread, join and delete.
144    */
145   static void TerminateThread( SvgRasterizeThread*& thread );
146
147   /**
148    * Add a rasterization task into the waiting queue, called by main thread.
149    *
150    * @param[in] task The task added to the queue.
151    */
152   void AddTask( RasterizingTaskPtr task );
153
154   /**
155    * Pop the next task out from the completed queue, called by main thread.
156    *
157    * @return The next task in the completed queue.
158    */
159   RasterizingTaskPtr NextCompletedTask();
160
161   /**
162    * Remove the task with the given visual from the waiting queue, called by main thread.
163    *
164    * Typically called when the actor is put off stage, so the renderer is not needed anymore.
165    *
166    * @param[in] visual The visual pointer.
167    */
168   void RemoveTask( SvgVisual* visual );
169
170   /**
171    * Delete the parsed SVG image, called by main thread.
172    *
173    * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
174    *
175    * @param[in] VectorImage The image to be deleted
176    */
177   void DeleteImage( VectorImageRenderer vectorImage );
178
179 private:
180
181   /**
182    * Pop the next task out from the queue.
183    *
184    * @return The next task to be processed.
185    */
186   RasterizingTaskPtr NextTaskToProcess();
187
188   /**
189    * Add a task in to the queue
190    *
191    * @param[in] task The task added to the queue.
192    */
193   void AddCompletedTask( RasterizingTaskPtr task );
194
195 protected:
196
197   /**
198    * Destructor.
199    */
200   ~SvgRasterizeThread() override;
201
202
203   /**
204    * The entry function of the worker thread.
205    * It fetches task from the Queue, rasterizes the image and apply to the renderer.
206    */
207   void Run() override;
208
209 private:
210
211   // Undefined
212   SvgRasterizeThread( const SvgRasterizeThread& thread );
213
214   // Undefined
215   SvgRasterizeThread& operator=( const SvgRasterizeThread& thread );
216
217 private:
218
219   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
220   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
221   Vector <VectorImageRenderer*>    mDeleteSvg;          //The images that the event thread requested to delete
222
223   ConditionalWait            mConditionalWait;
224   Dali::Mutex                mMutex;
225   std::unique_ptr< EventThreadCallback > mTrigger;
226   const Dali::LogFactoryInterface&       mLogFactory;
227   bool                       mIsThreadWaiting;
228 };
229
230 } // namespace Internal
231
232 } // namespace Toolkit
233
234 } // namespace Dali
235
236 #endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H