95ec2604a047f453dcaed02718a49f8048efdb49
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / image-loader / image-load-thread.h
1 #ifndef DALI_TOOLKIT_IMAGE_LOAD_THREAD_H
2 #define DALI_TOOLKIT_IMAGE_LOAD_THREAD_H
3
4 /*
5  * Copyright (c) 2021 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-toolkit/devel-api/image-loader/async-image-loader-devel.h>
22 #include <dali-toolkit/internal/visuals/visual-url.h>
23 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
24 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
25 #include <dali/devel-api/threading/conditional-wait.h>
26 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/devel-api/threading/thread.h>
28 #include <dali/integration-api/adaptor-framework/log-factory-interface.h>
29 #include <dali/public-api/common/dali-vector.h>
30 #include <dali/public-api/images/image-operations.h>
31 #include <dali/public-api/object/ref-object.h>
32 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
33
34 namespace Dali
35 {
36 namespace Toolkit
37 {
38 namespace Internal
39 {
40 /**
41  * The task of loading and packing an image into the atlas.
42  */
43 struct LoadingTask
44 {
45   /**
46    * Constructor.
47    * @param [in] id of the task
48    * @param [in] animatedImageLoading The AnimatedImageLoading to load animated image
49    * @param [in] frameIndex The frame index of a frame to be loaded frame
50    */
51   LoadingTask(uint32_t                   id,
52               Dali::AnimatedImageLoading animatedImageLoading,
53               uint32_t                   frameIndex);
54
55   /**
56    * Constructor.
57    * @param [in] id of the task
58    * @param [in] url The URL of the image file to load.
59    * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
60    * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
61    * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
62    * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
63    * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
64    */
65   LoadingTask(uint32_t                                 id,
66               const VisualUrl&                         url,
67               ImageDimensions                          dimensions,
68               FittingMode::Type                        fittingMode,
69               SamplingMode::Type                       samplingMode,
70               bool                                     orientationCorrection,
71               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
72
73   /**
74    * Constructor.
75    * @param [in] id of the task
76    * @param [in] encodedImageBuffer The encoded buffer of the image to load.
77    * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
78    * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
79    * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
80    * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
81    * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
82    */
83   LoadingTask(uint32_t                                 id,
84               const EncodedImageBuffer&                encodedImageBuffer,
85               ImageDimensions                          dimensions,
86               FittingMode::Type                        fittingMode,
87               SamplingMode::Type                       samplingMode,
88               bool                                     orientationCorrection,
89               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
90
91   /**
92    * Constructor.
93    * @param [in] id of the task
94    * @param [in] pixelBuffer of the to be masked image
95    * @param [in] maskPixelBuffer of the mask image
96    * @param [in] contentScale The factor to scale the content
97    * @param [in] cropToMask Whether to crop the content to the mask size
98    * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
99    */
100   LoadingTask(uint32_t                                 id,
101               Devel::PixelBuffer                       pixelBuffer,
102               Devel::PixelBuffer                       maskPixelBuffer,
103               float                                    contentScale,
104               bool                                     cropToMask,
105               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
106
107   /**
108    * Load the image
109    */
110   void Load();
111
112   /**
113    * Apply mask
114    */
115   void ApplyMask();
116
117   /**
118    * Multiply alpha
119    */
120   void MultiplyAlpha();
121
122 private:
123   // Undefined
124   LoadingTask(const LoadingTask& queue);
125
126   // Undefined
127   LoadingTask& operator=(const LoadingTask& queue);
128
129 public:
130   Devel::PixelBuffer pixelBuffer;                                     ///< pixelBuffer handle after successful load
131                                                                       ///< or pixelBuffer to be masked image in the mask task
132   VisualUrl                                url;                       ///< url of the image to load
133   EncodedImageBuffer                       encodedImageBuffer;        ///< encoded buffer of the image to load
134   uint32_t                                 id;                        ///< The unique id associated with this task.
135   ImageDimensions                          dimensions;                ///< dimensions to load
136   FittingMode::Type                        fittingMode;               ///< fitting options
137   SamplingMode::Type                       samplingMode;              ///< sampling options
138   bool                                     orientationCorrection : 1; ///< if orientation correction is needed
139   DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad;         //< if the image's color should be multiplied by it's alpha
140
141   bool                       isMaskTask;      ///< whether this task is for mask or not
142   Devel::PixelBuffer         maskPixelBuffer; ///< pixelBuffer of mask image
143   float                      contentScale;    ///< The factor to scale the content
144   bool                       cropToMask;      ///< Whether to crop the content to the mask size
145   Dali::AnimatedImageLoading animatedImageLoading;
146   uint32_t                   frameIndex;
147 };
148
149 /**
150  * The worker thread for image loading.
151  */
152 class ImageLoadThread : public Thread
153 {
154 public:
155   /**
156    * Constructor.
157    *
158    * @param[in] mTrigger The trigger to wake up the main thread.
159    */
160   ImageLoadThread(EventThreadCallback* mTrigger);
161
162   /**
163    * Destructor.
164    */
165   ~ImageLoadThread() override;
166
167   /**
168    * Add a task in to the loading queue
169    *
170    * @param[in] task The task added to the queue.
171    *
172    * @note This class takes ownership of the task object
173    */
174   void AddTask(LoadingTask* task);
175
176   /**
177    * Pop the next task out from the completed queue.
178    *
179    * @return The next task to be processed.
180    */
181   LoadingTask* NextCompletedTask();
182
183   /**
184    * Remove the loading task from the waiting queue.
185    */
186   bool CancelTask(uint32_t loadingTaskId);
187
188   /**
189    * Remove all the loading tasks in the waiting queue.
190    */
191   void CancelAll();
192
193 private:
194   /**
195    * Pop the next loading task out from the queue to process.
196    *
197    * @return The next task to be processed.
198    */
199   LoadingTask* NextTaskToProcess();
200
201   /**
202    * Add a task in to the loading queue
203    *
204    * @param[in] task The task added to the queue.
205    */
206   void AddCompletedTask(LoadingTask* task);
207
208 protected:
209   /**
210    * The entry function of the worker thread.
211    * It fetches loading task from the loadQueue, loads the image and adds to the completeQueue.
212    */
213   void Run() override;
214
215 private:
216   // Undefined
217   ImageLoadThread(const ImageLoadThread& thread);
218
219   // Undefined
220   ImageLoadThread& operator=(const ImageLoadThread& thread);
221
222 private:
223   Vector<LoadingTask*>             mLoadQueue;     ///<The task queue with images for loading.
224   Vector<LoadingTask*>             mCompleteQueue; ///<The task queue with images loaded.
225   EventThreadCallback*             mTrigger;
226   const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
227
228   ConditionalWait mConditionalWait;
229   Dali::Mutex     mMutex;
230 };
231
232 } // namespace Internal
233
234 } // namespace Toolkit
235
236 } // namespace Dali
237
238 #endif // DALI_TOOLKIT_IMAGE_LOAD_THREAD_H