diff --git a/frameworks/core/components_ng/components.gni b/frameworks/core/components_ng/components.gni index 0abbc774245a0c26be3b6f87d7ba0f0e67e27a49..15a44ad15f7ad62c7f2c616c4830acc12568f142 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 405c3e944a4276ba89cfbcc5956245855f09b6af..f9722a605944fb888c4b31d1c61619228349cb12 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 ea81d487c31ea246bdc15cbaf9981ae0853c8ec7..b471a57697d36b96599a4bc3b29588cad65814f6 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);