Merge "Fix Coverity issue" 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) 2019 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/buffer-image.h>
26 #include <dali/public-api/images/pixel-data.h>
27 #include <dali/public-api/common/intrusive-ptr.h>
28 #include <dali/public-api/common/vector-wrapper.h>
29 #include <dali/public-api/object/ref-object.h>
30 #include <dali/public-api/rendering/texture-set.h>
31
32 struct NSVGimage;
33 struct NSVGrasterizer;
34
35 namespace Dali
36 {
37
38 namespace Toolkit
39 {
40
41 namespace Internal
42 {
43
44 class SvgVisual;
45 typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
46 class RasterizingTask;
47 typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
48
49 /**
50  * The svg rasterizing tasks to be processed in the worker thread.
51  *
52  * Life cycle of a rasterizing task is as follows:
53  * 1. Created by SvgVisual in the main thread
54  * 2. Queued in the worked thread waiting to be processed.
55  * 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
56  *    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.
57  */
58 class RasterizingTask : public RefObject
59 {
60 public:
61   /**
62    * Constructor
63    *
64    * @param[in] svgRenderer The renderer which the rasterized image to be applied.
65    * @param[in] parsedSvg The parsed svg for rasterizing.
66    *            Note, after the task is added to the worker thread, the worker thread takes over the ownership.
67    *            When the image is to be deleted, delete it in the worker thread by calling SvgRasterizeThread::DeleteImage( parsedSvg ).
68    * @param[in] width The rasterization width.
69    * @param[in] height The rasterization height.
70    */
71   RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, unsigned int width, unsigned int height );
72
73   /**
74    * Do the rasterization with the given rasterizer.
75    *@param[in] rasterizer The rasterizer that rasterize the SVG to a buffer image
76    */
77   void Rasterize( NSVGrasterizer* rasterizer );
78
79   /**
80    * Get the svg visual
81    */
82   SvgVisual* GetSvgVisual() const;
83
84   /**
85    * Get the rasterization result.
86    * @return The pixel data with the rasterized pixels.
87    */
88   PixelData GetPixelData() const;
89
90 private:
91
92   // Undefined
93   RasterizingTask( const RasterizingTask& task );
94
95   // Undefined
96   RasterizingTask& operator=( const RasterizingTask& task );
97
98 private:
99   SvgVisualPtr  mSvgVisual;
100   PixelData       mPixelData;
101   NSVGimage*      mParsedSvg;
102   unsigned int    mWidth;
103   unsigned int    mHeight;
104 };
105
106
107 /**
108  * The worker thread for SVG rasterization.
109  */
110 class SvgRasterizeThread : public Thread
111 {
112 public:
113
114   /**
115    * Constructor.
116    *
117    * @param[in] trigger The trigger to wake up the main thread.
118    */
119   SvgRasterizeThread( EventThreadCallback* trigger );
120
121   /**
122    * Terminate the svg rasterize thread, join and delete.
123    */
124   static void TerminateThread( SvgRasterizeThread*& thread );
125
126   /**
127    * Add a rasterization task into the waiting queue, called by main thread.
128    *
129    * @param[in] task The task added to the queue.
130    */
131   void AddTask( RasterizingTaskPtr task );
132
133   /**
134    * Pop the next task out from the completed queue, called by main thread.
135    *
136    * @return The next task in the completed queue.
137    */
138   RasterizingTaskPtr NextCompletedTask();
139
140   /**
141    * Remove the task with the given visual from the waiting queue, called by main thread.
142    *
143    * Typically called when the actor is put off stage, so the renderer is not needed anymore.
144    *
145    * @param[in] visual The visual pointer.
146    */
147   void RemoveTask( SvgVisual* visual );
148
149   /**
150    * Delete the parsed SVG image, called by main thread.
151    *
152    * The parsed svg should be delelted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
153    *
154    * @param[in] parsedImage The image to be deleted
155    */
156   void DeleteImage( NSVGimage* parsedSvg );
157
158 private:
159
160   /**
161    * Pop the next task out from the queue.
162    *
163    * @return The next task to be processed.
164    */
165   RasterizingTaskPtr NextTaskToProcess();
166
167   /**
168    * Add a task in to the queue
169    *
170    * @param[in] task The task added to the queue.
171    */
172   void AddCompletedTask( RasterizingTaskPtr task );
173
174 protected:
175
176   /**
177    * Destructor.
178    */
179   virtual ~SvgRasterizeThread();
180
181
182   /**
183    * The entry function of the worker thread.
184    * It fetches task from the Queue, rasterizes the image and apply to the renderer.
185    */
186   void Run() override;
187
188 private:
189
190   // Undefined
191   SvgRasterizeThread( const SvgRasterizeThread& thread );
192
193   // Undefined
194   SvgRasterizeThread& operator=( const SvgRasterizeThread& thread );
195
196 private:
197
198   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
199   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
200   Vector<NSVGimage*>               mDeleteSvg;          //The images that the event thread requested to delete
201
202   ConditionalWait            mConditionalWait;
203   Dali::Mutex                mMutex;
204   EventThreadCallback*       mTrigger;
205
206   NSVGrasterizer*            mRasterizer;
207   bool                       mIsThreadWaiting;
208 };
209
210 } // namespace Internal
211
212 } // namespace Toolkit
213
214 } // namespace Dali
215
216 #endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H