From d32113a96f359a8e5a78b1e8ee3d32513a94d223 Mon Sep 17 00:00:00 2001 From: sf2020 Date: Thu, 10 Oct 2024 12:51:04 +0800 Subject: [PATCH] optimize for rs memory of pixelmap Change-Id: Ib97f47a89c36db381d372c0ed7853c118f78747b Signed-off-by: sf2020 --- .../innerkitsimpl/common/src/pixel_map.cpp | 124 ++++++++++++++---- interfaces/innerkits/include/pixel_map.h | 45 ++++++- 2 files changed, 139 insertions(+), 30 deletions(-) diff --git a/frameworks/innerkitsimpl/common/src/pixel_map.cpp b/frameworks/innerkitsimpl/common/src/pixel_map.cpp index 731a81357..8c64bee18 100644 --- a/frameworks/innerkitsimpl/common/src/pixel_map.cpp +++ b/frameworks/innerkitsimpl/common/src/pixel_map.cpp @@ -137,7 +137,7 @@ void PixelMap::FreePixelMap() __attribute__((no_sanitize("cfi"))) } #endif - if (data_ == nullptr) { + if (!isUnMap_ && data_ == nullptr) { return; } @@ -184,7 +184,7 @@ void PixelMap::ReleaseSharedMemory(void *addr, void *context, uint32_t size) { #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM) int *fd = static_cast(context); - if (addr != nullptr) { + if (!isUnMap_ && addr != nullptr) { ::munmap(addr, size); } if (fd != nullptr) { @@ -215,6 +215,8 @@ void PixelMap::SetPixelsAddr(void *addr, void *context, uint32_t size, Allocator IMAGE_LOGE("SetPixelsAddr error type %{public}d ", type); } data_ = static_cast(addr); + isUnMap_ = false; + unMapCount_ = 0; context_ = context; pixelsSize_ = size; allocatorType_ = type; @@ -1479,8 +1481,8 @@ uint8_t PixelMap::GetARGB32ColorB(uint32_t color) bool PixelMap::IsSameImage(const PixelMap &other) { - if (data_ == nullptr || other.data_ == nullptr) { - IMAGE_LOGE("IsSameImage data_ is nullptr."); + if (isUnMap_ || data_ == nullptr || other.data_ == nullptr) { + IMAGE_LOGE("IsSameImage data_ is nullptr, isUnMap %{public}d.", isUnMap_); return false; } if (imageInfo_.size.width != other.imageInfo_.size.width || @@ -1504,8 +1506,8 @@ uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, uint8_t *dst) IMAGE_LOGE("read pixels by buffer input dst address is null."); return ERR_IMAGE_READ_PIXELMAP_FAILED; } - if (data_ == nullptr) { - IMAGE_LOGE("read pixels by buffer current PixelMap data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("read pixels by buffer current PixelMap data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_READ_PIXELMAP_FAILED; } if (bufferSize < static_cast(pixelsSize_)) { @@ -1555,8 +1557,8 @@ uint32_t PixelMap::ReadARGBPixels(const uint64_t &bufferSize, uint8_t *dst) IMAGE_LOGE("Read ARGB pixels: input dst address is null."); return ERR_IMAGE_INVALID_PARAMETER; } - if (data_ == nullptr) { - IMAGE_LOGE("Read ARGB pixels: current PixelMap data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("Read ARGB pixels: current PixelMap data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_READ_PIXELMAP_FAILED; } if (!IsSupportConvertToARGB(imageInfo_.pixelFormat)) { @@ -1649,8 +1651,8 @@ uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, const uint32_t &offset IMAGE_LOGE("read pixels by rect input parameter fail."); return ERR_IMAGE_INVALID_PARAMETER; } - if (data_ == nullptr) { - IMAGE_LOGE("read pixels by rect this pixel data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("read pixels by rect this pixel data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_READ_PIXELMAP_FAILED; } ImageInfo dstImageInfo = @@ -1670,8 +1672,8 @@ uint32_t PixelMap::ReadPixel(const Position &pos, uint32_t &dst) IMAGE_LOGE("read pixel by pos input invalid exception. [x(%{public}d), y(%{public}d)]", pos.x, pos.y); return ERR_IMAGE_INVALID_PARAMETER; } - if (data_ == nullptr) { - IMAGE_LOGE("read pixel by pos source data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("read pixel by pos source data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_READ_PIXELMAP_FAILED; } ImageInfo dstImageInfo = @@ -1751,8 +1753,8 @@ uint32_t PixelMap::WritePixel(const Position &pos, const uint32_t &color) IMAGE_LOGE("write pixel by pos current pixelmap image info is invalid."); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } - if (data_ == nullptr) { - IMAGE_LOGE("write pixel by pos but current pixelmap data is nullptr."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("write pixel by pos but current pixelmap data is nullptr, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } ImageInfo srcImageInfo = @@ -1783,8 +1785,8 @@ uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize IMAGE_LOGE("write pixel by rect current pixelmap image info is invalid."); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } - if (data_ == nullptr) { - IMAGE_LOGE("write pixel by rect current pixel map data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("write pixel by rect current pixel map data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } uint32_t bytesPerPixel = ImageUtils::GetPixelBytes(imageInfo_.pixelFormat); @@ -1820,8 +1822,8 @@ uint32_t PixelMap::WritePixels(const uint8_t *source, const uint64_t &bufferSize IMAGE_LOGE("write pixels by buffer current pixelmap image info is invalid."); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } - if (data_ == nullptr) { - IMAGE_LOGE("write pixels by buffer current pixelmap data is nullptr."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("write pixels by buffer current pixelmap data is nullptr, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_WRITE_PIXELMAP_FAILED; } @@ -1863,8 +1865,8 @@ bool PixelMap::WritePixels(const uint32_t &color) IMAGE_LOGE("erase pixels by color current pixelmap image info is invalid."); return false; } - if (data_ == nullptr) { - IMAGE_LOGE("erase pixels by color current pixel map data is null."); + if (isUnMap_ || data_ == nullptr) { + IMAGE_LOGE("erase pixels by color current pixel map data is null, %{public}d.", isUnMap_); return false; } ImageInfo srcInfo = @@ -1982,8 +1984,8 @@ bool PixelMap::WriteAshmemDataToParcel(Parcel &parcel, size_t size) const bool PixelMap::WriteImageData(Parcel &parcel, size_t size) const { const uint8_t *data = data_; - if (data == nullptr || size > MAX_IMAGEDATA_SIZE) { - IMAGE_LOGE("WriteImageData failed, data is null or size bigger than 128M."); + if (isUnMap_ || data == nullptr || size > MAX_IMAGEDATA_SIZE) { + IMAGE_LOGE("WriteImageData failed, data is null or size bigger than 128M, isUnMap %{public}d.", isUnMap_); return false; } @@ -2860,10 +2862,10 @@ bool PixelMap::EncodeTlv(std::vector &buff) const WriteUint8(buff, TLV_IMAGE_DATA); const uint8_t *data = data_; int32_t dataSize = rowDataSize_ * imageInfo_.size.height; - if (data == nullptr || size_t(dataSize) > MAX_IMAGEDATA_SIZE || dataSize <= 0) { + if (isUnMap_ || data == nullptr || size_t(dataSize) > MAX_IMAGEDATA_SIZE || dataSize <= 0) { WriteVarint(buff, 0); // L is zero and no value WriteUint8(buff, TLV_END); // end tag - IMAGE_LOGE("pixel map tlv encode fail: no data"); + IMAGE_LOGE("pixel map tlv encode fail: no data, isUnMap %{public}d", isUnMap_); return false; } WriteVarint(buff, dataSize); @@ -3237,8 +3239,8 @@ uint32_t PixelMap::CheckAlphaFormatInput(PixelMap &wPixelMap, const bool isPremu void* dstData = wPixelMap.GetWritablePixels(); int32_t stride = wPixelMap.GetRowStride(); - if (dstData == nullptr || data_ == nullptr) { - IMAGE_LOGE("read pixels by dstPixelMap or srcPixelMap data is null."); + if (isUnMap_ || dstData == nullptr || data_ == nullptr) { + IMAGE_LOGE("read pixels by dstPixelMap or srcPixelMap data is null, isUnMap %{public}d.", isUnMap_); return ERR_IMAGE_READ_PIXELMAP_FAILED; } if (!((GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_PREMUL && !isPremul) || @@ -3329,9 +3331,9 @@ uint32_t PixelMap::SetAlpha(const float percent) auto pixelFormat = GetPixelFormat(); uint32_t pixelsSize = static_cast(GetByteCount()); int8_t alphaIndex = GetAlphaIndex(pixelFormat); - if (alphaIndex == INVALID_ALPHA_INDEX) { - IMAGE_LOGE("Could not set alpha on %{public}s", - GetNamedPixelFormat(pixelFormat).c_str()); + if (isUnMap_ || alphaIndex == INVALID_ALPHA_INDEX) { + IMAGE_LOGE("Could not set alpha on %{public}s, isUnMap %{public}d", + GetNamedPixelFormat(pixelFormat).c_str(), isUnMap_); return ERR_IMAGE_DATA_UNSUPPORT; } @@ -3532,6 +3534,10 @@ bool PixelMap::DoTranslation(TransInfos &infos, const AntiAliasingOption &option #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this)); #else + if (isUnMap_) { + IMAGE_LOGE("DoTranslation falied, isUnMap %{public}d", isUnMap_); + return false; + } GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this)); #endif SkTransInfo dst; @@ -3690,6 +3696,10 @@ uint32_t PixelMap::crop(const Rect &rect) #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) GenSrcTransInfo(src, imageInfo, this, ToSkColorSpace(this)); #else + if (isUnMap_) { + IMAGE_LOGE("PixelMap::crop falied, isUnMap %{public}d", isUnMap_); + return ERR_IMAGE_CROP; + } GenSrcTransInfo(src, imageInfo, data_, ToSkColorSpace(this)); #endif SkTransInfo dst; @@ -3864,6 +3874,58 @@ std::unique_ptr PixelMap::CreateSdrMemory(ImageInfo &imageInfo, Pixel #endif } +bool PixelMap::UnMap() +{ +#if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM) + if (allocatorType_ != AllocatorType::SHARE_MEM_ALLOC) { + return false; + } + std::lock_guard lock(*unmapMutex_); + if (!isUnMap_) { + unMapCount_++; + isUnMap_ = true; + + if (data_ != nullptr) { + ::munmap(data_, pixelsSize_); + data_ = nullptr; + } + } + return true; +#else + return false; +#endif +} + +bool PixelMap::ReMap() +{ +#if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM) + if (allocatorType_ != AllocatorType::SHARE_MEM_ALLOC) { + return false; + } + std::lock_guard lock(*unmapMutex_); + if (!isUnMap_) { + return true; + } + + int *fd = static_cast(context_); + if (fd == nullptr) { + return false; + } + + void *ptr = ::mmap(nullptr, pixelsSize_, PROT_READ, MAP_SHARED, *fd, 0); + if (ptr == MAP_FAILED) { + return false; + } + + data_ = (uint8_t *)ptr; + + isUnMap_ = false; + return true; +#else + return false; +#endif +} + uint32_t PixelMap::ToSdr() { ImageInfo imageInfo; @@ -3967,6 +4029,10 @@ uint32_t PixelMap::ApplyColorSpace(const OHOS::ColorManager::ColorSpace &grColor uint64_t rowStride = src.info.minRowBytes(); uint8_t* srcData = data_; #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + if (isUnMap_) { + IMAGE_LOGE("PixelMap::ApplyColorSpace falied, isUnMap %{public}d", isUnMap_); + return ERR_IMAGE_COLOR_CONVERT; + } if (GetAllocatorType() == AllocatorType::DMA_ALLOC && GetFd() != nullptr) { SurfaceBuffer* sbBuffer = reinterpret_cast(GetFd()); rowStride = static_cast(sbBuffer->GetStride()); diff --git a/interfaces/innerkits/include/pixel_map.h b/interfaces/innerkits/include/pixel_map.h index 8a2b63fc1..fadf24e9c 100644 --- a/interfaces/innerkits/include/pixel_map.h +++ b/interfaces/innerkits/include/pixel_map.h @@ -334,6 +334,42 @@ public: allocatorType_ = allocatorType; } + // unmap方案, 减少RenderService内存占用 + NATIVEEXPORT bool UnMap(); + NATIVEEXPORT bool ReMap(); + NATIVEEXPORT bool IsUnMap() + { + std::lock_guard lock(*unmapMutex_); + return isUnMap_; + } + NATIVEEXPORT void IncreaseUseCount() + { + std::lock_guard lock(*unmapMutex_); + useCount_ += 1; + } + NATIVEEXPORT void DecreaseUseCount() + { + std::lock_guard lock(*unmapMutex_); + if (useCount_ > 0) { + useCount_ -= 1; + } + } + NATIVEEXPORT void ResetUseCount() + { + std::lock_guard lock(*unmapMutex_); + useCount_ = 0; + } + NATIVEEXPORT uint64_t GetUseCount() + { + std::lock_guard lock(*unmapMutex_); + return useCount_; + } + NATIVEEXPORT uint64_t GetUnMapCount() + { + std::lock_guard lock(*unmapMutex_); + return unMapCount_; + } + static int32_t GetRGBxRowDataSize(const ImageInfo& info); static int32_t GetRGBxByteCount(const ImageInfo& info); static int32_t GetYUVByteCount(const ImageInfo& info); @@ -417,7 +453,8 @@ protected: bool CheckValidParam(int32_t x, int32_t y) { - return (data_ == nullptr) || (x >= imageInfo_.size.width) || (x < 0) || (y >= imageInfo_.size.height) || + return isUnMap_ || (data_ == nullptr) || + (x >= imageInfo_.size.width) || (x < 0) || (y >= imageInfo_.size.height) || (y < 0) || (pixelsSize_ < static_cast(rowDataSize_) * imageInfo_.size.height) ? false : true; @@ -496,6 +533,12 @@ protected: bool toSdrColorIsSRGB_ = false; uint32_t versionId_ = 1; std::shared_ptr versionMutex_ = std::make_shared(); +private: + // unmap方案, 减少RenderService内存占用 + bool isUnMap_ = false; + uint64_t useCount_ = 0ULL; + uint64_t unMapCount_ = 0; + std::shared_ptr unmapMutex_ = std::make_shared(); }; } // namespace Media } // namespace OHOS -- Gitee