1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef RS_MEMORY_MANAGER_H 16 #define RS_MEMORY_MANAGER_H 17 #include <vector> 18 19 #include "image/gpu_context.h" 20 21 #include "memory/rs_dfx_string.h" 22 #include "memory/rs_memory_graphic.h" 23 #include "memory/rs_memory_snapshot.h" 24 #include "memory/rs_memory_track.h" 25 #include "pipeline/rs_surface_render_node.h" 26 27 namespace OHOS::Rosen { 28 29 class MemoryManager { 30 public: 31 static void DumpMemoryUsage(DfxString& log, std::string& type); 32 static void DumpPidMemory(DfxString& log, int pid, const Drawing::GPUContext* gpuContext); 33 static void DumpDrawingGpuMemory(DfxString& log, const Drawing::GPUContext* grContext, 34 std::vector<std::pair<NodeId, std::string>>& nodeTags); 35 static void DumpExitPidMem(std::string& log, int pid); 36 // Count memory for hidumper 37 static MemoryGraphic CountPidMemory(int pid, const Drawing::GPUContext* gpuContext); 38 static void CountMemory(std::vector<pid_t> pids, 39 const Drawing::GPUContext* gpuContext, std::vector<MemoryGraphic>& mems); 40 static void ReleaseUnlockGpuResource(Drawing::GPUContext* gpuContext, NodeId surfaceNodeId); 41 static void ReleaseUnlockGpuResource(Drawing::GPUContext* gpuContext, pid_t pid); 42 static void ReleaseUnlockGpuResource(Drawing::GPUContext* gpuContext, Drawing::GPUResourceTag& tag); 43 static void ReleaseUnlockGpuResource(Drawing::GPUContext* gpuContext, std::set<pid_t> exitedPidSet); 44 static void PurgeCacheBetweenFrames(Drawing::GPUContext* gpuContext, bool scratchResourceOnly, 45 std::set<pid_t>& exitedPidSet, std::set<pid_t>& protectedPidSet); 46 static void ReleaseAllGpuResource(Drawing::GPUContext* gpuContext, pid_t pid); 47 static void ReleaseAllGpuResource(Drawing::GPUContext* gpuContext, Drawing::GPUResourceTag& tag); 48 static void ReleaseUnlockGpuResource(Drawing::GPUContext* grContext, bool scratchResourcesOnly = true); 49 static void ReleaseUnlockAndSafeCacheGpuResource(Drawing::GPUContext* grContext); 50 static float GetAppGpuMemoryInMB(Drawing::GPUContext* gpuContext); 51 static void InitMemoryLimit(); 52 static void SetGpuMemoryLimit(Drawing::GPUContext* gpuContext); 53 static void MemoryOverCheck(Drawing::GPUContext* gpuContext); 54 static void MemoryOverflow(pid_t pid, size_t overflowMemory, bool isGpu); 55 static void CheckIsClearApp(); 56 static void VmaDefragment(Drawing::GPUContext* gpuContext); 57 static void SetGpuCacheSuppressWindowSwitch(Drawing::GPUContext* gpuContext, bool enabled); 58 static void SetGpuMemoryAsyncReclaimerSwitch( 59 Drawing::GPUContext* gpuContext, bool enabled, const std::function<void()>& setThreadPriority); 60 static void FlushGpuMemoryInWaitQueue(Drawing::GPUContext* gpuContext); 61 static void SuppressGpuCacheBelowCertainRatio( 62 Drawing::GPUContext* gpuContext, const std::function<bool(void)>& nextFrameHasArrived); 63 private: 64 // rs memory = rs + skia cpu + skia gpu 65 static void DumpRenderServiceMemory(DfxString& log); 66 static void DumpDrawingCpuMemory(DfxString& log); 67 static void DumpGpuCache(DfxString& log, const Drawing::GPUContext* gpuContext, 68 Drawing::GPUResourceTag* tag, std::string& name); 69 static void DumpAllGpuInfo(DfxString& log, const Drawing::GPUContext* grContext, 70 std::vector<std::pair<NodeId, std::string>>& nodeTags); 71 //jemalloc info 72 static void DumpGpuStats(DfxString& log, const Drawing::GPUContext* gpuContext); 73 static void DumpMemorySnapshot(DfxString& log); 74 static void FillMemorySnapshot(); 75 static void MemoryOverReport(const pid_t pid, const MemorySnapshotInfo& info, const std::string& reportName, 76 const std::string& hidumperReport); 77 static void WriteInfoToFile(std::string& filePath, std::string& gpuMemInfo, const std::string& hidumperReport); 78 static bool NeedCleanNow(std::vector<std::string>& needCleanFileName); 79 static void CleanFiles(std::vector<std::string>& needCleanFileName); 80 static void TotalMemoryOverReport(const std::unordered_map<pid_t, MemorySnapshotInfo>& infoMap); 81 static void ErasePidInfo(const std::set<pid_t>& exitedPidSet); 82 static void MemoryOverForReport(std::unordered_map<pid_t, MemorySnapshotInfo>& infoMap, bool isTotalOver); 83 84 static std::mutex mutex_; 85 static std::unordered_map<pid_t, uint64_t> pidInfo_; 86 static uint32_t frameCount_; 87 static uint64_t memoryWarning_; 88 static uint64_t gpuMemoryControl_; 89 static uint64_t totalMemoryReportTime_; 90 static std::unordered_set<pid_t> processKillReportPidSet_; 91 }; 92 93 class RSB_EXPORT RSReclaimMemoryManager { 94 public: 95 static RSReclaimMemoryManager& Instance(); 96 97 RSReclaimMemoryManager() = default; 98 ~RSReclaimMemoryManager() = default; 99 100 void TriggerReclaimTask(); 101 void InterruptReclaimTask(const std::string& sceneId); 102 SetReclaimInterrupt(bool isInterrupt)103 void SetReclaimInterrupt(bool isInterrupt) 104 { 105 isReclaimInterrupt_.store(isInterrupt); 106 } IsReclaimInterrupt()107 bool IsReclaimInterrupt() 108 { 109 return isReclaimInterrupt_.load(); 110 } 111 private: 112 DISALLOW_COPY_AND_MOVE(RSReclaimMemoryManager); 113 // reclaim interrupt 114 std::atomic<bool> isReclaimInterrupt_ = false; 115 }; 116 } // namespace OHOS::Rosen 117 #endif