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