2 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/image-loader/loading-task.h>
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>
44 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_IMAGE_PERFORMANCE_MARKER, false);
47 uint64_t GetNanoseconds()
49 // Get the time of a monotonic clock since its epoch.
50 auto epoch = std::chrono::steady_clock::now().time_since_epoch();
51 auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(epoch);
52 return static_cast<uint64_t>(duration.count());
57 LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
58 : AsyncTask(callback),
62 textureId(TextureManagerType::INVALID_TEXTURE_ID),
64 fittingMode(FittingMode::SCALE_TO_FILL),
65 samplingMode(SamplingMode::BOX_THEN_LINEAR),
66 preMultiplyOnLoad(preMultiplyOnLoad),
69 animatedImageLoading(animatedImageLoading),
70 frameIndex(frameIndex),
71 orientationCorrection(),
79 LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
80 : AsyncTask(callback),
84 textureId(TextureManagerType::INVALID_TEXTURE_ID),
85 dimensions(dimensions),
86 fittingMode(fittingMode),
87 samplingMode(samplingMode),
88 preMultiplyOnLoad(preMultiplyOnLoad),
91 animatedImageLoading(animatedImageLoading),
92 frameIndex(frameIndex),
93 orientationCorrection(),
101 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)
102 : AsyncTask(callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
104 encodedImageBuffer(),
106 textureId(TextureManagerType::INVALID_TEXTURE_ID),
107 dimensions(dimensions),
108 fittingMode(fittingMode),
109 samplingMode(samplingMode),
110 preMultiplyOnLoad(preMultiplyOnLoad),
113 animatedImageLoading(),
115 orientationCorrection(orientationCorrection),
118 loadPlanes(loadPlanes),
123 LoadingTask::LoadingTask(uint32_t id, const EncodedImageBuffer& encodedImageBuffer, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
124 : AsyncTask(callback),
126 encodedImageBuffer(encodedImageBuffer),
128 textureId(TextureManagerType::INVALID_TEXTURE_ID),
129 dimensions(dimensions),
130 fittingMode(fittingMode),
131 samplingMode(samplingMode),
132 preMultiplyOnLoad(preMultiplyOnLoad),
135 animatedImageLoading(),
137 orientationCorrection(orientationCorrection),
145 LoadingTask::LoadingTask(uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
146 : AsyncTask(callback),
148 encodedImageBuffer(),
150 textureId(TextureManagerType::INVALID_TEXTURE_ID),
154 preMultiplyOnLoad(preMultiplyOnLoad),
155 maskPixelBuffer(maskPixelBuffer),
156 contentScale(contentScale),
157 animatedImageLoading(),
159 orientationCorrection(),
161 cropToMask(cropToMask),
165 pixelBuffers.push_back(pixelBuffer);
168 LoadingTask::~LoadingTask()
172 void LoadingTask::Process()
175 uint64_t mStartTimeNanoSceonds = 0;
176 uint64_t mEndTimeNanoSceonds = 0;
177 if(gTraceFilter && gTraceFilter->IsTraceEnabled())
179 mStartTimeNanoSceonds = GetNanoseconds();
180 std::ostringstream oss;
181 oss << "[u:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetEllipsedUrl()) << "]";
182 // DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
183 DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
200 if(gTraceFilter && gTraceFilter->IsTraceEnabled())
202 mEndTimeNanoSceonds = GetNanoseconds();
203 std::ostringstream oss;
204 oss << std::fixed << std::setprecision(3);
206 oss << "d:" << static_cast<float>(mEndTimeNanoSceonds - mStartTimeNanoSceonds) / 1000000.0f << "ms ";
207 oss << "m:" << isMaskTask << " ";
208 oss << "i:" << frameIndex << " ";
209 oss << "b:" << pixelBuffers.size() << " ";
210 if(!pixelBuffers.empty())
212 oss << "s:" << pixelBuffers[0].GetWidth() << "x" << pixelBuffers[0].GetHeight() << " ";
213 oss << "p:" << pixelBuffers[0].IsAlphaPreMultiplied() << " ";
215 oss << "u:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetEllipsedUrl()) << "]";
216 // DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
217 DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
222 bool LoadingTask::IsReady()
227 void LoadingTask::Load()
229 Devel::PixelBuffer pixelBuffer;
230 if(animatedImageLoading)
232 pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, dimensions, fittingMode, samplingMode);
234 else if(encodedImageBuffer)
236 pixelBuffer = Dali::LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), dimensions, fittingMode, samplingMode, orientationCorrection);
238 // We don't need to hold image buffer anymore.
239 encodedImageBuffer.Reset();
241 else if(url.IsValid() && url.IsLocalResource())
245 Dali::LoadImagePlanesFromFile(url.GetUrl(), pixelBuffers, dimensions, fittingMode, samplingMode, orientationCorrection);
249 pixelBuffer = Dali::LoadImageFromFile(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
252 else if(url.IsValid())
254 pixelBuffer = Dali::DownloadImageSynchronously(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
259 pixelBuffers.push_back(pixelBuffer);
262 if(pixelBuffers.empty())
264 DALI_LOG_ERROR("LoadingTask::Load: Loading is failed: %s\n", url.GetUrl().c_str());
268 void LoadingTask::ApplyMask()
270 if(!pixelBuffers.empty())
272 pixelBuffers[0].ApplyMask(maskPixelBuffer, contentScale, cropToMask);
276 void LoadingTask::MultiplyAlpha()
278 if(!pixelBuffers.empty() && Pixel::HasAlpha(pixelBuffers[0].GetPixelFormat()))
280 if(preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON)
282 pixelBuffers[0].MultiplyColorByAlpha();
287 void LoadingTask::SetTextureId(TextureManagerType::TextureId id)
292 } // namespace Internal
294 } // namespace Toolkit