86e233fcc8740111a3cc4abc2ae39460a026511c
[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 <dali/integration-api/processor-interface.h>
33 #include <memory>
34
35 // INTERNAL INCLUDES
36 #include <dali-toolkit/internal/visuals/visual-url.h>
37
38 namespace Dali
39 {
40
41 namespace Toolkit
42 {
43
44 namespace Internal
45 {
46
47 class SvgVisual;
48 typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
49 class RasterizingTask;
50 typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
51
52 /**
53  * The svg rasterizing tasks to be processed in the worker thread.
54  *
55  * Life cycle of a rasterizing task is as follows:
56  * 1. Created by SvgVisual in the main thread
57  * 2. Queued in the worked thread waiting to be processed.
58  * 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
59  *    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.
60  */
61 class RasterizingTask : public RefObject
62 {
63 public:
64   /**
65    * Constructor
66    * @param[in] svgRenderer The renderer which the rasterized image to be applied.
67    * @param[in] url The URL to svg resource to use.
68    * @param[in] width The rasterization width.
69    * @param[in] height The rasterization height.
70    */
71   RasterizingTask(SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height);
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            mLoadSuccess;
126 };
127
128 /**
129  * The worker thread for SVG rasterization.
130  */
131 class SvgRasterizeThread : public Thread, Integration::Processor
132 {
133 public:
134
135   /**
136    * Constructor.
137    *
138    * @param[in] trigger The trigger to wake up the main thread.
139    */
140   SvgRasterizeThread();
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     /**
180    * @copydoc Dali::Integration::Processor::Process()
181    */
182   void Process() override;
183
184 private:
185
186   /**
187    * Pop the next task out from the queue.
188    *
189    * @return The next task to be processed.
190    */
191   RasterizingTaskPtr NextTaskToProcess();
192
193   /**
194    * Add a task in to the queue
195    *
196    * @param[in] task The task added to the queue.
197    */
198   void AddCompletedTask( RasterizingTaskPtr task );
199
200   /**
201    * Applies the rasterized image to material
202    */
203   void ApplyRasterizedSVGToSampler();
204
205   /**
206    * @brief Unregister a previously registered processor
207    *
208    */
209   void UnregisterProcessor();
210
211 protected:
212
213   /**
214    * Destructor.
215    */
216   ~SvgRasterizeThread() override;
217
218
219   /**
220    * The entry function of the worker thread.
221    * It fetches task from the Queue, rasterizes the image and apply to the renderer.
222    */
223   void Run() override;
224
225 private:
226
227   // Undefined
228   SvgRasterizeThread( const SvgRasterizeThread& thread );
229
230   // Undefined
231   SvgRasterizeThread& operator=( const SvgRasterizeThread& thread );
232
233 private:
234
235   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
236   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
237   Vector <VectorImageRenderer*>    mDeleteSvg;          //The images that the event thread requested to delete
238
239   ConditionalWait            mConditionalWait;
240   Dali::Mutex                mMutex;
241   std::unique_ptr< EventThreadCallback > mTrigger;
242   const Dali::LogFactoryInterface&       mLogFactory;
243   bool                       mIsThreadWaiting;
244   bool                       mProcessorRegistered;
245 };
246
247 } // namespace Internal
248
249 } // namespace Toolkit
250
251 } // namespace Dali
252
253 #endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H