From 960f7b7eb0d1530ac060619365cc80b70ef05437 Mon Sep 17 00:00:00 2001 From: x00678224 Date: Sat, 20 May 2023 17:43:35 +0800 Subject: [PATCH] 0520 make pixelmap purgeable Signed-off-by: x00678224 Change-Id: Ice067a1e4ac2f02abb9f62e68b1e8b7318c665b3 --- frameworks/core/components_ng/components.gni | 10 +++ .../pattern/image/image_pattern.cpp | 87 +++++++++++++++++++ .../pattern/image/image_pattern.h | 7 ++ 3 files changed, 104 insertions(+) diff --git a/frameworks/core/components_ng/components.gni b/frameworks/core/components_ng/components.gni index 0abbc774245..15a44ad15f7 100644 --- a/frameworks/core/components_ng/components.gni +++ b/frameworks/core/components_ng/components.gni @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//commonlibrary/memory_utils/purgeable_mem_config.gni") import("//foundation/arkui/ace_engine/ace_config.gni") import("../../../build/uicast.gni") @@ -128,6 +129,15 @@ template("build_component_ng") { } } + if (purgeable_ashmem_enable) { + defines += [ "IMAGE_PURGEABLE_PIXELMAP" ] + if (defined(external_deps)) { + external_deps += [ "memory_utils:libpurgeablemem" ] + } else { + external_deps = [ "memory_utils:libpurgeablemem" ] + } + } + if (defined(config.model_component_support) && config.model_component_support) { include_dirs += [ diff --git a/frameworks/core/components_ng/pattern/image/image_pattern.cpp b/frameworks/core/components_ng/pattern/image/image_pattern.cpp index 405c3e944a4..f9722a60594 100644 --- a/frameworks/core/components_ng/pattern/image/image_pattern.cpp +++ b/frameworks/core/components_ng/pattern/image/image_pattern.cpp @@ -37,6 +37,12 @@ #include "core/common/ace_engine_ext.h" #endif +#ifdef IMAGE_PURGEABLE_PIXELMAP +#include "base/log/ace_trace.h" +#include "core/components_ng/image_provider/image_utils.h" +#include "foundation/multimedia/image_framework/interfaces/innerkits/include/pixel_map.h" +#endif + namespace OHOS::Ace::NG { DataReadyNotifyTask ImagePattern::CreateDataReadyCallback() @@ -92,6 +98,81 @@ LoadFailNotifyTask ImagePattern::CreateLoadFailCallback() }; } +#ifdef IMAGE_PURGEABLE_PIXELMAP +void ImagePattern::OnPurgeableResRebuildSuccess() +{ + ACE_SCOPED_TRACE("PurgeableImagePattern::%s", __func__); + auto task = [weak = WeakClaim(this)]() { + AceTraceBeginWithArgs("PurgeableImagePattern::task running."); + auto pattern = weak.Upgrade(); + pattern->OnPurgeableResRebuildSuccessUI(); + AceTraceEnd(); + }; + + AceTraceBeginWithArgs("PurgeableImagePattern::call PostToUI."); + ImageUtils::PostToUI(std::move(task)); + AceTraceEnd(); +} + +void ImagePattern::OnPurgeableResRebuildSuccessUI() +{ + ACE_SCOPED_TRACE("PurgeableImagePattern::%s", __func__); + auto host = GetHost(); + CHECK_NULL_VOID(host); + AceTraceBeginWithArgs("PurgeableImagePattern::call MarkNeedRenderOnly."); + host->MarkNeedRenderOnly(); + AceTraceEnd(); +} + +void ImagePattern::LoadPurgeableDataIfNeed() +{ + ACE_SCOPED_TRACE("PurgeableImagePattern::%s", __func__); + auto imageLayoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(imageLayoutProperty); + auto imageRenderProperty = GetPaintProperty(); + CHECK_NULL_VOID(imageRenderProperty); + auto src = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo("")); + UpdateInternalResource(src); + + if (loadingCtx_) { + std::string srcStr = src.GetSrc(); + if (srcStr.find("file://media/image") != std::string::npos && srcStr.find("thumbnail") != std::string::npos) { + if (image_ && image_->GetPixelMap()) { + std::shared_ptr mediaPixelMap = image_->GetPixelMap()->GetPixelMapSharedPtr(); + if (mediaPixelMap) { + bool purgeable = mediaPixelMap->IsPurgeable(); + if (purgeable) { + ImageUtils::PostToBg([mediaPixelMap, this] { + AceTraceBeginWithArgs("PurgeableImagePattern::bgtask running."); + if (mediaPixelMap) + mediaPixelMap->SetPurgeableResRebuildCallback(std::bind(&ImagePattern::OnPurgeableResRebuildSuccess, this)); + if (mediaPixelMap) + mediaPixelMap->VisitPurgeableMemForImageCallback(); + AceTraceEnd(); + }); + } + } + } + } + } +} + +void ImagePattern::RemovePurgeableDataIfNeed() +{ + ACE_SCOPED_TRACE("PurgeableImagePattern::%s", __func__); + if (image_ && image_->GetPixelMap()) { + std::shared_ptr mediaPixelMap = image_->GetPixelMap()->GetPixelMapSharedPtr(); + if (mediaPixelMap) { + bool purgeable = mediaPixelMap->IsPurgeable(); + if (purgeable) { + AceTraceBeginWithArgs("PurgeableImagePattern::end visit and remove purgeable resource."); + mediaPixelMap->EndVisitAndRemovePurgeableResource(); + } + } + } +} +#endif + void ImagePattern::PrepareAnimation() { if (image_->IsStatic()) { @@ -401,12 +482,18 @@ void ImagePattern::OnNotifyMemoryLevel(int32_t level) void ImagePattern::OnWindowHide() { isShow_ = false; +#ifdef IMAGE_PURGEABLE_PIXELMAP + RemovePurgeableDataIfNeed(); +#endif } void ImagePattern::OnWindowShow() { isShow_ = true; LoadImageDataIfNeed(); +#ifdef IMAGE_PURGEABLE_PIXELMAP + LoadPurgeableDataIfNeed(); +#endif } void ImagePattern::OnVisibleChange(bool visible) diff --git a/frameworks/core/components_ng/pattern/image/image_pattern.h b/frameworks/core/components_ng/pattern/image/image_pattern.h index ea81d487c31..b471a57697d 100644 --- a/frameworks/core/components_ng/pattern/image/image_pattern.h +++ b/frameworks/core/components_ng/pattern/image/image_pattern.h @@ -103,6 +103,13 @@ private: void OnImageDataReady(); void OnImageLoadFail(); void OnImageLoadSuccess(); +#ifdef IMAGE_PURGEABLE_PIXELMAP + void OnPurgeableResRebuildSuccess(); + void OnPurgeableResRebuildSuccessUI(); + void LoadPurgeableDataIfNeed(); + void RemovePurgeableDataIfNeed(); +#endif + void SetImagePaintConfig( const RefPtr& canvasImage, const RectF& srcRect, const RectF& dstRect, bool isSvg); void UpdateInternalResource(ImageSourceInfo& sourceInfo); -- Gitee