2 * Copyright (c) 2023 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/fast-track-loading-task.h>
22 #include <dali/devel-api/adaptor-framework/image-loading.h>
23 #include <dali/devel-api/adaptor-framework/texture-upload-manager.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/integration-api/texture-integ.h>
26 #include <dali/integration-api/trace.h>
27 #include <dali/public-api/common/vector-wrapper.h>
41 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_IMAGE_PERFORMANCE_MARKER, false);
43 constexpr uint32_t CHROMINANCE_U_INDEX = 1u;
44 constexpr uint32_t CHROMINANCE_V_INDEX = 2u;
46 Dali::PixelData GetDummyChrominanceUPixelData()
48 static Dali::PixelData pixelDataU = PixelData::New(new uint8_t[2]{0x00, 0x00}, 2, 1, 2, Pixel::L8, PixelData::DELETE_ARRAY);
52 Dali::PixelData GetDummyChrominanceVPixelData()
54 static Dali::PixelData pixelDataV = PixelData::New(new uint8_t[2]{0x00, 0x00}, 2, 2, 1, Pixel::L8, PixelData::DELETE_ARRAY);
60 FastTrackLoadingTask::FastTrackLoadingTask(const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, bool loadPlanes, CallbackBase* callback)
61 : AsyncTask(MakeCallback(this, &FastTrackLoadingTask::OnComplete), url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
64 mDimensions(dimensions),
65 mFittingMode(fittingMode),
66 mSamplingMode(samplingMode),
67 mPreMultiplyOnLoad(preMultiplyOnLoad),
69 mTextureUploadManager(Dali::Devel::TextureUploadManager::Get()),
72 mOrientationCorrection(orientationCorrection),
74 mLoadPlanesAvaliable(loadPlanes),
75 mPremultiplied(false),
78 mCallback = std::unique_ptr<CallbackBase>(callback);
82 FastTrackLoadingTask::~FastTrackLoadingTask()
86 void FastTrackLoadingTask::PrepareTexture()
88 const uint32_t requiredTexturesCount = mLoadPlanesAvaliable ? 3u : 1u;
90 mTextures.resize(requiredTexturesCount);
91 mImageInformations.resize(requiredTexturesCount);
92 for(uint32_t index = 0u; index < requiredTexturesCount; ++index)
94 mTextures[index] = mTextureUploadManager.GenerateTexture2D();
96 mImageInformations[index].resourceId = Integration::GetTextureResourceId(mTextures[index]);
99 if(mLoadPlanesAvaliable)
101 // Create static dummy chrominance pixel data now, for thread safety.
102 [[maybe_unused]] auto pixelDataU = GetDummyChrominanceUPixelData();
103 [[maybe_unused]] auto pixelDataV = GetDummyChrominanceVPixelData();
107 void FastTrackLoadingTask::OnComplete(AsyncTaskPtr task)
111 for(uint32_t index = 0u; index < mImageInformations.size(); ++index)
113 Dali::Integration::SetTextureSize(mTextures[index], Dali::ImageDimensions(mImageInformations[index].width, mImageInformations[index].height));
114 Dali::Integration::SetTexturePixelFormat(mTextures[index], mImageInformations[index].format);
116 if(mLoadPlanesAvaliable && !mPlanesLoaded)
118 // We will not use ChrominanceU and ChrominanceV texture anymore.
119 mTextures.resize(1u);
129 CallbackBase::Execute(*mCallback, FastTrackLoadingTaskPtr(reinterpret_cast<FastTrackLoadingTask*>(task.Get())));
133 // Called by worker thread
135 void FastTrackLoadingTask::Process()
141 bool FastTrackLoadingTask::IsReady()
146 void FastTrackLoadingTask::Load()
149 if(gTraceFilter && gTraceFilter->IsTraceEnabled())
151 std::ostringstream oss;
152 oss << "[url:" << mUrl.GetUrl() << "]";
153 // DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK"); ///< TODO : Open it if we can control trace log level
154 DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_FAST_TRACK_UPLOADING_TASK %s", oss.str().c_str());
158 Devel::PixelBuffer pixelBuffer;
159 std::vector<Devel::PixelBuffer> pixelBuffers;
161 if(mUrl.IsValid() && mUrl.IsLocalResource())
163 if(mLoadPlanesAvaliable)
165 Dali::LoadImagePlanesFromFile(mUrl.GetUrl(), pixelBuffers, mDimensions, mFittingMode, mSamplingMode, mOrientationCorrection);
169 pixelBuffer = Dali::LoadImageFromFile(mUrl.GetUrl(), mDimensions, mFittingMode, mSamplingMode, mOrientationCorrection);
172 else if(mUrl.IsValid())
174 pixelBuffer = Dali::DownloadImageSynchronously(mUrl.GetUrl(), mDimensions, mFittingMode, mSamplingMode, mOrientationCorrection);
179 pixelBuffers.emplace_back(std::move(pixelBuffer));
182 if(pixelBuffers.empty())
184 mLoadSuccess = false;
185 DALI_LOG_ERROR("FastTrackLoadingTask::Load: Loading is failed: ResourceId : %d url : [%s]\n", mImageInformations[0u].resourceId, mUrl.GetUrl().c_str());
189 mPixelData.resize(pixelBuffers.size());
192 MultiplyAlpha(pixelBuffers[0]);
194 for(auto&& pixelBuffer : pixelBuffers)
196 mPixelData[index++] = Dali::Devel::PixelBuffer::Convert(pixelBuffer);
199 if(pixelBuffers.size() > 1u)
201 mPlanesLoaded = true;
203 else if(mLoadPlanesAvaliable && pixelBuffers.size() == 1u && mTextures.size() == 3u) ///< Case when we prepare three textures to render YUV, but loaded image is not YUV.
205 // Dummy pixel data for fake shader that we don't use actual YUV format.
206 // To fake shader, let we use indivisual sizes of texture for U and V.
207 mPixelData.resize(3u);
208 mPixelData[CHROMINANCE_U_INDEX] = GetDummyChrominanceUPixelData();
209 mPixelData[CHROMINANCE_V_INDEX] = GetDummyChrominanceVPixelData();
212 if(DALI_UNLIKELY(mPixelData.size() != mImageInformations.size()))
214 DALI_LOG_ERROR("FastTrackLoadingTask::Load: Undefined case. pixelBuffers.size() : %zu, image size : %zu, ResourceId : %d, url : [%s]\n", pixelBuffers.size(), mImageInformations.size(), mImageInformations[0u].resourceId, mUrl.GetUrl().c_str());
215 mLoadSuccess = false;
220 if(gTraceFilter && gTraceFilter->IsTraceEnabled())
222 std::ostringstream oss;
224 oss << "pixelBuffers:" << pixelBuffers.size() << " ";
225 if(!pixelBuffers.empty())
227 oss << "size:" << pixelBuffers[0].GetWidth() << "x" << pixelBuffers[0].GetHeight() << " ";
228 oss << "premult:" << mPremultiplied << " ";
230 oss << "url:" << mUrl.GetUrl() << "]";
231 // DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK"); ///< TODO : Open it if we can control trace log level
232 DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_FAST_TRACK_UPLOADING_TASK %s", oss.str().c_str());
237 void FastTrackLoadingTask::MultiplyAlpha(Dali::Devel::PixelBuffer pixelBuffer)
239 if(mPreMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON && Pixel::HasAlpha(pixelBuffer.GetPixelFormat()))
241 pixelBuffer.MultiplyColorByAlpha();
242 mPremultiplied = pixelBuffer.IsAlphaPreMultiplied();
246 void FastTrackLoadingTask::UploadToTexture()
250 DALI_ASSERT_DEBUG(mPixelData.size() == mImageInformations.size());
253 for(auto&& pixelData : mPixelData)
255 mImageInformations[index].width = pixelData.GetWidth();
256 mImageInformations[index].height = pixelData.GetHeight();
257 mImageInformations[index].format = pixelData.GetPixelFormat();
259 mTextureUploadManager.RequestUpload(mImageInformations[index].resourceId, pixelData);
270 } // namespace Internal
272 } // namespace Toolkit