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