• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "memory/rs_memory_manager.h"
17 
18 #include <malloc.h>
19 #include "include/core/SkGraphics.h"
20 #include "rs_trace.h"
21 
22 #include "rs_skia_memory_tracer.h"
23 #include "memory/rs_memory_graphic.h"
24 #ifdef NEW_SKIA
25 #include "include/gpu/GrDirectContext.h"
26 #include "src/gpu/GrDirectContextPriv.h"
27 #else
28 #include "include/gpu/GrContext.h"
29 #include "src/gpu/GrContextPriv.h"
30 #endif
31 
32 #include "common/rs_obj_abs_geometry.h"
33 #include "memory/rs_tag_tracker.h"
34 #ifdef NEW_RENDER_CONTEXT
35 #include "render_context/memory_handler.h"
36 #endif
37 #include "pipeline/rs_main_thread.h"
38 #include "pipeline/rs_surface_render_node.h"
39 #include "platform/common/rs_log.h"
40 
41 namespace OHOS::Rosen {
42 namespace {
43 constexpr uint32_t MEMUNIT_RATE = 1024;
44 constexpr const char* MEM_RS_TYPE = "renderservice";
45 constexpr const char* MEM_CPU_TYPE = "cpu";
46 constexpr const char* MEM_GPU_TYPE = "gpu";
47 constexpr const char* MEM_JEMALLOC_TYPE = "jemalloc";
48 }
49 
50 #ifndef USE_ROSEN_DRAWING
51 #ifdef NEW_SKIA
DumpMemoryUsage(DfxString & log,const GrDirectContext * grContext,std::string & type)52 void MemoryManager::DumpMemoryUsage(DfxString& log, const GrDirectContext* grContext, std::string& type)
53 #else
54 void MemoryManager::DumpMemoryUsage(DfxString& log, const GrContext* grContext, std::string& type)
55 #endif
56 {
57     if (type.empty() || type == MEM_RS_TYPE) {
58         DumpRenderServiceMemory(log);
59     }
60     if (type.empty() || type == MEM_CPU_TYPE) {
61         DumpDrawingCpuMemory(log);
62     }
63     if (type.empty() || type == MEM_GPU_TYPE) {
64         DumpDrawingGpuMemory(log, grContext);
65     }
66     if (type.empty() || type == MEM_JEMALLOC_TYPE) {
67         std::string out;
68         DumpMallocStat(out);
69         log.AppendFormat("%s\n... detail dump at hilog\n", out.c_str());
70     }
71 }
72 #else
DumpMemoryUsage(DfxString & log,const Drawing::GPUContext * gpuContext,std::string & type)73 void MemoryManager::DumpMemoryUsage(DfxString& log, const Drawing::GPUContext* gpuContext, std::string& type)
74 {
75     if (type.empty() || type == MEM_RS_TYPE) {
76         DumpRenderServiceMemory(log);
77     }
78     if (type.empty() || type == MEM_CPU_TYPE) {
79         DumpDrawingCpuMemory(log);
80     }
81     if (type.empty() || type == MEM_GPU_TYPE) {
82         DumpDrawingGpuMemory(log, gpuContext);
83     }
84     if (type.empty() || type == MEM_JEMALLOC_TYPE) {
85         std::string out;
86         DumpMallocStat(out);
87         log.AppendFormat("%s\n... detail dump at hilog\n", out.c_str());
88     }
89 }
90 #endif // USE_ROSEN_DRAWING
91 
92 #ifndef USE_ROSEN_DRAWING
93 #ifdef NEW_SKIA
ReleaseAllGpuResource(GrDirectContext * grContext,GrGpuResourceTag & tag)94 void MemoryManager::ReleaseAllGpuResource(GrDirectContext* grContext, GrGpuResourceTag& tag)
95 #else
96 void MemoryManager::ReleaseAllGpuResource(GrContext* grContext, GrGpuResourceTag& tag)
97 #endif
98 {
99 #ifdef RS_ENABLE_GL
100     if (!grContext) {
101         RS_LOGE("ReleaseGpuResByTag fail, grContext is nullptr");
102     }
103     RS_TRACE_NAME_FMT("ReleaseAllGpuResource [Pid:%d Tid:%d Nid:%d Funcid:%d]",
104         tag.fPid, tag.fTid, tag.fWid, tag.fFid);
105     grContext->releaseByTag(tag);
106 #endif
107 }
108 #else
109 #endif
110 
111 #ifndef USE_ROSEN_DRAWING
112 #ifdef NEW_SKIA
ReleaseAllGpuResource(GrDirectContext * grContext,pid_t pid)113 void MemoryManager::ReleaseAllGpuResource(GrDirectContext* grContext, pid_t pid)
114 #else
115 void MemoryManager::ReleaseAllGpuResource(GrContext* grContext, pid_t pid)
116 #endif
117 {
118 #ifdef RS_ENABLE_GL
119     GrGpuResourceTag tag(pid, 0, 0, 0);
120     ReleaseAllGpuResource(grContext, tag);
121 #endif
122 }
123 #else
ReleaseAllGpuResource(Drawing::GPUContext * gpuContext,pid_t pid)124 void MemoryManager::ReleaseAllGpuResource(Drawing::GPUContext* gpuContext, pid_t pid)
125 {
126 }
127 #endif
128 
129 #ifndef USE_ROSEN_DRAWING
130 #ifdef NEW_SKIA
ReleaseUnlockGpuResource(GrDirectContext * grContext,GrGpuResourceTag & tag)131 void MemoryManager::ReleaseUnlockGpuResource(GrDirectContext* grContext, GrGpuResourceTag& tag)
132 #else
133 void MemoryManager::ReleaseUnlockGpuResource(GrContext* grContext, GrGpuResourceTag& tag)
134 #endif
135 {
136 #ifdef RS_ENABLE_GL
137     if (!grContext) {
138         RS_LOGE("ReleaseGpuResByTag fail, grContext is nullptr");
139     }
140     RS_TRACE_NAME_FMT("ReleaseUnlockGpuResource [Pid:%d Tid:%d Nid:%d Funcid:%d]",
141         tag.fPid, tag.fTid, tag.fWid, tag.fFid);
142     grContext->purgeUnlockedResourcesByTag(false, tag);
143 #endif
144 }
145 #else
146 #endif
147 
148 #ifndef USE_ROSEN_DRAWING
149 #ifdef NEW_SKIA
ReleaseUnlockGpuResource(GrDirectContext * grContext,NodeId surfaceNodeId)150 void MemoryManager::ReleaseUnlockGpuResource(GrDirectContext* grContext, NodeId surfaceNodeId)
151 #else
152 void MemoryManager::ReleaseUnlockGpuResource(GrContext* grContext, NodeId surfaceNodeId)
153 #endif
154 {
155 #ifdef RS_ENABLE_GL
156     GrGpuResourceTag tag(ExtractPid(surfaceNodeId), 0, 0, 0);
157     ReleaseUnlockGpuResource(grContext, tag); // clear gpu resource by pid
158 #endif
159 }
160 #else
ReleaseUnlockGpuResource(Drawing::GPUContext * grContext,NodeId surfaceNodeId)161 void MemoryManager::ReleaseUnlockGpuResource(Drawing::GPUContext* grContext, NodeId surfaceNodeId)
162 {
163 }
164 #endif
165 
166 #ifndef USE_ROSEN_DRAWING
167 #ifdef NEW_SKIA
ReleaseUnlockGpuResource(GrDirectContext * grContext,pid_t pid)168 void MemoryManager::ReleaseUnlockGpuResource(GrDirectContext* grContext, pid_t pid)
169 #else
170 void MemoryManager::ReleaseUnlockGpuResource(GrContext* grContext, pid_t pid)
171 #endif
172 {
173 #ifdef RS_ENABLE_GL
174     GrGpuResourceTag tag(pid, 0, 0, 0);
175     ReleaseUnlockGpuResource(grContext, tag); // clear gpu resource by pid
176 #endif
177 }
178 #else
ReleaseUnlockGpuResource(Drawing::GPUContext * grContext,pid_t pid)179 void MemoryManager::ReleaseUnlockGpuResource(Drawing::GPUContext* grContext, pid_t pid)
180 {
181 }
182 #endif
183 
184 #ifndef USE_ROSEN_DRAWING
185 #ifdef NEW_SKIA
ReleaseUnlockGpuResource(GrDirectContext * grContext,bool scratchResourcesOnly)186 void MemoryManager::ReleaseUnlockGpuResource(GrDirectContext* grContext, bool scratchResourcesOnly)
187 #else
188 void MemoryManager::ReleaseUnlockGpuResource(GrContext* grContext, bool scratchResourcesOnly)
189 #endif
190 {
191 #ifdef RS_ENABLE_GL
192     if (!grContext) {
193         RS_LOGE("ReleaseGpuResByTag fail, grContext is nullptr");
194     }
195     RS_TRACE_NAME_FMT("ReleaseUnlockGpuResource scratchResourcesOnly:%d", scratchResourcesOnly);
196     grContext->purgeUnlockedResources(scratchResourcesOnly);
197 #endif
198 }
199 #else
ReleaseUnlockGpuResource(Drawing::GPUContext * gpuContext,bool scratchResourcesOnly)200 void MemoryManager::ReleaseUnlockGpuResource(Drawing::GPUContext* gpuContext, bool scratchResourcesOnly)
201 {
202 #ifdef RS_ENABLE_GL
203     if (!gpuContext) {
204         RS_LOGE("ReleaseGpuResByTag fail, gpuContext is nullptr");
205     }
206     RS_TRACE_NAME_FMT("ReleaseUnlockGpuResource scratchResourcesOnly:%d", scratchResourcesOnly);
207 #endif
208 }
209 #endif
210 
211 #ifndef USE_ROSEN_DRAWING
212 #ifdef NEW_SKIA
ReleaseUnlockAndSafeCacheGpuResource(GrDirectContext * grContext)213 void MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(GrDirectContext* grContext)
214 #else
215 void MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(GrContext* grContext)
216 #endif
217 {
218 #ifdef RS_ENABLE_GL
219     if (!grContext) {
220         RS_LOGE("ReleaseUnlockAndSafeCacheGpuResource fail, grContext is nullptr");
221     }
222     RS_TRACE_NAME_FMT("ReleaseUnlockAndSafeCacheGpuResource");
223     grContext->purgeUnlockAndSafeCacheGpuResources();
224 #endif
225 }
226 #else
ReleaseUnlockAndSafeCacheGpuResource(Drawing::GPUContext * gpuContext)227 void MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(Drawing::GPUContext* gpuContext)
228 {
229 #ifdef RS_ENABLE_GL
230     if (!gpuContext) {
231         RS_LOGE("ReleaseUnlockAndSafeCacheGpuResource fail, gpuContext is nullptr");
232     }
233     RS_TRACE_NAME_FMT("ReleaseUnlockAndSafeCacheGpuResource");
234 #endif
235 }
236 #endif
237 
238 #ifndef USE_ROSEN_DRAWING
239 #ifdef NEW_SKIA
DumpPidMemory(DfxString & log,int pid,const GrDirectContext * grContext)240 void MemoryManager::DumpPidMemory(DfxString& log, int pid, const GrDirectContext* grContext)
241 #else
242 void MemoryManager::DumpPidMemory(DfxString& log, int pid, const GrContext* grContext)
243 #endif
244 {
245     //MemoryTrack::Instance().DumpMemoryStatistics(log, pid);
246     MemoryGraphic mem = CountPidMemory(pid, grContext);
247     log.AppendFormat("GPU Mem(MB):%f\n", mem.GetGpuMemorySize() / (MEMUNIT_RATE * MEMUNIT_RATE));
248     log.AppendFormat("CPU Mem(MB):%f\n", mem.GetCpuMemorySize() / (MEMUNIT_RATE * MEMUNIT_RATE));
249     log.AppendFormat("Total Mem(MB):%f\n", mem.GetTotalMemorySize() / (MEMUNIT_RATE * MEMUNIT_RATE));
250 }
251 #else
DumpPidMemory(DfxString & log,int pid,const Drawing::GPUContext * gpuContext)252 void MemoryManager::DumpPidMemory(DfxString& log, int pid, const Drawing::GPUContext* gpuContext)
253 {
254     MemoryGraphic mem = CountPidMemory(pid, gpuContext);
255     log.AppendFormat("GPU Mem(MB):%f\n", mem.GetGpuMemorySize() / (MEMUNIT_RATE * MEMUNIT_RATE));
256     log.AppendFormat("CPU Mem(KB):%f\n", mem.GetCpuMemorySize() / MEMUNIT_RATE);
257     log.AppendFormat("Total Mem(MB):%f\n", mem.GetTotalMemorySize() / (MEMUNIT_RATE * MEMUNIT_RATE));
258 }
259 #endif
260 
261 #ifndef USE_ROSEN_DRAWING
262 #ifdef NEW_SKIA
CountPidMemory(int pid,const GrDirectContext * grContext)263 MemoryGraphic MemoryManager::CountPidMemory(int pid, const GrDirectContext* grContext)
264 #else
265 MemoryGraphic MemoryManager::CountPidMemory(int pid, const GrContext* grContext)
266 #endif
267 {
268     MemoryGraphic totalMemGraphic;
269 
270     // Count mem of RS
271     totalMemGraphic.SetPid(pid);
272     MemoryGraphic rsMemGraphic = MemoryTrack::Instance().CountRSMemory(pid);
273     totalMemGraphic += rsMemGraphic;
274 
275 #ifdef RS_ENABLE_GL
276     // Count mem of Skia GPU
277     if (grContext) {
278         SkiaMemoryTracer gpuTracer("category", true);
279         GrGpuResourceTag tag(pid, 0, 0, 0);
280         grContext->dumpMemoryStatisticsByTag(&gpuTracer, tag);
281         float gpuMem = gpuTracer.GetGLMemorySize();
282         totalMemGraphic.IncreaseGpuMemory(gpuMem);
283     }
284 #endif
285 
286     return totalMemGraphic;
287 }
288 #else
CountPidMemory(int pid,const Drawing::GPUContext * gpuContext)289 MemoryGraphic MemoryManager::CountPidMemory(int pid, const Drawing::GPUContext* gpuContext)
290 {
291     MemoryGraphic totalMemGraphic;
292 
293     // Count mem of RS
294     totalMemGraphic.SetPid(pid);
295     MemoryGraphic rsMemGraphic = MemoryTrack::Instance().CountRSMemory(pid);
296     totalMemGraphic += rsMemGraphic;
297 
298 #ifdef RS_ENABLE_GL
299     // Count mem of Skia GPU
300 #endif
301 
302     return totalMemGraphic;
303 }
304 #endif
305 
306 #ifndef USE_ROSEN_DRAWING
307 #ifdef NEW_SKIA
CountMemory(std::vector<pid_t> pids,const GrDirectContext * grContext,std::vector<MemoryGraphic> & mems)308 void MemoryManager::CountMemory(std::vector<pid_t> pids, const GrDirectContext* grContext,
309     std::vector<MemoryGraphic>& mems)
310 #else
311 void MemoryManager::CountMemory(std::vector<pid_t> pids, const GrContext* grContext, std::vector<MemoryGraphic>& mems)
312 #endif
313 {
314     auto countMem = [&grContext, &mems] (pid_t pid) {
315         mems.emplace_back(CountPidMemory(pid, grContext));
316     };
317     // Count mem of Skia GPU
318     std::for_each(pids.begin(), pids.end(), countMem);
319 }
320 #else
CountMemory(std::vector<pid_t> pids,const Drawing::GPUContext * gpuContext,std::vector<MemoryGraphic> & mems)321 void MemoryManager::CountMemory(
322     std::vector<pid_t> pids, const Drawing::GPUContext* gpuContext, std::vector<MemoryGraphic>& mems)
323 {
324     auto countMem = [&gpuContext, &mems] (pid_t pid) {
325         mems.emplace_back(CountPidMemory(pid, gpuContext));
326     };
327     // Count mem of Skia GPU
328     std::for_each(pids.begin(), pids.end(), countMem);
329 }
330 #endif
331 
FindGeoById(uint64_t nodeId)332 static std::tuple<uint64_t, std::string, RectI> FindGeoById(uint64_t nodeId)
333 {
334     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
335     auto node = nodeMap.GetRenderNode<RSRenderNode>(nodeId);
336     uint64_t windowId = nodeId;
337     std::string windowName = "NONE";
338     RectI nodeFrameRect;
339     if (!node) {
340         return { windowId, windowName, nodeFrameRect };
341     }
342     nodeFrameRect =
343         (node->GetRenderProperties().GetBoundsGeometry())->GetAbsRect();
344     // Obtain the window according to childId
345     auto parent = node->GetParent().lock();
346     while (parent) {
347         if (parent->IsInstanceOf<RSSurfaceRenderNode>()) {
348             const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parent);
349             windowName = surfaceNode->GetName();
350             windowId = surfaceNode->GetId();
351             break;
352         }
353         parent = parent->GetParent().lock();
354     }
355     return { windowId, windowName, nodeFrameRect };
356 }
357 
DumpRenderServiceMemory(DfxString & log)358 void MemoryManager::DumpRenderServiceMemory(DfxString& log)
359 {
360     log.AppendFormat("\n----------\nRenderService caches:\n");
361     MemoryTrack::Instance().DumpMemoryStatistics(log, FindGeoById);
362 }
363 
DumpDrawingCpuMemory(DfxString & log)364 void MemoryManager::DumpDrawingCpuMemory(DfxString& log)
365 {
366     // CPU
367     log.AppendFormat("\n----------\nSkia CPU caches:\n");
368     log.AppendFormat("Font Cache (CPU):\n");
369     log.AppendFormat("  Size: %.2f kB \n", SkGraphics::GetFontCacheUsed() / MEMUNIT_RATE);
370     log.AppendFormat("  Glyph Count: %d \n", SkGraphics::GetFontCacheCountUsed());
371 
372     std::vector<ResourcePair> cpuResourceMap = {
373         { "skia/sk_resource_cache/bitmap_", "Bitmaps" },
374         { "skia/sk_resource_cache/rrect-blur_", "Masks" },
375         { "skia/sk_resource_cache/rects-blur_", "Masks" },
376         { "skia/sk_resource_cache/tessellated", "Shadows" },
377         { "skia/sk_resource_cache/yuv-planes_", "YUVPlanes" },
378         { "skia/sk_resource_cache/budget_glyph_count", "Bitmaps" },
379     };
380     SkiaMemoryTracer cpuTracer(cpuResourceMap, true);
381     SkGraphics::DumpMemoryStatistics(&cpuTracer);
382     log.AppendFormat("CPU Cachesxx:\n");
383     cpuTracer.LogOutput(log);
384     log.AppendFormat("Total CPU memory usage:\n");
385     cpuTracer.LogTotals(log);
386 
387     // cache limit
388     size_t cacheLimit = SkGraphics::GetResourceCacheTotalByteLimit();
389     size_t fontCacheLimit = SkGraphics::GetFontCacheLimit();
390     log.AppendFormat("\ncpu cache limit = %zu ( fontcache = %zu ):\n", cacheLimit, fontCacheLimit);
391 }
392 
393 #ifndef USE_ROSEN_DRAWING
394 #ifdef NEW_SKIA
DumpGpuCache(DfxString & log,const GrDirectContext * grContext,GrGpuResourceTag * tag,std::string & name)395 void MemoryManager::DumpGpuCache(
396     DfxString& log, const GrDirectContext* grContext, GrGpuResourceTag* tag, std::string& name)
397 #else
398 void MemoryManager::DumpGpuCache(DfxString& log, const GrContext* grContext, GrGpuResourceTag* tag, std::string& name)
399 #endif
400 {
401     if (!grContext) {
402         log.AppendFormat("grContext is nullptr.\n");
403         return;
404     }
405     /////////////////////////////GPU/////////////////////////
406 #ifdef RS_ENABLE_GL
407     log.AppendFormat("\n---------------\nSkia GPU Caches:%s\n", name.c_str());
408     SkiaMemoryTracer gpuTracer("category", true);
409     if (tag) {
410         grContext->dumpMemoryStatisticsByTag(&gpuTracer, *tag);
411     } else {
412         grContext->dumpMemoryStatistics(&gpuTracer);
413     }
414     gpuTracer.LogOutput(log);
415     log.AppendFormat("Total GPU memory usage:\n");
416     gpuTracer.LogTotals(log);
417 #endif
418 }
419 #else
420 #endif
421 
422 #ifndef USE_ROSEN_DRAWING
423 #ifdef NEW_SKIA
DumpAllGpuInfo(DfxString & log,const GrDirectContext * grContext)424 void MemoryManager::DumpAllGpuInfo(DfxString& log, const GrDirectContext* grContext)
425 #else
426 void MemoryManager::DumpAllGpuInfo(DfxString& log, const GrContext* grContext)
427 #endif
428 {
429     if (!grContext) {
430         log.AppendFormat("No valid gpu cache instance.\n");
431         return;
432     }
433 #ifdef RS_ENABLE_GL
434     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
435     nodeMap.TraverseSurfaceNodes([&log, &grContext](const std::shared_ptr<RSSurfaceRenderNode> node) {
436         GrGpuResourceTag tag(ExtractPid(node->GetId()), 0, node->GetId(), 0);
437         std::string name = node->GetName() + " " + std::to_string(node->GetId());
438         DumpGpuCache(log, grContext, &tag, name);
439     });
440 #endif
441 }
442 #else
DumpAllGpuInfo(DfxString & log,const Drawing::GPUContext * gpuContext)443 void MemoryManager::DumpAllGpuInfo(DfxString& log, const Drawing::GPUContext* gpuContext)
444 {
445     if (!gpuContext) {
446         log.AppendFormat("No valid gpu cache instance.\n");
447         return;
448     }
449 #ifdef RS_ENABLE_GL
450     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
451     nodeMap.TraverseSurfaceNodes([&log, &gpuContext](const std::shared_ptr<RSSurfaceRenderNode> node) {
452     });
453 #endif
454 }
455 #endif
456 
457 #ifndef USE_ROSEN_DRAWING
458 #ifdef NEW_SKIA
DumpDrawingGpuMemory(DfxString & log,const GrDirectContext * grContext)459 void MemoryManager::DumpDrawingGpuMemory(DfxString& log, const GrDirectContext* grContext)
460 #else
461 void MemoryManager::DumpDrawingGpuMemory(DfxString& log, const GrContext* grContext)
462 #endif
463 {
464     if (!grContext) {
465         log.AppendFormat("No valid gpu cache instance.\n");
466         return;
467     }
468     /////////////////////////////GPU/////////////////////////
469 #ifdef RS_ENABLE_GL
470     std::string gpuInfo;
471     // total
472     DumpGpuCache(log, grContext, nullptr, gpuInfo);
473     // Get memory of window by tag
474     DumpAllGpuInfo(log, grContext);
475     for (uint32_t tagtype = RSTagTracker::TAG_SAVELAYER_DRAW_NODE; tagtype <= RSTagTracker::TAG_CAPTURE; tagtype++) {
476         GrGpuResourceTag tag(0, 0, 0, tagtype);
477         std::string tagType = RSTagTracker::TagType2String(static_cast<RSTagTracker::TAGTYPE>(tagtype));
478         DumpGpuCache(log, grContext, &tag, tagType);
479     }
480     // cache limit
481     size_t cacheLimit = 0;
482     size_t cacheUsed = 0;
483     grContext->getResourceCacheLimits(nullptr, &cacheLimit);
484     grContext->getResourceCacheUsage(nullptr, &cacheUsed);
485     log.AppendFormat("\ngpu limit = %zu ( used = %zu ):\n", cacheLimit, cacheUsed);
486 
487     //////////////////////////ShaderCache///////////////////
488     log.AppendFormat("\n---------------\nShader Caches:\n");
489 #ifdef NEW_RENDER_CONTEXT
490     log.AppendFormat(MemoryHandler::QuerryShader().c_str());
491 #else
492     std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
493     log.AppendFormat(rendercontext->GetShaderCacheSize().c_str());
494 #endif
495     // gpu stat
496     log.AppendFormat("\n---------------\ndumpGpuStats:\n");
497     SkString stat;
498     grContext->priv().dumpGpuStats(&stat);
499 
500     log.AppendFormat("%s\n", stat.c_str());
501 #endif
502 }
503 #else
DumpDrawingGpuMemory(DfxString & log,const Drawing::GPUContext * gpuContext)504 void MemoryManager::DumpDrawingGpuMemory(DfxString& log, const Drawing::GPUContext* gpuContext)
505 {
506 }
507 #endif
508 
DumpMallocStat(std::string & log)509 void MemoryManager::DumpMallocStat(std::string& log)
510 {
511     malloc_stats_print(
512         [](void* fp, const char* str) {
513             if (!fp) {
514                 RS_LOGE("DumpMallocStat fp is nullptr");
515                 return;
516             }
517             std::string* sp = static_cast<std::string*>(fp);
518             if (str) {
519                 // cause log only support 2096 len. we need to only output critical log
520                 // and only put total log in RSLOG
521                 // get allocated string
522                 if (strncmp(str, "Allocated", strlen("Allocated")) == 0) {
523                     sp->append(str);
524                 }
525                 RS_LOGW("[mallocstat]:%s", str);
526             }
527         },
528         &log, nullptr);
529 }
530 } // namespace OHOS::Rosen