diff --git a/bundle.json b/bundle.json index cbd905ec2ea2db2f0f916ccd8b92a86b0d028d0b..5a0e7e4cb1a91146393c169ac0a47fb0a8efd6cb 100644 --- a/bundle.json +++ b/bundle.json @@ -27,7 +27,8 @@ "sub_component": [ "//commonlibrary/memory_utils/libdmabufheap:libdmabufheap", "//commonlibrary/memory_utils/libpurgeablemem:libpurgeablemem", - "//commonlibrary/memory_utils/libpurgeablemem:purgeable_memory_ndk" + "//commonlibrary/memory_utils/libpurgeablemem:purgeable_memory_ndk", + "//commonlibrary/memory_utils/purgeable_builder:pixelmap_builder" ], "inner_kits": [ { @@ -53,6 +54,15 @@ ], "header_base": "//commonlibrary/memory_utils/libpurgeablemem/cpp/include" } + }, + { + "name": "//commonlibrary/memory_utils/purgeable_builder:pixelmap_builder", + "header": { + "header_files": [ + "purgeable_pixelmap_builder.h" + ], + "header_base": "//commonlibrary/memory_utils/purgeable_builder/include" + } } ], "test": [ diff --git a/libpurgeablemem/c/src/purgeable_mem_c.c b/libpurgeablemem/c/src/purgeable_mem_c.c index 3e36bb654d9294850bc720287745d059dcde572e..feb50a011bf4d61e9ab1aee08eb543484009ade8 100644 --- a/libpurgeablemem/c/src/purgeable_mem_c.c +++ b/libpurgeablemem/c/src/purgeable_mem_c.c @@ -56,7 +56,7 @@ static inline size_t RoundUp_(size_t val, size_t align) } static bool IsPurgMemPtrValid_(struct PurgMem *purgObj); -static bool IsPurged_(struct PurgMem *purgObj); +static bool IsPurged(struct PurgMem *purgObj); static struct PurgMem *PurgMemCreate_(size_t len, struct PurgMemBuilder *builder) { @@ -171,7 +171,7 @@ bool PurgMemDestroy(struct PurgMem *purgObj) err = PM_UNMAP_PURG_FAIL; } else { /* double check munmap result: if uxpte is set to no_present */ - if (UxpteIsEnabled() && !IsPurged_(purgObj)) { + if (UxpteIsEnabled() && !IsPurged(purgObj)) { PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: munmap dataPtr succ, but uxpte present", __func__); err = PM_UXPT_PRESENT_DATA_PURGED; } @@ -235,7 +235,7 @@ static PMState TryBeginRead_(struct PurgMem *purgObj) return PM_LOCK_READ_FAIL; } - if (!IsPurged_(purgObj)) { + if (!IsPurged(purgObj)) { PM_HILOG_INFO_C(LOG_CORE, "%{public}s: not purged, return true. MAP_PUG=0x%{public}x", __func__, MAP_PURGEABLE); return PM_DATA_NO_PURGED; @@ -259,7 +259,7 @@ static PMState BeginReadBuildData_(struct PurgMem *purgObj) return PM_LOCK_WRITE_FAIL; } - if (IsPurged_(purgObj)) { + if (IsPurged(purgObj)) { rebuildRet = PurgMemBuildData_(purgObj); PM_HILOG_ERROR_C(LOG_CORE, "%{public}s: purged, after built %{public}s", __func__, rebuildRet ? "succ" : "fail"); @@ -333,7 +333,7 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) goto uxpte_put; } - if (!IsPurged_(purgObj)) { + if (!IsPurged(purgObj)) { goto succ; } @@ -419,7 +419,7 @@ bool PurgMemAppendModify(struct PurgMem *purgObj, PurgMemModifyFunc func, void * return PurgMemBuilderAppendBuilder(purgObj->builder, builder); } -static bool IsPurged_(struct PurgMem *purgObj) +static bool IsPurged(struct PurgMem *purgObj) { /* first access, return true means purged */ if (purgObj->buildDataCount == 0) { diff --git a/libpurgeablemem/cpp/include/purgeable_ashmem.h b/libpurgeablemem/cpp/include/purgeable_ashmem.h index 8ccfcf421c161c1be48057a8950417c9c02e192e..42435d8fc0e796eddca8da3f3081316d402c97c7 100644 --- a/libpurgeablemem/cpp/include/purgeable_ashmem.h +++ b/libpurgeablemem/cpp/include/purgeable_ashmem.h @@ -50,17 +50,20 @@ public: ~PurgeableAshMem() override; int GetAshmemFd(); void ResizeData(size_t newSize) override; - void ChangeAshmemData(size_t size, int fd, void *data); + bool ChangeAshmemData(size_t size, int fd, void *data); + protected: int ashmemFd_; int isSupport_; + bool isChange_; ashmem_pin pin_ = { static_cast(0), static_cast(0) }; - bool Pin_() override; - bool Unpin_() override; - bool IsPurged_() override; + bool Pin() override; + bool Unpin() override; + bool IsPurged() override; + int GetPinStatus() const override; bool CreatePurgeableData_(); - void AfterRebuildSucc_() override; - std::string ToString_() const override; + void AfterRebuildSucc() override; + std::string ToString() const override; }; } /* namespace PurgeableMem */ } /* namespace OHOS */ diff --git a/libpurgeablemem/cpp/include/purgeable_mem.h b/libpurgeablemem/cpp/include/purgeable_mem.h index 474aa7c21c2eea31e8a420eb64e691e8cdcfcfb3..534edf0560596863ea0434b83cad6b8d68ad00a8 100644 --- a/libpurgeablemem/cpp/include/purgeable_mem.h +++ b/libpurgeablemem/cpp/include/purgeable_mem.h @@ -35,12 +35,13 @@ public: protected: std::unique_ptr pageTable_ = nullptr; - bool Pin_() override; - bool Unpin_() override; - bool IsPurged_() override; + bool Pin() override; + bool Unpin() override; + bool IsPurged() override; + int GetPinStatus() const override; bool CreatePurgeableData_(); - void AfterRebuildSucc_() override; - std::string ToString_() const override; + void AfterRebuildSucc() override; + std::string ToString() const override; }; } /* namespace PurgeableMem */ } /* namespace OHOS */ diff --git a/libpurgeablemem/cpp/include/purgeable_mem_base.h b/libpurgeablemem/cpp/include/purgeable_mem_base.h index caa36bc007c2732532bcaad29dc28551679030ab..5426df67c33a07884f83075f3c09a74f448061b1 100644 --- a/libpurgeablemem/cpp/include/purgeable_mem_base.h +++ b/libpurgeablemem/cpp/include/purgeable_mem_base.h @@ -90,7 +90,7 @@ public: * ResizeData: resize size of the PurgeableMem obj. */ virtual void ResizeData(size_t newSize); - + void SetRebuildSuccessCallback(std::function &callback); PurgeableMemBase(); virtual ~PurgeableMemBase(); @@ -107,11 +107,13 @@ protected: unsigned int buildDataCount_ = 0; bool BuildContent_(); bool IfNeedRebuild_(); - virtual bool Pin_(); - virtual bool Unpin_(); - virtual bool IsPurged_(); - virtual void AfterRebuildSucc_(); - virtual std::string ToString_() const; + virtual bool Pin(); + virtual bool Unpin(); + virtual bool IsPurged(); + virtual int GetPinStatus() const; + virtual void AfterRebuildSucc(); + virtual std::string ToString() const; + friend class LruCache; }; } /* namespace PurgeableMem */ } /* namespace OHOS */ diff --git a/libpurgeablemem/cpp/include/purgeable_mem_builder.h b/libpurgeablemem/cpp/include/purgeable_mem_builder.h index 9a3fbf004850e6f4c6936a30c1d49f7f2570851f..93b7e85f4f6b3739eea661873cb1c5ca3787d71f 100644 --- a/libpurgeablemem/cpp/include/purgeable_mem_builder.h +++ b/libpurgeablemem/cpp/include/purgeable_mem_builder.h @@ -17,6 +17,7 @@ #define OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_CPP_INCLUDE_PURGEABLE_MEM_BUILDER_H #include /* unique_ptr */ +#include namespace OHOS { namespace PurgeableMem { @@ -37,7 +38,20 @@ public: */ virtual bool Build(void *data, size_t size) = 0; + void SetRebuildSuccessCallback(std::function &callback) + { + rebuildSuccessCallback_ = callback; + } + + void DoRebuildSuccessCallback() + { + if (rebuildSuccessCallback_) { + rebuildSuccessCallback_(); + } + } + private: + std::function rebuildSuccessCallback_ = nullptr; std::unique_ptr nextBuilder_ = nullptr; /* Only called by its friend */ diff --git a/libpurgeablemem/cpp/src/purgeable_ashmem.cpp b/libpurgeablemem/cpp/src/purgeable_ashmem.cpp index 8462ce287dd9d5f4a28609a53e38ea861fe466b6..3ac9630f969db39f1262804c26f4d67563de2b50 100644 --- a/libpurgeablemem/cpp/src/purgeable_ashmem.cpp +++ b/libpurgeablemem/cpp/src/purgeable_ashmem.cpp @@ -44,9 +44,10 @@ PurgeableAshMem::PurgeableAshMem(std::unique_ptr builder) ashmemFd_ = -1; buildDataCount_ = 0; isSupport_ = false; + isChange_ = false; IF_NULL_LOG_ACTION(builder, "%{public}s: input builder nullptr", return); builder_ = std::move(builder); - PM_HILOG_DEBUG(LOG_CORE, "%{public}s init succ. %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s init succ. %{public}s", __func__, ToString().c_str()); } PurgeableAshMem::PurgeableAshMem(size_t dataSize, std::unique_ptr builder) @@ -56,6 +57,7 @@ PurgeableAshMem::PurgeableAshMem(size_t dataSize, std::unique_ptr CreatePurgeableData_(); builder_ = std::move(builder); - PM_HILOG_DEBUG(LOG_CORE, "%{public}s init succ. %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s init succ. %{public}s", __func__, ToString().c_str()); } PurgeableMem::~PurgeableMem() { - PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString().c_str()); if (dataPtr_) { if (munmap(dataPtr_, RoundUp_(dataSizeInput_, PAGE_SIZE)) != 0) { PM_HILOG_ERROR(LOG_CORE, "%{public}s: munmap dataPtr fail", __func__); } else { - if (UxpteIsEnabled() && !IsPurged_()) { + if (UxpteIsEnabled() && !IsPurged()) { PM_HILOG_ERROR(LOG_CORE, "%{public}s: munmap dataPtr succ, but uxpte present", __func__); } dataPtr_ = nullptr; @@ -72,7 +72,7 @@ PurgeableMem::~PurgeableMem() pageTable_.reset(); } -bool PurgeableMem::IsPurged_() +bool PurgeableMem::IsPurged() { IF_NULL_LOG_ACTION(pageTable_, "pageTable_ is nullptrin BeginWrite", return false); return !(pageTable_->CheckPresent((uint64_t)dataPtr_, dataSizeInput_)); @@ -97,24 +97,29 @@ bool PurgeableMem::CreatePurgeableData_() return true; } -bool PurgeableMem::Pin_() +bool PurgeableMem::Pin() { IF_NULL_LOG_ACTION(pageTable_, "pageTable_ is nullptrin BeginWrite", return false); pageTable_->GetUxpte((uint64_t)dataPtr_, dataSizeInput_); return true; } -bool PurgeableMem::Unpin_() +bool PurgeableMem::Unpin() { IF_NULL_LOG_ACTION(pageTable_, "pageTable_ is nullptrin BeginWrite", return false); pageTable_->PutUxpte((uint64_t)dataPtr_, dataSizeInput_); return true; } -void PurgeableMem::AfterRebuildSucc_() +void PurgeableMem::AfterRebuildSucc() { } +int PurgeableMem::GetPinStatus() const +{ + return 0; +} + void PurgeableMem::ResizeData(size_t newSize) { if (newSize <= 0) { @@ -131,7 +136,7 @@ void PurgeableMem::ResizeData(size_t newSize) CreatePurgeableData_(); } -inline std::string PurgeableMem::ToString_() const +inline std::string PurgeableMem::ToString() const { std::string dataptrStr = dataPtr_ ? std::to_string((unsigned long long)dataPtr_) : "0"; std::string pageTableStr = pageTable_ ? pageTable_->ToString() : "0"; diff --git a/libpurgeablemem/cpp/src/purgeable_mem_base.cpp b/libpurgeablemem/cpp/src/purgeable_mem_base.cpp index ead92454d0500a67bc81dfd7a7323183097c37ef..f4150dc36f32e379c68950da7a2ce6cc7e8f3456 100644 --- a/libpurgeablemem/cpp/src/purgeable_mem_base.cpp +++ b/libpurgeablemem/cpp/src/purgeable_mem_base.cpp @@ -50,10 +50,10 @@ bool PurgeableMemBase::BeginRead() bool succ = false; bool ret = false; - PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString().c_str()); IF_NULL_LOG_ACTION(dataPtr_, "dataPtr is nullptr in BeginRead", return false); IF_NULL_LOG_ACTION(builder_, "builder_ is nullptr in BeginRead", return false); - Pin_(); + Pin(); PMState err = PM_OK; while (true) { try { @@ -79,7 +79,7 @@ bool PurgeableMemBase::BeginRead() if (IfNeedRebuild_()) { succ = BuildContent_(); if (succ) { - AfterRebuildSucc_(); + AfterRebuildSucc(); } PM_HILOG_DEBUG(LOG_CORE, "%{public}s: purged, built %{public}s", __func__, succ ? "succ" : "fail"); } @@ -92,28 +92,28 @@ bool PurgeableMemBase::BeginRead() if (!ret) { PM_HILOG_ERROR(LOG_CORE, "%{public}s: err %{public}s, UxptePut.", __func__, GetPMStateName(err)); - Unpin_(); + Unpin(); } return ret; } void PurgeableMemBase::EndRead() { - PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString().c_str()); rwlock_.unlock_shared(); - Unpin_(); + Unpin(); } bool PurgeableMemBase::BeginWrite() { - PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString().c_str()); if (dataPtr_ == nullptr) { return false; } IF_NULL_LOG_ACTION(dataPtr_, "dataPtr is nullptr in BeginWrite", return false); IF_NULL_LOG_ACTION(builder_, "builder_ is nullptr in BeginWrite", return false); - Pin_(); + Pin(); PMState err = PM_OK; do { try { @@ -129,7 +129,7 @@ bool PurgeableMemBase::BeginWrite() /* data purged, rebuild it */ if (BuildContent_()) { /* data rebuild succ, return true */ - AfterRebuildSucc_(); + AfterRebuildSucc(); break; } err = PMB_BUILD_ALL_FAIL; @@ -141,15 +141,15 @@ bool PurgeableMemBase::BeginWrite() rwlock_.unlock(); PM_HILOG_ERROR(LOG_CORE, "%{public}s: err %{public}s, UxptePut.", __func__, GetPMStateName(err)); - Unpin_(); + Unpin(); return false; } void PurgeableMemBase::EndWrite() { - PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString_().c_str()); + PM_HILOG_DEBUG(LOG_CORE, "%{public}s %{public}s", __func__, ToString().c_str()); rwlock_.unlock(); - Unpin_(); + Unpin(); } bool PurgeableMemBase::ModifyContentByBuilder(std::unique_ptr modifier) @@ -170,13 +170,13 @@ bool PurgeableMemBase::ModifyContentByBuilder(std::unique_ptr &callback) +{ + if (builder_) { + builder_->SetRebuildSuccessCallback(callback); + } +} } /* namespace PurgeableMem */ } /* namespace OHOS */ diff --git a/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp b/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp index 7783ef0d3db4f832e6335fe2a5877d66019ee337..458a9136f47e0a61acfd9b3b5225f4e4f0a0fac1 100644 --- a/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp +++ b/libpurgeablemem/cpp/src/purgeable_resource_manager.cpp @@ -49,6 +49,10 @@ void LruCache::Insert(std::shared_ptr key) resourcePtrList_.emplace_front(key); positionMap_.emplace(key, resourcePtrList_.begin()); if (static_cast(resourcePtrList_.size()) > lruCacheCapacity_) { + auto popResource = resourcePtrList_.back(); + if (popResource->GetPinStatus() == 0) { + popResource->Pin(); + } positionMap_.erase(resourcePtrList_.back()); resourcePtrList_.pop_back(); } @@ -65,6 +69,10 @@ void LruCache::Erase(std::shared_ptr key) return; } + if (key->GetPinStatus() == 0) { + key->Pin(); + } + resourcePtrList_.erase(resourcePtrIter->second); positionMap_.erase(key); } @@ -240,7 +248,7 @@ void PurgeableResourceManager::ShowLruCache() const for (auto &resourcePtr : resourcePtrList) { cnt++; PM_HILOG_DEBUG(LOG_CORE, "[PurgeableResourceManager] ShowLruCache (resourcePtr: 0x%{public}lx, " - "%{public}zu th, list size: %{public}zu)", (long)resourcePtr.get(), cnt, lruCache_.Size()); + "%{public}d th, list size: %{public}zu)", (long)resourcePtr.get(), cnt, lruCache_.Size()); } } diff --git a/purgeable_builder/BUILD.gn b/purgeable_builder/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bde6d9243186ca992a542f5fd288ce495ad6add5 --- /dev/null +++ b/purgeable_builder/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//commonlibrary/memory_utils/purgeable_mem_config.gni") + +config("purgeable_builder_config") { + include_dirs = [ "include" ] + cflags_cc = [ "-fexceptions" ] +} + +ohos_shared_library("pixelmap_builder") { + sources = [] + include_dirs = [] + defines = [] + + if (purgeable_ashmem_enable) { + sources += [ "src/purgeable_pixelmap_builder.cpp" ] + include_dirs += [ "include/purgeable_pixelmap_builder.h" ] + defines += [ "IMAGE_PURGEABLE_PIXELMAP" ] + } + + external_deps = [ + "c_utils:utils", + "hitrace_native:hitrace_meter", + "hiviewdfx_hilog_native:libhilog", + "init:libbegetutil", + "memory_utils:libpurgeablemem", + "multimedia_image_framework:image", + "multimedia_image_framework:image_native", + ] + public_configs = [ ":purgeable_builder_config" ] + subsystem_name = "commonlibrary" + part_name = "memory_utils" +} diff --git a/purgeable_builder/include/purgeable_pixelmap_builder.h b/purgeable_builder/include/purgeable_pixelmap_builder.h new file mode 100644 index 0000000000000000000000000000000000000000..83aaba26b4f132dac6ddf5dcaa5990254391ba48 --- /dev/null +++ b/purgeable_builder/include/purgeable_pixelmap_builder.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_MEMORY_UTILS_PURGEABLE_PIXELMAP_BUILDER_H +#define OHOS_MEMORY_UTILS_PURGEABLE_PIXELMAP_BUILDER_H + +#include "image_source.h" +#include "image_type.h" +#include "pixel_map.h" + +#include "purgeable_ashmem.h" +#include "purgeable_mem_builder.h" +#include "purgeable_resource_manager.h" + +#include "memory.h" + +namespace OHOS { +namespace PurgeableBuilder { +using namespace OHOS::Media; + +class PurgeablePixelMapBuilder : public PurgeableMem::PurgeableMemBuilder { +public: + PurgeablePixelMapBuilder(uint32_t index, std::unique_ptr &imageSource, + DecodeOptions opts, PixelMap *pixelMap); + + bool Build(void *data, size_t size) override; + + ~PurgeablePixelMapBuilder() {} + +private: + uint32_t index_; + DecodeOptions opts_; + PixelMap *pixelMap_; + std::unique_ptr imageSource_; +}; // class PurgeablePixelMapBuilder + +bool GetSysForPurgeable(); +void SetBuilderToBePurgeable(std::unique_ptr &pixelMap, + std::unique_ptr &builder); +void RemoveFromPurgeableResourceMgr(std::shared_ptr &pixelMap); +void AddToPurgeableResourceMgr(std::unique_ptr &pixelMap); +bool MakePixelMapToBePurgeable(std::unique_ptr &pixelMap, + std::unique_ptr &backupImgSrc4Rebuild, DecodeOptions &decodeOpts); +} // namespace PurgeableBuilder +} // namespace OHOS +#endif /* OHOS_MEMORY_UTILS_PURGEABLE_PIXELMAP_BUILDER_H */ \ No newline at end of file diff --git a/purgeable_builder/src/purgeable_pixelmap_builder.cpp b/purgeable_builder/src/purgeable_pixelmap_builder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..503743ecad121d7e15b916de010379d88b774a81 --- /dev/null +++ b/purgeable_builder/src/purgeable_pixelmap_builder.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "purgeable_pixelmap_builder.h" + +#include "hitrace_meter.h" +#include "hilog/log.h" +#include "parameters.h" +#include "purgeable_ashmem.h" +#include "purgeable_mem_base.h" +#include "purgeable_mem_builder.h" +#include "purgeable_resource_manager.h" + +#ifndef _WIN32 +#include "securec.h" +#else +#include "memory.h" +#endif + +namespace OHOS { +namespace PurgeableBuilder { +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001799, "PurgeablePixelMapBuilder" }; + +PurgeablePixelMapBuilder::PurgeablePixelMapBuilder(uint32_t index, std::unique_ptr &imageSource, + DecodeOptions opts, PixelMap *pixelMap) + : index_(index), opts_(opts), pixelMap_(pixelMap), imageSource_(move(imageSource)) {} + +bool PurgeablePixelMapBuilder::Build(void *data, size_t size) +{ + HiviewDFX::HiLog::Debug(LABEL, "purgeableMem build in."); + uint32_t errorCode; + if (imageSource_ == nullptr) { + return false; + } + + StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::PixelMapPurgeableMemBuilder::Build"); + std::unique_ptr pixelMap = imageSource_->CreatePixelMap(index_, opts_, errorCode); + if (pixelMap == nullptr || pixelMap_ == nullptr) { + FinishTrace(HITRACE_TAG_ZIMAGE); + return false; + } + + StartTrace(HITRACE_TAG_ZIMAGE, ("OHOS::PurgeableBuilder::PixelMapPurgeableMemBuilder::CopyData " + + std::to_string(size))); + memcpy_s((char *)pixelMap_->GetPixels(), size, (char *)pixelMap->GetPixels(), size); + + DoRebuildSuccessCallback(); + + FinishTrace(HITRACE_TAG_ZIMAGE); // memcpy_s trace + FinishTrace(HITRACE_TAG_ZIMAGE); // PixelMapPurgeableMemBuilder::Build trace + + return true; +} + +bool GetSysForPurgeable() +{ + return system::GetBoolParameter("persist.memmgr.purgeable.enable", false); +} + +void SetBuilderToBePurgeable(std::unique_ptr &pixelMap, + std::unique_ptr &builder) +{ + HiviewDFX::HiLog::Debug(LABEL, "set builder for purgeable pixelmap. allocatorType = %{public}d.", + pixelMap->GetAllocatorType()); + StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::SetBuilderToBePurgeable"); + if (builder == nullptr) { + FinishTrace(HITRACE_TAG_ZIMAGE); + return; + } + + if (pixelMap->GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) { + std::shared_ptr tmpPtr = + std::make_shared(std::move(builder)); + bool isChanged = tmpPtr->ChangeAshmemData(pixelMap->GetCapacity(), + *(static_cast(pixelMap->GetFd())), pixelMap->GetWritablePixels()); + if (isChanged) { + pixelMap->SetPurgeableMemPtr(tmpPtr); + pixelMap->GetPurgeableMemPtr()->BeginRead(); + } else { + HiviewDFX::HiLog::Error(LABEL, "ChangeAshmemData fail."); + } + } + + FinishTrace(HITRACE_TAG_ZIMAGE); +} + +void RemoveFromPurgeableResourceMgr(std::shared_ptr &pixelMap) +{ + StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::RemoveFromPurgeableResourceMgr"); + HiviewDFX::HiLog::Debug(LABEL, "remove pixelmap from PurgeableResourceMgr."); + + if (pixelMap->IsPurgeable()) { + PurgeableMem::PurgeableResourceManager::GetInstance().RemoveResource(pixelMap->GetPurgeableMemPtr()); + } + + FinishTrace(HITRACE_TAG_ZIMAGE); +} + +void AddToPurgeableResourceMgr(std::unique_ptr &pixelMap) +{ + StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::AddToPurgeableResourceMgr"); + HiviewDFX::HiLog::Debug(LABEL, "add pixelmap purgeablemem ptr to PurgeableResourceMgr"); + + if (pixelMap->IsPurgeable()) { + PurgeableMem::PurgeableResourceManager::GetInstance().AddResource(pixelMap->GetPurgeableMemPtr()); + } + + FinishTrace(HITRACE_TAG_ZIMAGE); +} + +bool MakePixelMapToBePurgeable(std::unique_ptr &pixelMap, std::unique_ptr &backupImgSrc4Rebuild, + DecodeOptions &decodeOpts) +{ + StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::MakePixelMapToBePurgeable"); + HiviewDFX::HiLog::Debug(LABEL, "MakePixelMapToBePurgeable in."); + + if (!GetSysForPurgeable()) { + return false; + } + + if (pixelMap == nullptr || backupImgSrc4Rebuild == nullptr) { + HiviewDFX::HiLog::Error(LABEL, "PixelMap or backupImgSrc4Rebuild is null."); + return false; + } + + if (pixelMap->IsPurgeable()) { + HiviewDFX::HiLog::Error(LABEL, "PixelMap is already purgeable."); + return false; + } + + std::unique_ptr purgeableMemBuilder = + std::make_unique(0, backupImgSrc4Rebuild, decodeOpts, pixelMap.get()); + SetBuilderToBePurgeable(pixelMap, purgeableMemBuilder); + + if (pixelMap->IsPurgeable()) { + AddToPurgeableResourceMgr(pixelMap); + } + + FinishTrace(HITRACE_TAG_ZIMAGE); + return true; +} +} // namespace PurgeableBuilder +} // namespace OHOS \ No newline at end of file diff --git a/purgeable_mem_config.gni b/purgeable_mem_config.gni index 388025da8b3bcee71c4b263b98a5b0f286c0d603..bb872155dba79dd0e81c76aaa578a5cc31ca5d91 100644 --- a/purgeable_mem_config.gni +++ b/purgeable_mem_config.gni @@ -9,7 +9,7 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. declare_args() { purgeable_ashmem_enable = false