Merge "Change the precision of size and uSize from mediumP to highP" into devel/master
[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-toolkit/internal/visuals/visual-url.h>
31
32 #ifdef NO_THORVG
33 struct NSVGimage;
34 struct NSVGrasterizer;
35 #else /* NO_THORVG */
36 #include <string.h>
37 #include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
38 #endif /* NO_THORVG */
39
40 namespace Dali
41 {
42
43 namespace Toolkit
44 {
45
46 namespace Internal
47 {
48
49 class SvgVisual;
50 typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
51 class RasterizingTask;
52 typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
53
54 /**
55  * The svg rasterizing tasks to be processed in the worker thread.
56  *
57  * Life cycle of a rasterizing task is as follows:
58  * 1. Created by SvgVisual in the main thread
59  * 2. Queued in the worked thread waiting to be processed.
60  * 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
61  *    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.
62  */
63 class RasterizingTask : public RefObject
64 {
65 public:
66 #ifdef NO_THORVG
67   /**
68    * Constructor
69    *
70    * @param[in] svgRenderer The renderer which the rasterized image to be applied.
71    * @param[in] parsedSvg The parsed svg for rasterizing.
72    *            Note, after the task is added to the worker thread, the worker thread takes over the ownership.
73    *            When the image is to be deleted, delete it in the worker thread by calling SvgRasterizeThread::DeleteImage( parsedSvg ).
74    * @param[in] url The URL to svg resource to use.
75    * @param[in] width The rasterization width.
76    * @param[in] height The rasterization height.
77    */
78   RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
79 #else /* NO_THORVG */
80   /**
81    * Constructor
82    * @param[in] svgRenderer The renderer which the rasterized image to be applied.
83    * @param[in] url The URL to svg resource to use.
84    * @param[in] width The rasterization width.
85    * @param[in] height The rasterization height.
86    * @param[in] loaded The svg resource is loaded or not.
87    */
88   RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded );
89 #endif /* NO_THORVG */
90
91   /**
92    * Destructor.
93    */
94   ~RasterizingTask() override;
95
96   /**
97    * Do the rasterization with the mRasterizer.
98    */
99   void Rasterize( );
100
101   /**
102    * Get the svg visual
103    */
104   SvgVisual* GetSvgVisual() const;
105
106   /**
107    * Get the rasterization result.
108    * @return The pixel data with the rasterized pixels.
109    */
110   PixelData GetPixelData() const;
111
112 #ifdef NO_THORVG
113   /**
114    * Get the parsed data.
115    * @return parsed image data.
116    */
117   NSVGimage* GetParsedImage() const;
118   /**
119    * Get default size of svg
120    *
121    * @param[out] width The default width of svg
122    * @param[out] height The default height of svg
123    */
124   void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
125 #else /* NO_THORVG */
126   /**
127    * Get the VectorRenderer.
128    * @return VectorRenderer.
129    */
130   VectorImageRenderer GetVectorRenderer() const;
131   /**
132    * Whether the resource is loaded.
133    * @return True if the resource is loaded.
134    */
135   bool IsLoaded() const;
136 #endif /* NO_THORVG */
137
138   /**
139    * Load svg file
140    */
141   void Load();
142
143 private:
144   // Undefined
145   RasterizingTask( const RasterizingTask& task );
146
147   // Undefined
148   RasterizingTask& operator=( const RasterizingTask& task );
149
150 private:
151   SvgVisualPtr    mSvgVisual;
152 #ifdef NO_THORVG
153   NSVGimage*      mParsedSvg;
154 #else /* NO_THORVG */
155   VectorImageRenderer mVectorRenderer;
156 #endif /* NO_THORVG */
157   VisualUrl       mUrl;
158   PixelData       mPixelData;
159   float           mDpi;
160   unsigned int    mWidth;
161   unsigned int    mHeight;
162 #ifdef NO_THORVG
163   NSVGrasterizer* mRasterizer;
164 #else /* NO_THORVG */
165   bool            mLoaded;
166 #endif /* NO_THORVG */
167 };
168
169 /**
170  * The worker thread for SVG rasterization.
171  */
172 class SvgRasterizeThread : public Thread
173 {
174 public:
175
176   /**
177    * Constructor.
178    *
179    * @param[in] trigger The trigger to wake up the main thread.
180    */
181   SvgRasterizeThread( EventThreadCallback* trigger );
182
183   /**
184    * Terminate the svg rasterize thread, join and delete.
185    */
186   static void TerminateThread( SvgRasterizeThread*& thread );
187
188   /**
189    * Add a rasterization task into the waiting queue, called by main thread.
190    *
191    * @param[in] task The task added to the queue.
192    */
193   void AddTask( RasterizingTaskPtr task );
194
195   /**
196    * Pop the next task out from the completed queue, called by main thread.
197    *
198    * @return The next task in the completed queue.
199    */
200   RasterizingTaskPtr NextCompletedTask();
201
202   /**
203    * Remove the task with the given visual from the waiting queue, called by main thread.
204    *
205    * Typically called when the actor is put off stage, so the renderer is not needed anymore.
206    *
207    * @param[in] visual The visual pointer.
208    */
209   void RemoveTask( SvgVisual* visual );
210
211 #ifdef NO_THORVG
212   /**
213    * Delete the parsed SVG image, called by main thread.
214    *
215    * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
216    *
217    * @param[in] parsedImage The image to be deleted
218    */
219   void DeleteImage( NSVGimage* parsedSvg );
220 #else /* NO_THORVG */
221   /**
222    * Delete the parsed SVG image, called by main thread.
223    *
224    * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
225    *
226    * @param[in] VectorImage The image to be deleted
227    */
228   void DeleteImage( VectorImageRenderer vectorImage );
229 #endif /* NO_THORVG */
230
231 private:
232
233   /**
234    * Pop the next task out from the queue.
235    *
236    * @return The next task to be processed.
237    */
238   RasterizingTaskPtr NextTaskToProcess();
239
240   /**
241    * Add a task in to the queue
242    *
243    * @param[in] task The task added to the queue.
244    */
245   void AddCompletedTask( RasterizingTaskPtr task );
246
247 protected:
248
249   /**
250    * Destructor.
251    */
252   ~SvgRasterizeThread() override;
253
254
255   /**
256    * The entry function of the worker thread.
257    * It fetches task from the Queue, rasterizes the image and apply to the renderer.
258    */
259   void Run() override;
260
261 private:
262
263   // Undefined
264   SvgRasterizeThread( const SvgRasterizeThread& thread );
265
266   // Undefined
267   SvgRasterizeThread& operator=( const SvgRasterizeThread& thread );
268
269 private:
270
271   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
272   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
273 #ifdef NO_THORVG
274   Vector<NSVGimage*>               mDeleteSvg;          //The images that the event thread requested to delete
275 #else /* NO_THORVG */
276   Vector <VectorImageRenderer*>      mDeleteSvg;          //The images that the event thread requested to delete
277 #endif /* NO_THORVG */
278
279   ConditionalWait            mConditionalWait;
280   Dali::Mutex                mMutex;
281   EventThreadCallback*       mTrigger;
282
283   bool                       mIsThreadWaiting;
284 };
285
286 } // namespace Internal
287
288 } // namespace Toolkit
289
290 } // namespace Dali
291
292 #endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H