[dali_2.2.39] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / image-loader / loading-task.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/image-loader/loading-task.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/image-loading.h>
23 #include <dali/devel-api/adaptor-framework/thread-settings.h>
24 #include <dali/integration-api/adaptor-framework/adaptor.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/integration-api/trace.h>
27 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
28
29 #ifdef TRACE_ENABLED
30 #include <sstream>
31 #endif
32
33 namespace Dali
34 {
35 namespace Toolkit
36 {
37 namespace Internal
38 {
39 namespace
40 {
41 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_IMAGE_PERFORMANCE_MARKER, false);
42 }
43
44 LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
45 : AsyncTask(callback),
46   url(),
47   encodedImageBuffer(),
48   id(id),
49   textureId(TextureManagerType::INVALID_TEXTURE_ID),
50   dimensions(),
51   fittingMode(FittingMode::SCALE_TO_FILL),
52   samplingMode(SamplingMode::BOX_THEN_LINEAR),
53   preMultiplyOnLoad(preMultiplyOnLoad),
54   maskPixelBuffer(),
55   contentScale(1.0f),
56   animatedImageLoading(animatedImageLoading),
57   frameIndex(frameIndex),
58   orientationCorrection(),
59   isMaskTask(false),
60   cropToMask(false),
61   loadPlanes(false),
62   isReady(true)
63 {
64 }
65
66 LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
67 : AsyncTask(callback),
68   url(),
69   encodedImageBuffer(),
70   id(id),
71   textureId(TextureManagerType::INVALID_TEXTURE_ID),
72   dimensions(dimensions),
73   fittingMode(fittingMode),
74   samplingMode(samplingMode),
75   preMultiplyOnLoad(preMultiplyOnLoad),
76   maskPixelBuffer(),
77   contentScale(1.0f),
78   animatedImageLoading(animatedImageLoading),
79   frameIndex(frameIndex),
80   orientationCorrection(),
81   isMaskTask(false),
82   cropToMask(false),
83   loadPlanes(false),
84   isReady(true)
85 {
86 }
87
88 LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, bool loadPlanes, CallbackBase* callback)
89 : AsyncTask(callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
90   url(url),
91   encodedImageBuffer(),
92   id(id),
93   textureId(TextureManagerType::INVALID_TEXTURE_ID),
94   dimensions(dimensions),
95   fittingMode(fittingMode),
96   samplingMode(samplingMode),
97   preMultiplyOnLoad(preMultiplyOnLoad),
98   maskPixelBuffer(),
99   contentScale(1.0f),
100   animatedImageLoading(),
101   frameIndex(0u),
102   orientationCorrection(orientationCorrection),
103   isMaskTask(false),
104   cropToMask(false),
105   loadPlanes(loadPlanes),
106   isReady(true)
107 {
108 }
109
110 LoadingTask::LoadingTask(uint32_t id, const EncodedImageBuffer& encodedImageBuffer, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
111 : AsyncTask(callback),
112   url(),
113   encodedImageBuffer(encodedImageBuffer),
114   id(id),
115   textureId(TextureManagerType::INVALID_TEXTURE_ID),
116   dimensions(dimensions),
117   fittingMode(fittingMode),
118   samplingMode(samplingMode),
119   preMultiplyOnLoad(preMultiplyOnLoad),
120   maskPixelBuffer(),
121   contentScale(1.0f),
122   animatedImageLoading(),
123   frameIndex(0u),
124   orientationCorrection(orientationCorrection),
125   isMaskTask(false),
126   cropToMask(false),
127   loadPlanes(false),
128   isReady(true)
129 {
130 }
131
132 LoadingTask::LoadingTask(uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
133 : AsyncTask(callback),
134   url(""),
135   encodedImageBuffer(),
136   id(id),
137   textureId(TextureManagerType::INVALID_TEXTURE_ID),
138   dimensions(),
139   fittingMode(),
140   samplingMode(),
141   preMultiplyOnLoad(preMultiplyOnLoad),
142   maskPixelBuffer(maskPixelBuffer),
143   contentScale(contentScale),
144   animatedImageLoading(),
145   frameIndex(0u),
146   orientationCorrection(),
147   isMaskTask(true),
148   cropToMask(cropToMask),
149   loadPlanes(false),
150   isReady(true)
151 {
152   pixelBuffers.push_back(pixelBuffer);
153 }
154
155 LoadingTask::~LoadingTask()
156 {
157 }
158
159 void LoadingTask::Process()
160 {
161 #ifdef TRACE_ENABLED
162   if(gTraceFilter && gTraceFilter->IsTraceEnabled())
163   {
164     std::ostringstream oss;
165     oss << "[url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
166     DALI_TRACE_BEGIN_WITH_MESSAGE(gTraceFilter, "DALI_IMAGE_LOADING_TASK", oss.str().c_str());
167   }
168 #endif
169
170   isReady = false;
171   if(!isMaskTask)
172   {
173     Load();
174   }
175   else
176   {
177     ApplyMask();
178   }
179   MultiplyAlpha();
180   isReady = true;
181
182 #ifdef TRACE_ENABLED
183   if(gTraceFilter && gTraceFilter->IsTraceEnabled())
184   {
185     std::ostringstream oss;
186     oss << "[";
187     oss << "masking:" << isMaskTask << " ";
188     oss << "index: " << frameIndex << " ";
189     oss << "pixelBuffers: " << pixelBuffers.size() << " ";
190     if(!pixelBuffers.empty())
191     {
192       oss << "premult:" << pixelBuffers[0].IsAlphaPreMultiplied() << " ";
193     }
194     oss << "url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
195     DALI_TRACE_END_WITH_MESSAGE(gTraceFilter, "DALI_IMAGE_LOADING_TASK", oss.str().c_str());
196   }
197 #endif
198 }
199
200 bool LoadingTask::IsReady()
201 {
202   return isReady;
203 }
204
205 void LoadingTask::Load()
206 {
207   Devel::PixelBuffer pixelBuffer;
208   if(animatedImageLoading)
209   {
210     pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, dimensions, fittingMode, samplingMode);
211   }
212   else if(encodedImageBuffer)
213   {
214     pixelBuffer = Dali::LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), dimensions, fittingMode, samplingMode, orientationCorrection);
215   }
216   else if(url.IsValid() && url.IsLocalResource())
217   {
218     if(loadPlanes)
219     {
220       Dali::LoadImagePlanesFromFile(url.GetUrl(), pixelBuffers, dimensions, fittingMode, samplingMode, orientationCorrection);
221     }
222     else
223     {
224       pixelBuffer = Dali::LoadImageFromFile(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
225     }
226   }
227   else if(url.IsValid())
228   {
229     pixelBuffer = Dali::DownloadImageSynchronously(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
230   }
231
232   if(pixelBuffer)
233   {
234     pixelBuffers.push_back(pixelBuffer);
235   }
236
237   if(pixelBuffers.empty())
238   {
239     DALI_LOG_ERROR("LoadingTask::Load: Loading is failed: %s\n", url.GetUrl().c_str());
240   }
241 }
242
243 void LoadingTask::ApplyMask()
244 {
245   if(!pixelBuffers.empty())
246   {
247     pixelBuffers[0].ApplyMask(maskPixelBuffer, contentScale, cropToMask);
248   }
249 }
250
251 void LoadingTask::MultiplyAlpha()
252 {
253   if(!pixelBuffers.empty() && Pixel::HasAlpha(pixelBuffers[0].GetPixelFormat()))
254   {
255     if(preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON)
256     {
257       pixelBuffers[0].MultiplyColorByAlpha();
258     }
259   }
260 }
261
262 void LoadingTask::SetTextureId(TextureManagerType::TextureId id)
263 {
264   textureId = id;
265 }
266
267 } // namespace Internal
268
269 } // namespace Toolkit
270
271 } // namespace Dali