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 RS_PROFILER_RS_EVENT, 49 }; 50 51 template<typename T, typename = void> 52 struct HasContiguousLayout : std::false_type {}; 53 54 template<typename T> 55 struct HasContiguousLayout<T, std::void_t<decltype(std::declval<T>().data())>> : std::true_type {}; 56 57 class Packet { 58 public: 59 enum PacketType : uint8_t { 60 BINARY, 61 COMMAND, 62 LOG, 63 UNKNOWN, 64 }; 65 66 enum class Severity { 67 LOG_CRITICAL, 68 LOG_ERROR, 69 LOG_INFO, 70 LOG_DEBUG, 71 LOG_TRACE, 72 }; 73 74 static constexpr size_t HEADER_SIZE = sizeof(uint32_t) + sizeof(uint8_t); 75 76 explicit Packet(PacketType type, uint32_t reserve = DEFAULT_RESERVED_SIZE); 77 Packet(const Packet&) = default; 78 Packet& operator=(const Packet&) = default; 79 Packet(Packet&&) = default; 80 Packet& operator=(Packet&&) = default; 81 82 bool IsBinary() const; 83 84 bool IsCommand() const; 85 86 char* Begin(); 87 88 char* End(); 89 90 PacketType GetType() const; 91 void SetType(PacketType type); 92 uint32_t GetLength() const; 93 uint32_t GetPayloadLength() const; 94 95 std::vector<char> Release(); 96 97 template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>> 98 [[maybe_unused]] bool Read(T& value); 99 100 template<typename T> 101 [[maybe_unused]] bool Read(T& value, size_t size); 102 103 [[maybe_unused]] bool Read(void* value, size_t size); 104 105 template<typename T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>> 106 T Read(); 107 108 template<typename T> 109 T Read(size_t size); 110 111 template<typename T> 112 [[maybe_unused]] bool Write(const T& value); 113 114 [[maybe_unused]] bool Write(const void* value, size_t size); 115 116 private: 117 void SetLength(uint32_t length); 118 119 void InitData(PacketType type); 120 121 private: 122 static constexpr size_t HEADER_TYPE_OFFSET = 0; 123 static constexpr size_t HEADER_LENGTH_OFFSET = sizeof(uint8_t); 124 static constexpr size_t DEFAULT_RESERVED_SIZE = 64; 125 size_t readPointer_ = HEADER_SIZE; 126 size_t writePointer_ = HEADER_SIZE; 127 std::vector<char> data_ = { 0, 0, 0, 0, 0 }; 128 }; 129 130 template<typename T, typename> 131 [[maybe_unused]] inline bool Packet::Read(T& value) 132 { 133 return Read(&value, sizeof(value)); 134 } 135 136 template<typename T> 137 [[maybe_unused]] bool Packet::Read(T& value, size_t size) 138 { 139 if constexpr (HasContiguousLayout<T>::value) { 140 value.resize(size); 141 return Read(value.data(), size * sizeof(typename T::value_type)); 142 } else { 143 bool res = true; 144 for (size_t i = 0; i < size; ++i) { 145 typename T::value_type v {}; 146 res = res && Read(v); 147 value.emplace(std::move(v)); 148 } 149 return res; 150 } 151 return false; 152 } 153 154 template<typename T, typename> 155 inline T Packet::Read() 156 { 157 T v {}; 158 Read(v); 159 return v; 160 } 161 162 template<typename T> 163 inline T Packet::Read(size_t size) 164 { 165 T v {}; 166 Read(v, size); 167 return v; 168 } 169 170 template<typename T> 171 [[maybe_unused]] bool Packet::Write(const T& value) 172 { 173 if constexpr (std::is_trivially_copyable_v<T>) { 174 return Write(&value, sizeof(value)); 175 } else if constexpr (HasContiguousLayout<T>::value) { 176 return Write(value.data(), value.size() * sizeof(typename T::value_type)); 177 } else { 178 bool res = true; 179 for (auto it = value.cbegin(); it != value.cend(); ++it) { 180 res = res && Write(*it); 181 } 182 return res; 183 } 184 return false; 185 } 186 187 } // namespace OHOS::Rosen 188 189 #endif // RS_PROFILER_MESSAGE_HELPER_H 190