diff --git a/frameworks/base/thread/background_task_executor.cpp b/frameworks/base/thread/background_task_executor.cpp index d47d026c412c0f06dad2479278fbe403f47b96d2..75927bf733c17d596bba025e9f80055b93827fee 100644 --- a/frameworks/base/thread/background_task_executor.cpp +++ b/frameworks/base/thread/background_task_executor.cpp @@ -73,7 +73,7 @@ BackgroundTaskExecutor::~BackgroundTaskExecutor() } } -bool BackgroundTaskExecutor::PostTask(Task&& task) +bool BackgroundTaskExecutor::PostTask(Task&& task, BgTaskPriority priority) { if (!task) { return false; @@ -83,12 +83,19 @@ bool BackgroundTaskExecutor::PostTask(Task&& task) if (!running_) { return false; } - tasks_.emplace_back(std::move(task)); + switch (priority) { + case BgTaskPriority::LOW: + lowPriorityTasks_.emplace_back(std::move(task)); + break; + default: + tasks_.emplace_back(std::move(task)); + break; + } condition_.notify_one(); return true; } -bool BackgroundTaskExecutor::PostTask(const Task& task) +bool BackgroundTaskExecutor::PostTask(const Task& task, BgTaskPriority priority) { if (!task) { return false; @@ -98,7 +105,14 @@ bool BackgroundTaskExecutor::PostTask(const Task& task) if (!running_) { return false; } - tasks_.emplace_back(task); + switch (priority) { + case BgTaskPriority::LOW: + lowPriorityTasks_.emplace_back(task); + break; + default: + tasks_.emplace_back(task); + break; + } condition_.notify_one(); return true; } @@ -150,7 +164,7 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo) const uint32_t purgeFlag = (1 << (threadNo - 1)); std::unique_lock lock(mutex_); while (running_) { - if (tasks_.empty()) { + if (tasks_.empty() && lowPriorityTasks_.empty()) { if ((purgeFlags_ & purgeFlag) != purgeFlag) { condition_.wait(lock); continue; @@ -163,9 +177,14 @@ void BackgroundTaskExecutor::ThreadLoop(uint32_t threadNo) purgeFlags_ &= ~purgeFlag; continue; } - - task = std::move(tasks_.front()); - tasks_.pop_front(); + // deal with tasks_ first. do lowPriorityTasks_ only when all tasks_ done. + if (!tasks_.empty()) { + task = std::move(tasks_.front()); + tasks_.pop_front(); + } else { + task = std::move(lowPriorityTasks_.front()); + lowPriorityTasks_.pop_front(); + } lock.unlock(); // Execute the task and clear after execution. diff --git a/frameworks/base/thread/background_task_executor.h b/frameworks/base/thread/background_task_executor.h index 52fd780fb67277557be8d13c5431044309c6c2cc..5547d3e4fd17d33ba645b31e0348129518090a1f 100644 --- a/frameworks/base/thread/background_task_executor.h +++ b/frameworks/base/thread/background_task_executor.h @@ -23,6 +23,11 @@ namespace OHOS::Ace { +enum class BgTaskPriority { + DEFAULT, + LOW, +}; + class BackgroundTaskExecutor { ACE_DISALLOW_COPY_AND_MOVE(BackgroundTaskExecutor); @@ -31,8 +36,8 @@ public: static BackgroundTaskExecutor& GetInstance(); - bool PostTask(Task&& task); - bool PostTask(const Task& task); + bool PostTask(Task&& task, BgTaskPriority priority = BgTaskPriority::DEFAULT); + bool PostTask(const Task& task, BgTaskPriority priority = BgTaskPriority::DEFAULT); void TriggerGarbageCollection(); @@ -46,6 +51,7 @@ private: std::mutex mutex_; std::condition_variable condition_; std::list tasks_; + std::list lowPriorityTasks_; std::list threads_; size_t currentThreadNum_ { 0 }; size_t maxThreadNum_ { 0 }; diff --git a/frameworks/core/image/image_loader.cpp b/frameworks/core/image/image_loader.cpp index 0989a4dfa40bc0e523d9c9c1df3374b5d1bd6246..427b41b6b5c93a1474f02779c342748337b41501 100644 --- a/frameworks/core/image/image_loader.cpp +++ b/frameworks/core/image/image_loader.cpp @@ -23,6 +23,7 @@ #include "base/network/download_manager.h" #include "base/resource/ace_res_config.h" #include "base/resource/asset_manager.h" +#include "base/thread/background_task_executor.h" #include "base/utils/string_utils.h" #include "core/common/ace_application_info.h" #include "core/common/ace_engine.h" @@ -53,16 +54,6 @@ char* realpath(const char* path, char* resolved_path) } // namespace -void ImageLoader::CacheResizedImage(const sk_sp& image, const std::string& key) -{ -#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM) - auto data = image->encodeToData(SkEncodedImageFormat::kPNG, 100); - if (data) { - ImageCache::WriteCacheFile(key, data->data(), data->size()); - } -#endif -} - std::string ImageLoader::RemovePathHead(const std::string& uri) { auto iter = uri.find_first_of(':'); @@ -164,7 +155,7 @@ sk_sp FileImageLoader::LoadImageData( .append(bundleName) .append("/files/") // infix of absolute path .append(filePath.substr(4)); // 4 is the length of "app/" from "internal://app/" - }\ + } if (filePath.length() > PATH_MAX) { LOGE("src path is too long"); return nullptr; @@ -207,8 +198,12 @@ sk_sp DataProviderImageLoader::LoadImageData( return nullptr; } auto imageData = dataRes->GetData(); - ImageCache::WriteCacheFile(src, imageData.data(), imageData.size()); - return SkData::MakeWithCopy(imageData.data(), imageData.size()); + sk_sp data = SkData::MakeWithCopy(imageData.data(), imageData.size()); + BackgroundTaskExecutor::GetInstance().PostTask( + [ src, imgData = std::move(imageData) ] () { + ImageCache::WriteCacheFile(src, imgData.data(), imgData.size()); + }, BgTaskPriority::LOW); + return data; } sk_sp AssetImageLoader::LoadImageData( @@ -295,17 +290,10 @@ sk_sp NetworkImageLoader::LoadImageData( } sk_sp data = SkData::MakeWithCopy(imageData.data(), imageData.size()); // 3. write it into file cache. - auto pipelineContext = context.Upgrade(); - if (!pipelineContext) { - LOGE("invalid pipeline context"); - return nullptr; - } - pipelineContext->GetTaskExecutor()->PostTask( + BackgroundTaskExecutor::GetInstance().PostTask( [ uri, imgData = std::move(imageData) ] () { ImageCache::WriteCacheFile(uri, imgData.data(), imgData.size()); - }, - TaskExecutor::TaskType::IO); - + }, BgTaskPriority::LOW); return data; } diff --git a/frameworks/core/image/image_loader.h b/frameworks/core/image/image_loader.h index 32b167939fcd4f2fc04161804601301ae28d4874..0b249de5092270c3d5e47c49c2acfa9a8d2cc32e 100644 --- a/frameworks/core/image/image_loader.h +++ b/frameworks/core/image/image_loader.h @@ -40,7 +40,6 @@ public: static std::string RemovePathHead(const std::string& uri); static RefPtr CreateImageLoader(const ImageSourceInfo& imageSourceInfo); - static void CacheResizedImage(const sk_sp& image, const std::string& key); static sk_sp LoadDataFromCachedFile(const std::string& uri); }; diff --git a/frameworks/core/image/image_provider.cpp b/frameworks/core/image/image_provider.cpp index d1be3ab3a39b9b8ef4eb34852068bad4669d18fa..b3b734d26ca55736a6ba01ef7ddf2b4afa201ab8 100644 --- a/frameworks/core/image/image_provider.cpp +++ b/frameworks/core/image/image_provider.cpp @@ -363,11 +363,16 @@ sk_sp ImageProvider::ApplySizeToSkImage( bool needCacheResizedImageFile = (1.0 * dstWidth * dstHeight) / (rawImage->width() * rawImage->height()) < RESIZE_MAX_PROPORTION; if (needCacheResizedImageFile && !srcKey.empty()) { - auto data = scaledImage->encodeToData(SkEncodedImageFormat::kPNG, 100); - if (data) { - LOGD("write cache file: %{private}s", srcKey.c_str()); - ImageCache::WriteCacheFile(srcKey, data->data(), data->size()); - } + BackgroundTaskExecutor::GetInstance().PostTask( + [ srcKey, scaledImage ] () { + LOGI("write png cache file: %{private}s", srcKey.c_str()); + auto data = scaledImage->encodeToData(SkEncodedImageFormat::kPNG, 100); + if (!data) { + LOGI("encode cache image into cache file failed."); + return; + } + ImageCache::WriteCacheFile(srcKey, data->data(), data->size()); + }, BgTaskPriority::LOW); } return scaledImage; }