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 DumpMallocStat(std::string& log); 74 static void DumpMemorySnapshot(DfxString& log); 75 static void MemoryOverReport(const pid_t pid, const MemorySnapshotInfo& info, const std::string& bundleName, 76 const std::string& reportName); 77 static void TotalMemoryOverReport(const std::unordered_map<pid_t, MemorySnapshotInfo>& infoMap); 78 static void ErasePidInfo(const std::set<pid_t>& exitedPidSet); 79 80 static std::mutex mutex_; 81 static std::unordered_map<pid_t, std::pair<std::string, uint64_t>> pidInfo_; 82 static uint32_t frameCount_; 83 static uint64_t memoryWarning_; 84 static uint64_t gpuMemoryControl_; 85 static uint64_t totalMemoryReportTime_; 86 }; 87 88 class RSB_EXPORT RSReclaimMemoryManager { 89 public: 90 static RSReclaimMemoryManager& Instance(); 91 92 RSReclaimMemoryManager() = default; 93 ~RSReclaimMemoryManager() = default; 94 95 void TriggerReclaimTask(); 96 void InterruptReclaimTask(const std::string& sceneId); 97 SetReclaimInterrupt(bool isInterrupt)98 void SetReclaimInterrupt(bool isInterrupt) 99 { 100 isReclaimInterrupt_.store(isInterrupt); 101 } IsReclaimInterrupt()102 bool IsReclaimInterrupt() 103 { 104 return isReclaimInterrupt_.load(); 105 } 106 private: 107 DISALLOW_COPY_AND_MOVE(RSReclaimMemoryManager); 108 // reclaim interrupt 109 std::atomic<bool> isReclaimInterrupt_ = false; 110 }; 111 } // namespace OHOS::Rosen 112 #endif