1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef HARDWARE_GOOGLE_CAMERA_COMMON_PROFILER_H 18 #define HARDWARE_GOOGLE_CAMERA_COMMON_PROFILER_H 19 20 #include <cutils/properties.h> 21 22 #include <limits> 23 #include <memory> 24 #include <string> 25 #include <vector> 26 27 namespace google { 28 namespace camera_common { 29 30 // The goal of the Profiler is to profile the performance of camemra pipeline. 31 // However you can use it profile any procedure. 32 // The profiler prints out the result when the Profiler obejct is deconstructed. 33 // 34 // Setprops: 35 // - To disable the profiler: 36 // $ adb shell setprop persist.vendor.camera.profiler 0 37 // - To print the profiling result in standard output: 38 // $ adb shell setprop persist.vendor.camera.profiler 1 39 // - To dump the profiling result to "/data/vendor/camera/profiler": 40 // $ adb shell setprop persist.vendor.camera.profiler 2 41 // - To print and dump the profiling result to "/data/vendor/camera/profiler": 42 // $ adb shell setprop persist.vendor.camera.profiler 3 43 // After add FPS option, here are the combination results. 44 // Option 0 (kDisable): Disable Profiler 45 // Option 1 (kPrintBit): 46 // When close, Print the result 47 // - Processing time 48 // - FPS with total frames on process start function 49 // Option 2 (kDumpBit): 50 // When close, dump the result to file(dump_file_prefix) 51 // - Processing time 52 // - FPS with total frames on process start function 53 // Option 3 (kPrintBit|kDumpBit): 54 // When close, print and dump the result 55 // - Processing time 56 // - FPS with total frames on process start function 57 // Option 8 (kPrintFpsPerIntervalBit): 58 // Print FPS per interval on ProfileFrameRate function 59 // The frequency is based on the value of SetFpsPrintInterval() 60 // Option 9 (kPrintFpsPerIntervalBit|kPrintBit): 61 // Print FPS per interval on process start and ProfileFrameRate function 62 // When close, print the result 63 // - Processing time 64 // - FPS with total frames on process start function 65 // Option 10 (kPrintFpsPerIntervalBit|kDumpBit): 66 // Print FPS per interval on process start and ProfileFrameRate function 67 // When close, dump the result 68 // - Processing time 69 // - FPS with total frames on process start function 70 // Option 11 (kPrintFpsPerIntervalBit|kPrintBit|kDumpBit): 71 // Print FPS per interval on process start and ProfileFrameRate function 72 // When close, print and dump the result 73 // - Processing time 74 // - FPS with total frames on process start function 75 // Option 16 (kCalculateFpsOnEndBit): 76 // Calculate FPS on process end function instead of process start function 77 // Option 17 (kCalculateFpsOnEndBit|kPrintBit): 78 // When close, print the result 79 // - Processing time 80 // - FPS with total frames on process "end" function 81 // Option 18 (kCalculateFpsOnEndBit|kDumpBit): 82 // When close, dump the result 83 // - Processing time 84 // - FPS with total frames on process "end" function 85 // Option 19 (kCalculateFpsOnEndBit|kPrintBitk|DumpBit): 86 // When close, print and dump the result 87 // - Processing time 88 // - FPS with total frames on process "end" function 89 // Option 25 (kCalculateFpsOnEndBit|kPrintFpsPerIntervalBit|kPrintBit): 90 // Print FPS per interval on process start and ProfileFrameRate function 91 // When close, print the result 92 // - Processing time 93 // - FPS with total frames on process "end" function 94 // Option 26 (kCalculateFpsOnEndBit|kPrintFpsPerIntervalBit|DumpBit): 95 // Print FPS per interval on process start and ProfileFrameRate function 96 // When close, dump the result 97 // - Processing time 98 // - FPS with total frames on process "end" function 99 // Option 27 (kCalculateFpsOnEndBit|kPrintFpsPerIntervalBit|kPrintBitk|DumpBit): 100 // Print FPS per interval on process start and ProfileFrameRate function 101 // When close, print and dump the result 102 // - Processing time 103 // - FPS with total frames on process "end" function 104 // 105 // By default the profiler is disabled. 106 // 107 // Usage: 108 // 1. To Create a profiler, please call Profiler::Create(...). 109 // 2. Use Start() and End() to profile the enclosed code snippet. 110 // 3. Use SetUseCase to specify the name of the profiling target (purpose). 111 // 4 If you want to dump the profiling data to the disk, call 112 // SetDumpFilePrefix(), which is default to "/vendor/camera/profiler/". 113 // The dumped file name is the prefix name + usecase name. 114 // 115 // Example Code: 116 // In the following example, we use a for loop to profile two fucntions Foo() 117 // and Bar; Foo() run once, and Bar() run twice. 118 // 119 // std::unique_ptr<Profiler> profiler = Profiler::Create(Profiler::kPrintBit); 120 // profiler->SetUseCase("Profiling Example"); 121 // 122 // for (int i = 0; i < 100; i++) { 123 // profiler->Start("Foo function", i); 124 // Foo() 125 // profiler->End("Foo function", i); 126 // 127 // profiler->Start("Bar function", i); 128 // Bar() 129 // profiler->End("Bar function", i); 130 // 131 // profiler->Start("Bar function", i); 132 // Bar() 133 // profiler->End("Bar function", i); 134 // } 135 // 136 // Example Print Out: 137 // 138 // UseCase: Profiling Example. Profiled Frames: 100. 139 // Foo function Max: 0.012 ms. Avg: 0.020 ms x 1 = 0.040 ms 140 // Bar function Max: 0.008 ms. Avg: 0.019 ms x 2 = 0.039 ms 141 // SUM OF MAX: 0.020 ms, SUM OF AVG = 0.079 ms 142 // 143 class Profiler { 144 public: 145 // Invalid request id. 146 static constexpr int kInvalidRequestId = std::numeric_limits<int>::max(); 147 148 // Create profiler. 149 static std::shared_ptr<Profiler> Create(int option); 150 151 virtual ~Profiler() = default; 152 153 struct LatencyEvent { 154 std::string name; 155 float duration; 156 }; 157 158 // adb setprop options. 159 enum SetPropFlag { 160 kDisable = 0, 161 kPrintBit = 1 << 0, 162 kDumpBit = 1 << 1, 163 kStopWatch = 1 << 2, 164 // Print FPS per interval time based on the value of SetFpsPrintInterval() 165 kPrintFpsPerIntervalBit = 1 << 3, 166 // Calculate FPS on process end function instead of process start function 167 kCalculateFpsOnEndBit = 1 << 4, 168 // Dynamic start profiling. 169 kDynamicStartBit = 1 << 5, 170 // Dumps result using proto format. 171 kProto = 1 << 6, 172 // Customized profiler derived from Profiler 173 kCustomProfiler = 1 << 7, 174 }; 175 176 // Setup the name of use case the profiler is running. 177 // Argument: 178 // usecase: the name use case of the profiler is running. 179 virtual void SetUseCase(std::string usecase) = 0; 180 181 // Set the file prefix name for dumpping the profiling file. 182 // Argument: 183 // dump_file_prefix: file prefix name. In the current setting, 184 // "/data/vendor/camera/" is a valid folder for camera to dump file. 185 // A valid prefix can be "/data/vendor/camera/test_prefix_". 186 virtual void SetDumpFilePrefix(const std::string& dump_file_prefix) = 0; 187 188 // Start to profile. 189 // We use start and end to choose which code snippet to be profile. 190 // The user specifies the name, and the profiler will print the name and its 191 // timing. 192 // Arguments: 193 // name: the name of the node to be profiled. 194 // request_id: frame requesd id. 195 virtual void Start(const std::string& name, int request_id) = 0; 196 197 // End the profileing. 198 // Arguments: 199 // name: the name of the node to be profiled. Should be the same in Start(). 200 // request_id: frame requesd id. 201 virtual void End(const std::string& name, int request_id) = 0; 202 203 // Print out the profiling result in the standard output (ANDROID_LOG_ERROR). 204 virtual void PrintResult() = 0; 205 206 // Profile the frame rate 207 // If only call this function without start() and End(), 208 // creating profiler needs to set option with kPrintFpsPerIntervalBit bit. 209 // It can print FPS every second. 210 virtual void ProfileFrameRate(const std::string& name) = 0; 211 212 // Set the interval of FPS print 213 // The interval unit is second and interval_seconds must >= 1 214 virtual void SetFpsPrintInterval(int32_t interval_seconds) = 0; 215 216 virtual std::vector<LatencyEvent> GetLatencyData() = 0; 217 218 virtual std::string GetUseCase() const = 0; 219 220 protected: 221 Profiler() = default; 222 }; 223 224 // A scoped utility class to facilitate profiling. 225 class ScopedProfiler { 226 public: 227 // Constructor. 228 // Arguments: 229 // profiler: profiler object. 230 // target: the name of the target to be profiled. 231 // request_id: frame requesd id. ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target,int request_id)232 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target, 233 int request_id) 234 : profiler_(profiler), 235 target_(std::move(target)), 236 request_id_(request_id) { 237 profiler_->Start(target_, request_id_); 238 } 239 ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target)240 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target) 241 : profiler_(profiler), target_(std::move(target)) { 242 request_id_ = Profiler::kInvalidRequestId; 243 profiler_->Start(target_, request_id_); 244 } 245 ScopedProfiler(const std::string target,int option)246 ScopedProfiler(const std::string target, int option) 247 : target_(std::move(target)) { 248 profiler_ = Profiler::Create(option); 249 request_id_ = Profiler::kInvalidRequestId; 250 profiler_->Start(target_, request_id_); 251 } 252 ~ScopedProfiler()253 ~ScopedProfiler() { 254 profiler_->End(target_, request_id_); 255 } 256 257 private: 258 std::shared_ptr<Profiler> profiler_; 259 const std::string target_; 260 int request_id_; 261 }; 262 263 } // namespace camera_common 264 } // namespace google 265 266 #endif // HARDWARE_GOOGLE_CAMERA_COMMON_PROFILER_H 267