Merge "Blend Equation Advanced Supporting" 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/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    * @param[in] loaded The svg resource is loaded or not.
71    */
72   RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded );
73
74   /**
75    * Destructor.
76    */
77   ~RasterizingTask() override;
78
79   /**
80    * Do the rasterization with the mRasterizer.
81    */
82   void Rasterize();
83
84   /**
85    * Get the svg visual
86    */
87   SvgVisual* GetSvgVisual() const;
88
89   /**
90    * Get the rasterization result.
91    * @return The pixel data with the rasterized pixels.
92    */
93   PixelData GetPixelData() const;
94
95   /**
96    * Get the VectorRenderer.
97    * @return VectorRenderer.
98    */
99   VectorImageRenderer GetVectorRenderer() const;
100   /**
101    * Whether the resource is loaded.
102    * @return True if the resource is loaded.
103    */
104   bool IsLoaded() const;
105
106   /**
107    * Load svg file
108    */
109   void Load();
110
111 private:
112   // Undefined
113   RasterizingTask( const RasterizingTask& task );
114
115   // Undefined
116   RasterizingTask& operator=( const RasterizingTask& task );
117
118 private:
119   SvgVisualPtr    mSvgVisual;
120   VectorImageRenderer mVectorRenderer;
121   VisualUrl       mUrl;
122   PixelData       mPixelData;
123   float           mDpi;
124   unsigned int    mWidth;
125   unsigned int    mHeight;
126   bool            mLoaded;
127 };
128
129 /**
130  * The worker thread for SVG rasterization.
131  */
132 class SvgRasterizeThread : public Thread, Integration::Processor
133 {
134 public:
135
136   /**
137    * Constructor.
138    *
139    * @param[in] trigger The trigger to wake up the main thread.
140    */
141   SvgRasterizeThread();
142
143   /**
144    * Terminate the svg rasterize thread, join and delete.
145    */
146   static void TerminateThread( SvgRasterizeThread*& thread );
147
148   /**
149    * Add a rasterization task into the waiting queue, called by main thread.
150    *
151    * @param[in] task The task added to the queue.
152    */
153   void AddTask( RasterizingTaskPtr task );
154
155   /**
156    * Pop the next task out from the completed queue, called by main thread.
157    *
158    * @return The next task in the completed queue.
159    */
160   RasterizingTaskPtr NextCompletedTask();
161
162   /**
163    * Remove the task with the given visual from the waiting queue, called by main thread.
164    *
165    * Typically called when the actor is put off stage, so the renderer is not needed anymore.
166    *
167    * @param[in] visual The visual pointer.
168    */
169   void RemoveTask( SvgVisual* visual );
170
171   /**
172    * Delete the parsed SVG image, called by main thread.
173    *
174    * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
175    *
176    * @param[in] VectorImage The image to be deleted
177    */
178   void DeleteImage( VectorImageRenderer vectorImage );
179
180     /**
181    * @copydoc Dali::Integration::Processor::Process()
182    */
183   void Process() override;
184
185 private:
186
187   /**
188    * Pop the next task out from the queue.
189    *
190    * @return The next task to be processed.
191    */
192   RasterizingTaskPtr NextTaskToProcess();
193
194   /**
195    * Add a task in to the queue
196    *
197    * @param[in] task The task added to the queue.
198    */
199   void AddCompletedTask( RasterizingTaskPtr task );
200
201   /**
202    * Applies the rasterized image to material
203    */
204   void ApplyRasterizedSVGToSampler();
205
206   /**
207    * @brief Unregister a previously registered processor
208    *
209    */
210   void UnregisterProcessor();
211
212 protected:
213
214   /**
215    * Destructor.
216    */
217   ~SvgRasterizeThread() override;
218
219
220   /**
221    * The entry function of the worker thread.
222    * It fetches task from the Queue, rasterizes the image and apply to the renderer.
223    */
224   void Run() override;
225
226 private:
227
228   // Undefined
229   SvgRasterizeThread( const SvgRasterizeThread& thread );
230
231   // Undefined
232   SvgRasterizeThread& operator=( const SvgRasterizeThread& thread );
233
234 private:
235
236   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
237   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
238   Vector <VectorImageRenderer*>    mDeleteSvg;          //The images that the event thread requested to delete
239
240   ConditionalWait            mConditionalWait;
241   Dali::Mutex                mMutex;
242   std::unique_ptr< EventThreadCallback > mTrigger;
243   const Dali::LogFactoryInterface&       mLogFactory;
244   bool                       mIsThreadWaiting;
245   bool                       mProcessorRegistered;
246 };
247
248 } // namespace Internal
249
250 } // namespace Toolkit
251
252 } // namespace Dali
253
254 #endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H