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 <list> 24 #include <memory> 25 #include <string> 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 // adb setprop options. 154 enum SetPropFlag { 155 kDisable = 0, 156 kPrintBit = 1 << 0, 157 kDumpBit = 1 << 1, 158 kStopWatch = 1 << 2, 159 // Print FPS per interval time based on the value of SetFpsPrintInterval() 160 kPrintFpsPerIntervalBit = 1 << 3, 161 // Calculate FPS on process end function instead of process start function 162 kCalculateFpsOnEndBit = 1 << 4, 163 // Dynamic start profiling. 164 kDynamicStartBit = 1 << 5, 165 // Dumps result using proto format. 166 kProto = 1 << 6, 167 // Customized profiler derived from Profiler 168 kCustomProfiler = 1 << 7, 169 }; 170 171 // Setup the name of use case the profiler is running. 172 // Argument: 173 // usecase: the name use case of the profiler is running. 174 virtual void SetUseCase(std::string usecase) = 0; 175 176 // Set the file prefix name for dumpping the profiling file. 177 // Argument: 178 // dump_file_prefix: file prefix name. In the current setting, 179 // "/data/vendor/camera/" is a valid folder for camera to dump file. 180 // A valid prefix can be "/data/vendor/camera/test_prefix_". 181 virtual void SetDumpFilePrefix(const std::string& dump_file_prefix) = 0; 182 183 // Start to profile. 184 // We use start and end to choose which code snippet to be profile. 185 // The user specifies the name, and the profiler will print the name and its 186 // timing. 187 // Arguments: 188 // name: the name of the node to be profiled. 189 // request_id: frame requesd id. 190 virtual void Start(const std::string& name, int request_id) = 0; 191 192 // End the profileing. 193 // Arguments: 194 // name: the name of the node to be profiled. Should be the same in Start(). 195 // request_id: frame requesd id. 196 virtual void End(const std::string& name, int request_id) = 0; 197 198 // Print out the profiling result in the standard output (ANDROID_LOG_ERROR). 199 virtual void PrintResult() = 0; 200 201 // Profile the frame rate 202 // If only call this function without start() and End(), 203 // creating profiler needs to set option with kPrintFpsPerIntervalBit bit. 204 // It can print FPS every second. 205 virtual void ProfileFrameRate(const std::string& name) = 0; 206 207 // Set the interval of FPS print 208 // The interval unit is second and interval_seconds must >= 1 209 virtual void SetFpsPrintInterval(int32_t interval_seconds) = 0; 210 211 virtual std::list<std::pair<std::string, float>> GetLatencyData() = 0; 212 213 virtual std::string GetUseCase() const = 0; 214 215 protected: 216 Profiler() = default; 217 }; 218 219 // A scoped utility class to facilitate profiling. 220 class ScopedProfiler { 221 public: 222 // Constructor. 223 // Arguments: 224 // profiler: profiler object. 225 // target: the name of the target to be profiled. 226 // request_id: frame requesd id. ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target,int request_id)227 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target, 228 int request_id) 229 : profiler_(profiler), 230 target_(std::move(target)), 231 request_id_(request_id) { 232 profiler_->Start(target_, request_id_); 233 } 234 ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target)235 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target) 236 : profiler_(profiler), target_(std::move(target)) { 237 request_id_ = Profiler::kInvalidRequestId; 238 profiler_->Start(target_, request_id_); 239 } 240 ScopedProfiler(const std::string target,int option)241 ScopedProfiler(const std::string target, int option) 242 : target_(std::move(target)) { 243 profiler_ = Profiler::Create(option); 244 request_id_ = Profiler::kInvalidRequestId; 245 profiler_->Start(target_, request_id_); 246 } 247 ~ScopedProfiler()248 ~ScopedProfiler() { 249 profiler_->End(target_, request_id_); 250 } 251 252 private: 253 std::shared_ptr<Profiler> profiler_; 254 const std::string target_; 255 int request_id_; 256 }; 257 258 } // namespace camera_common 259 } // namespace google 260 261 #endif // HARDWARE_GOOGLE_CAMERA_COMMON_PROFILER_H 262