From a77dc37db755fe358727d039c4e9537a7573237e Mon Sep 17 00:00:00 2001 From: xiexiyun Date: Wed, 25 Oct 2023 17:24:20 +0800 Subject: [PATCH] network image cache Signed-off-by: xiexiyun Change-Id: I2671257275811249e33b6436dbfa22c1cd3e9d34 --- .../image_provider/image_loading_context.cpp | 72 +++++++++++++++++++ .../image_provider/image_loading_context.h | 1 + .../image_provider/image_provider.cpp | 13 ++-- .../image_provider/image_provider.h | 2 + .../mock/image_provider/mock_image_loader.cpp | 3 + frameworks/core/image/image_loader.cpp | 15 ++-- frameworks/core/image/image_loader.h | 2 + 7 files changed, 97 insertions(+), 11 deletions(-) diff --git a/frameworks/core/components_ng/image_provider/image_loading_context.cpp b/frameworks/core/components_ng/image_provider/image_loading_context.cpp index 35c1a2df678..eab655e44b5 100644 --- a/frameworks/core/components_ng/image_provider/image_loading_context.cpp +++ b/frameworks/core/components_ng/image_provider/image_loading_context.cpp @@ -15,6 +15,7 @@ #include "core/components_ng/image_provider/image_loading_context.h" +#include "base/thread/background_task_executor.h" #include "base/utils/utils.h" #include "core/common/container.h" #include "core/components_ng/image_provider/image_state_manager.h" @@ -22,11 +23,46 @@ #include "core/components_ng/image_provider/pixel_map_image_object.h" #include "core/components_ng/image_provider/static_image_object.h" #include "core/components_ng/render/image_painter.h" +#include "core/image/image_file_cache.h" #include "core/image/image_loader.h" #include "core/pipeline_ng/pipeline_context.h" namespace OHOS::Ace::NG { +namespace { +RefPtr QueryDataFromCache(const ImageSourceInfo& src, bool& dataHit) +{ + ACE_FUNCTION_TRACE(); +#ifndef USE_ROSEN_DRAWING + auto cachedData = ImageLoader::QueryImageDataFromImageCache(src); + if (cachedData) { + dataHit = true; + return NG::ImageData::MakeFromDataWrapper(&cachedData); + } + auto skData = ImageLoader::LoadDataFromCachedFile(src.GetSrc()); + if (skData) { + sk_sp data = SkData::MakeWithCopy(skData->data(), skData->size()); + + return NG::ImageData::MakeFromDataWrapper(&data); + } +#else + std::shared_ptr rsData = nullptr; + rsData = ImageLoader::QueryImageDataFromImageCache(src); + if (rsData) { + dataHit = true; + return NG::ImageData::MakeFromDataWrapper(reinterpret_cast(&rsData)); + } + auto drawingData = ImageLoader::LoadDataFromCachedFile(src.GetSrc()); + if (drawingData) { + auto data = std::make_shared(); + data->BuildWithCopy(drawingData->data(), drawingData->size()); + return NG::ImageData::MakeFromDataWrapper(reinterpret_cast(&data)); + } +#endif + return nullptr; +} +} // namespace + ImageLoadingContext::ImageLoadingContext(const ImageSourceInfo& src, LoadNotifier&& loadNotifier, bool syncLoad) : src_(src), notifiers_(std::move(loadNotifier)), syncLoad_(syncLoad) { @@ -118,16 +154,52 @@ void ImageLoadingContext::OnDataLoading() ImageProvider::CreateImageObject(src_, WeakClaim(this), syncLoad_); } +bool ImageLoadingContext::NotifyReadyIfCacheHit() +{ + bool dataHit = false; + auto cachedImageData = QueryDataFromCache(src_, dataHit); + CHECK_NULL_RETURN(cachedImageData, false); + auto notifyDataReadyTask = [weak = AceType::WeakClaim(this), data = std::move(cachedImageData), dataHit] { + auto ctx = weak.Upgrade(); + CHECK_NULL_VOID(ctx); + auto src = ctx->GetSourceInfo(); + // if find data or file cache only, build and cache object, cache data if file cache hit + RefPtr imageObj = ImageProvider::BuildImageObject(src, data); + ImageProvider::CacheImageObject(imageObj); + if (!dataHit) { + ImageLoader::CacheImageData(ctx->GetSourceInfo().GetKey(), data); + } + ctx->DataReadyCallback(imageObj); + }; + if (syncLoad_) { + notifyDataReadyTask(); + } else { + ImageUtils::PostToUI(std::move(notifyDataReadyTask)); + } + return true; +} + void ImageLoadingContext::DownloadImage() { auto pipeline = PipelineBase::GetCurrentContext(); CHECK_NULL_VOID(pipeline); DownloadCallback downloadCallback; + if (NotifyReadyIfCacheHit()) { + return; + } downloadCallback.successCallback = [weak = AceType::WeakClaim(this)](const std::vector& imageData) { auto ctx = weak.Upgrade(); CHECK_NULL_VOID(ctx); auto data = ImageData::MakeFromDataWithCopy(imageData.data(), imageData.size()); + // if downloading is necessary, cache object, data to file RefPtr imageObj = ImageProvider::BuildImageObject(ctx->GetSourceInfo(), data); + if (!imageObj) { + ctx->FailCallback("ImageObject null"); + return; + } + ImageProvider::CacheImageObject(imageObj); + ImageLoader::CacheImageData(ctx->GetSourceInfo().GetKey(), data); + ImageLoader::WriteCacheToFile(ctx->GetSourceInfo().GetSrc(), imageData); ctx->DataReadyCallback(imageObj); }; downloadCallback.failCallback = [weak = AceType::WeakClaim(this)](std::string errorMsg) { diff --git a/frameworks/core/components_ng/image_provider/image_loading_context.h b/frameworks/core/components_ng/image_provider/image_loading_context.h index 9848c50451d..8599a2a0081 100644 --- a/frameworks/core/components_ng/image_provider/image_loading_context.h +++ b/frameworks/core/components_ng/image_provider/image_loading_context.h @@ -90,6 +90,7 @@ private: void OnLoadSuccess(); void OnLoadFail(); void DownloadImage(); + bool NotifyReadyIfCacheHit(); // round up int to the nearest 2-fold proportion of image width // REQUIRE: value > 0, image width > 0 diff --git a/frameworks/core/components_ng/image_provider/image_provider.cpp b/frameworks/core/components_ng/image_provider/image_provider.cpp index 495b72798b1..e4bb27c156f 100644 --- a/frameworks/core/components_ng/image_provider/image_provider.cpp +++ b/frameworks/core/components_ng/image_provider/image_provider.cpp @@ -44,10 +44,9 @@ namespace OHOS::Ace::NG { -namespace { - -void CacheImageObject(const RefPtr& obj) +void ImageProvider::CacheImageObject(const RefPtr& obj) { + CHECK_NULL_VOID(obj); auto pipelineCtx = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipelineCtx); auto cache = pipelineCtx->GetImageCache(); @@ -56,7 +55,6 @@ void CacheImageObject(const RefPtr& obj) cache->CacheImgObjNG(obj->GetSourceInfo().GetKey(), obj); } } -} // namespace std::mutex ImageProvider::taskMtx_; std::unordered_map ImageProvider::tasks_; @@ -293,8 +291,11 @@ RefPtr ImageProvider::BuildImageObject(const ImageSourceInfo& src, CHECK_NULL_RETURN(rosenImageData, nullptr); auto [size, frameCount] = rosenImageData->Parse(); #endif - CHECK_NULL_RETURN(size.IsPositive(), nullptr); - + if (!size.IsPositive()) { + TAG_LOGW(AceLogTag::ACE_IMAGE, "Image of src: %{public}s decode failed, size is invalid %{public}s", + src.ToString().c_str(), size.ToString().c_str()); + return nullptr; + } if (frameCount > 1) { return MakeRefPtr(src, size, data); } diff --git a/frameworks/core/components_ng/image_provider/image_provider.h b/frameworks/core/components_ng/image_provider/image_provider.h index b70cf8b9175..cbed3a9e684 100644 --- a/frameworks/core/components_ng/image_provider/image_provider.h +++ b/frameworks/core/components_ng/image_provider/image_provider.h @@ -85,6 +85,8 @@ public: static RefPtr BuildImageObject(const ImageSourceInfo& src, const RefPtr& data); + static void CacheImageObject(const RefPtr& obj); + private: /** Check if task is already running and register task in the task map, * making sure the same task runs only once (CreateImageObject with same diff --git a/frameworks/core/components_ng/test/mock/image_provider/mock_image_loader.cpp b/frameworks/core/components_ng/test/mock/image_provider/mock_image_loader.cpp index 47bc463762a..5312b15a652 100644 --- a/frameworks/core/components_ng/test/mock/image_provider/mock_image_loader.cpp +++ b/frameworks/core/components_ng/test/mock/image_provider/mock_image_loader.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "mock_image_loader.h" + #include #include "core/image/image_loader.h" @@ -62,4 +63,6 @@ bool NetworkImageLoader::DownloadImage(DownloadCallback&& downloadCallback, cons { return false; } + +void ImageLoader::WriteCacheToFile(const std::string& uri, const std::vector& imageData) {} } // namespace OHOS::Ace diff --git a/frameworks/core/image/image_loader.cpp b/frameworks/core/image/image_loader.cpp index f1b673e2aff..d9e907a5f42 100644 --- a/frameworks/core/image/image_loader.cpp +++ b/frameworks/core/image/image_loader.cpp @@ -481,11 +481,7 @@ std::shared_ptr NetworkImageLoader::LoadImageData( data->BuildWithCopy(imageData.data(), imageData.size()); #endif // 3. write it into file cache. - BackgroundTaskExecutor::GetInstance().PostTask( - [uri, imgData = std::move(imageData)]() { - ImageFileCache::GetInstance().WriteCacheFile(uri, imgData.data(), imgData.size()); - }, - BgTaskPriority::LOW); + WriteCacheToFile(uri, imageData); return data; } @@ -806,4 +802,13 @@ void SharedMemoryImageLoader::UpdateData(const std::string& uri, const std::vect cv_.notify_one(); } +void ImageLoader::WriteCacheToFile(const std::string& uri, const std::vector& imageData) +{ + BackgroundTaskExecutor::GetInstance().PostTask( + [uri, imgData = std::move(imageData)]() { + ImageFileCache::GetInstance().WriteCacheFile(uri, imgData.data(), imgData.size()); + }, + BgTaskPriority::LOW); +} + } // namespace OHOS::Ace diff --git a/frameworks/core/image/image_loader.h b/frameworks/core/image/image_loader.h index c2f321bf64e..5dd0571f7ac 100644 --- a/frameworks/core/image/image_loader.h +++ b/frameworks/core/image/image_loader.h @@ -70,6 +70,8 @@ public: #endif static void CacheImageData(const std::string& key, const RefPtr& data); static RefPtr LoadImageDataFromFileCache(const std::string& key, const std::string& suffix); + + static void WriteCacheToFile(const std::string& uri, const std::vector& imageData); }; // File image provider: read image from file. -- Gitee