• 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 #ifndef ROSEN_MODULES_TEXGINE_SRC_UTILS_MEMORY_REPORTER_H
17 #define ROSEN_MODULES_TEXGINE_SRC_UTILS_MEMORY_REPORTER_H
18 
19 #include <cstring>
20 #include <map>
21 #include <memory>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 #include "texgine/typography.h"
27 #include "texgine/utils/memory_usage_scope.h"
28 #include "variant_font_style_set.h"
29 #include "variant_span.h"
30 
31 struct hb_blob_t;
32 
33 namespace OHOS {
34 namespace Rosen {
35 namespace TextEngine {
36 #define DECLARE_CLASS_RMU(type) \
37     void type::ReportMemoryUsage(const std::string &member, bool needThis) const
38 
39 #define DECLARE_RMU(type) \
40     void ReportMemoryUsage(const std::string &member, type const &that, bool needThis)
41 
42 #define MEMORY_USAGE_REPORT(member) \
43     OHOS::Rosen::TextEngine::ReportMemoryUsage(#member, currentVal.member, false)
44 
45 #define MEMORY_USAGE_SCOPE(classname, var) \
46     MemoryUsageScope s(std::string(classname) + " " + member); \
47     if (needThis) { DoReportMemoryUsage("*this", sizeof(var)); } \
48     [[maybe_unused]] const auto &currentVal = var
49 
50 template<class T>
GetTypeName()51 std::string GetTypeName()
52 {
53     std::string nameT = __PRETTY_FUNCTION__;
54     nameT = nameT.substr(nameT.find("T = "));
55     nameT = nameT.substr(strlen("T = "), nameT.length() - strlen("T = ") - 1);
56     constexpr const char *str = "std::variant<std::shared_ptr<TextSpan>, std::shared_ptr<AnySpan> >";
57     auto it = nameT.find(str);
58     if (it != std::string::npos) {
59         nameT = nameT.replace(it, strlen(str), "VariantSpan");
60     }
61     return nameT;
62 }
63 
64 template<class T>
65 void ReportMemoryUsage(const std::string &member, const T &t, bool needThis = true);
66 template<class T>
67 void ReportMemoryUsage(const std::string &member, const std::vector<T> &vec, bool needThis = true);
68 template<class T>
69 void ReportMemoryUsage(const std::string &member, const std::shared_ptr<T> &sp, bool needThis = true);
70 template<class T>
71 void ReportMemoryUsage(const std::string &member, const std::unique_ptr<T> &up, bool needThis = true);
72 template<class K, class V>
73 void ReportMemoryUsage(const std::string &member, const std::map<K, V> &m, bool needThis = true);
74 
75 struct StyledSpan;
76 class CmapParser;
77 class Ranges;
78 class Typeface;
79 class CharGroups;
80 class FontFeatures;
81 
82 DECLARE_RMU(std::string);
83 DECLARE_RMU(struct LineMetrics);
84 DECLARE_RMU(struct TypographyStyle);
85 DECLARE_RMU(VariantSpan);
86 DECLARE_RMU(struct StyledSpan);
87 DECLARE_RMU(AnySpan);
88 DECLARE_RMU(FontProviders);
89 DECLARE_RMU(IFontProvider);
90 DECLARE_RMU(TextSpan);
91 DECLARE_RMU(Typeface);
92 DECLARE_RMU(hb_blob_t *);
93 DECLARE_RMU(CharGroups);
94 DECLARE_RMU(struct TextStyle);
95 DECLARE_RMU(CmapParser);
96 DECLARE_RMU(FontFeatures);
97 DECLARE_RMU(Ranges);
98 
99 #ifdef TEXGINE_ENABLE_MEMORY
100 #define DEFINE_RMU(type) \
101     template<> \
102     DECLARE_RMU(type) \
103     { \
104         DoReportMemoryUsage(member, sizeof(that)); \
105     }
106 
107 DEFINE_RMU(uint16_t);
108 DEFINE_RMU(uint32_t);
109 DEFINE_RMU(int32_t);
110 DEFINE_RMU(double);
111 DEFINE_RMU(VariantFontStyleSet);
112 DEFINE_RMU(struct TextShadow);
113 DEFINE_RMU(struct Glyph);
114 #endif
115 
116 template<class T>
ReportMemoryUsage(const std::string & member,const T & t,bool needThis)117 void ReportMemoryUsage(const std::string &member, const T &t, bool needThis)
118 {
119     DoReportMemoryUsage(member, sizeof(t));
120 }
121 
122 template<class T>
ReportMemoryUsage(const std::string & member,const std::vector<T> & that,bool needThis)123 void ReportMemoryUsage(const std::string &member, const std::vector<T> &that, bool needThis)
124 {
125     auto nameT = GetTypeName<T>();
126     MEMORY_USAGE_SCOPE("v<" + nameT + ">", that);
127     // 16 is the vector`s base memory footprint
128     int baseMemory = 16;
129     if (that.capacity() != 0) {
130         DoReportMemoryUsage("*external", baseMemory + sizeof(T) * (that.capacity() - that.size()));
131         for (size_t i = 0; i < that.size(); i++) {
132             ReportMemoryUsage(member + "[?]", that[i], true);
133         }
134     }
135 }
136 
137 template<class T>
ReportMemoryUsage(const std::string & member,const std::shared_ptr<T> & that,bool needThis)138 void ReportMemoryUsage(const std::string &member, const std::shared_ptr<T> &that, bool needThis)
139 {
140     static std::set<void *> ptrs;
141     if (ptrs.find((void *)(that.get())) != ptrs.end()) {
142         return;
143     }
144     ptrs.insert((void *)(that.get()));
145 
146     auto nameT = GetTypeName<T>();
147     if (that != nullptr) {
148         ReportMemoryUsage(member, *that, true);
149     }
150 }
151 
152 template<class T>
ReportMemoryUsage(const std::string & member,const std::unique_ptr<T> & that,bool needThis)153 void ReportMemoryUsage(const std::string &member, const std::unique_ptr<T> &that, bool needThis)
154 {
155     static std::set<void *> ptrs;
156     if (ptrs.find((void *)(that.get())) != ptrs.end()) {
157         return;
158     }
159     ptrs.insert((void *)(that.get()));
160 
161     auto nameT = GetTypeName<T>();
162     if (that != nullptr) {
163         ReportMemoryUsage(member, *that, true);
164     }
165 }
166 
167 template<class K, class V>
ReportMemoryUsage(const std::string & member,const std::map<K,V> & that,bool needThis)168 void ReportMemoryUsage(const std::string &member, const std::map<K, V> &that, bool needThis)
169 {
170     if (that.size()) {
171         auto nameK = GetTypeName<K>();
172         auto nameV = GetTypeName<V>();
173         MEMORY_USAGE_SCOPE("m<" + nameK + ", " + nameV + ">", that);
174         // in std::map, the size of key, if more than 8, it`s base memory footprint is 8 + 40
175         // else base memory footprint is 40
176         unsigned long memoryDelta = 8;
177         unsigned long baseMemory = 40;
178         unsigned long sizeLimit = 8;
179         DoReportMemoryUsage("*external", static_cast<int>(
180             that.size() * ((sizeof(K) < sizeLimit ? 0 : memoryDelta) + baseMemory + sizeof(K) + sizeof(V))));
181     }
182 }
183 } // namespace TextEngine
184 } // namespace Rosen
185 } // namespace OHOS
186 
187 #endif // ROSEN_MODULES_TEXGINE_SRC_UTILS_MEMORY_REPORTER_H
188