1 /*
2 * Copyright (c) 2024 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 RS_PROFILER_MESSAGE_HELPER_H
17 #define RS_PROFILER_MESSAGE_HELPER_H
18
19 #include "rs_profiler_utils.h"
20
21 #include <bitset>
22 #include <iterator>
23 #include <type_traits>
24 #include <vector>
25
26 #ifndef RENDER_PROFILER_APPLICATION
27 #include <securec.h>
28 #endif
29
30 namespace OHOS::Rosen {
31
32 enum class PackageID {
33 RS_PROFILER_HEADER,
34 RS_PROFILER_BINARY,
35 RS_PROFILER_RS_METRICS,
36 RS_PROFILER_GFX_METRICS,
37 RS_PROFILER_PREPARE,
38 RS_PROFILER_PREPARE_DONE,
39 RS_PROFILER_SKP_BINARY,
40 RS_PROFILER_RDC_BINARY,
41 RS_PROFILER_DCL_BINARY,
42 RS_PROFILER_RSTREE_DUMP_JSON,
43 RS_PROFILER_RSTREE_PERF_NODE_LIST,
44 RS_PROFILER_RSTREE_SINGLE_NODE_PERF,
45 RS_PROFILER_MSKP_FILEPATH,
46 RS_PROFILER_BETAREC_FILEPATH,
47 RS_PROFILER_RENDER_METRICS,
48 };
49
50 template<typename T, typename = void>
51 struct HasContiguousLayout : std::false_type {};
52
53 template<typename T>
54 struct HasContiguousLayout<T, std::void_t<decltype(std::declval<T>().data())>> : std::true_type {};
55
56 class Packet {
57 public:
58 enum PacketType : uint8_t {
59 BINARY,
60 COMMAND,
61 LOG,
62 UNKNOWN,
63 };
64
65 enum class Severity {
66 LOG_CRITICAL,
67 LOG_ERROR,
68 LOG_INFO,
69 LOG_DEBUG,
70 LOG_TRACE,
71 };
72
73 static constexpr size_t HEADER_SIZE = sizeof(uint32_t) + sizeof(uint8_t);
74
75 explicit Packet(PacketType type, uint32_t reserve = DEFAULT_RESERVED_SIZE);
76 Packet(const Packet&) = default;
77 Packet& operator=(const Packet&) = default;
78 Packet(Packet&&) = default;
79 Packet& operator=(Packet&&) = default;
80
81 bool IsBinary() const;
82
83 bool IsCommand() const;
84
85 char* Begin();
86
87 char* End();
88
89 PacketType GetType() const;
90 void SetType(PacketType type);
91 uint32_t GetLength() const;
92 uint32_t GetPayloadLength() const;
93
94 std::vector<char> Release();
95
96 template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
97 [[maybe_unused]] bool Read(T& value);
98
99 template<typename T>
100 [[maybe_unused]] bool Read(T& value, size_t size);
101
102 [[maybe_unused]] bool Read(void* value, size_t size);
103
104 template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
105 T Read();
106
107 template<typename T>
108 T Read(size_t size);
109
110 template<typename T>
111 [[maybe_unused]] bool Write(const T& value);
112
113 [[maybe_unused]] bool Write(const void* value, size_t size);
114
115 private:
116 void SetLength(uint32_t length);
117
118 void InitData(PacketType type);
119
120 private:
121 static constexpr size_t HEADER_TYPE_OFFSET = 0;
122 static constexpr size_t HEADER_LENGTH_OFFSET = sizeof(uint8_t);
123 static constexpr size_t DEFAULT_RESERVED_SIZE = 64;
124 size_t readPointer_ = HEADER_SIZE;
125 size_t writePointer_ = HEADER_SIZE;
126 std::vector<char> data_ = { 0, 0, 0, 0, 0 };
127 };
128
129 template<typename T, typename>
Read(T& value)130 [[maybe_unused]] inline bool Packet::Read(T& value)
131 {
132 return Read(&value, sizeof(value));
133 }
134
135 template<typename T>
Read(T& value, size_t size)136 [[maybe_unused]] bool Packet::Read(T& value, size_t size)
137 {
138 if constexpr (HasContiguousLayout<T>::value) {
139 value.resize(size);
140 return Read(value.data(), size * sizeof(typename T::value_type));
141 } else {
142 bool res = true;
143 for (size_t i = 0; i < size; ++i) {
144 typename T::value_type v {};
145 res = res && Read(v);
146 value.emplace(std::move(v));
147 }
148 return res;
149 }
150 return false;
151 }
152
153 template<typename T, typename>
Read()154 inline T Packet::Read()
155 {
156 T v {};
157 Read(v);
158 return v;
159 }
160
161 template<typename T>
Read(size_t size)162 inline T Packet::Read(size_t size)
163 {
164 T v {};
165 Read(v, size);
166 return v;
167 }
168
169 template<typename T>
Write(const T& value)170 [[maybe_unused]] bool Packet::Write(const T& value)
171 {
172 if constexpr (std::is_trivially_copyable_v<T>) {
173 return Write(&value, sizeof(value));
174 } else if constexpr (HasContiguousLayout<T>::value) {
175 return Write(value.data(), value.size() * sizeof(typename T::value_type));
176 } else {
177 bool res = true;
178 for (auto it = value.cbegin(); it != value.cend(); ++it) {
179 res = res && Write(*it);
180 }
181 return res;
182 }
183 return false;
184 }
185
186 } // namespace OHOS::Rosen
187
188 #endif // RS_PROFILER_MESSAGE_HELPER_H
189