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 // 43 // By default the profiler is disabled. 44 // 45 // Usage: 46 // 1. To Create a profiler, please call Profiler::Create(...). 47 // 2. Use Start() and End() to profile the enclosed code snippet. 48 // 3. Use SetUseCase to specify the name of the profiling target (purpose). 49 // 4 If you want to dump the profiling data to the disk, call 50 // SetDumpFilePrefix(), which is default to "/vendor/camera/profiler/". 51 // The dumped file name is the prefix name + usecase name. 52 // 53 // Example Code: 54 // In the following example, we use a for loop to profile two fucntions Foo() 55 // and Bar; Foo() run once, and Bar() run twice. 56 // 57 // std::unique_ptr<Profiler> profiler = Profiler::Create(Profiler::kPrintBit); 58 // profiler->SetUseCase("Profiling Example"); 59 // 60 // for (int i = 0; i < 100; i++) { 61 // profiler->Start("Foo function", i); 62 // Foo() 63 // profiler->End("Foo function", i); 64 // 65 // profiler->Start("Bar function", i); 66 // Bar() 67 // profiler->End("Bar function", i); 68 // 69 // profiler->Start("Bar function", i); 70 // Bar() 71 // profiler->End("Bar function", i); 72 // } 73 // 74 // Example Print Out: 75 // 76 // UseCase: Profiling Example. Profiled Frames: 100. 77 // Foo function Max: 0.012 ms. Avg: 0.020 ms x 1 = 0.040 ms 78 // Bar function Max: 0.008 ms. Avg: 0.019 ms x 2 = 0.039 ms 79 // SUM OF MAX: 0.020 ms, SUM OF AVG = 0.079 ms 80 // 81 class Profiler { 82 public: 83 // Invalid request id. 84 static constexpr int kInvalidRequestId = std::numeric_limits<int>::max(); 85 86 // Create profiler. 87 static std::shared_ptr<Profiler> Create(int option); 88 ~Profiler()89 virtual ~Profiler(){}; 90 91 // adb setprop options. 92 enum SetPropFlag { 93 kDisable = 0, 94 kPrintBit = 1 << 0, 95 kDumpBit = 1 << 1, 96 kStopWatch = 1 << 2 97 }; 98 99 // Setup the name of use case the profiler is running. 100 // Argument: 101 // usecase: the name use case of the profiler is running. 102 virtual void SetUseCase(std::string usecase) = 0; 103 104 // Set the file prefix name for dumpping the profiling file. 105 // Argument: 106 // dump_file_prefix: file prefix name. In the current setting, 107 // "/data/vendor/camera/" is a valid folder for camera to dump file. 108 // A valid prefix can be "/data/vendor/camera/test_prefix_". 109 virtual void SetDumpFilePrefix(std::string dump_file_prefix) = 0; 110 111 // Start to profile. 112 // We use start and end to choose which code snippet to be profile. 113 // The user specifies the name, and the profiler will print the name and its 114 // timing. 115 // Arguments: 116 // name: the name of the node to be profiled. 117 // request_id: frame requesd id. 118 virtual void Start(const std::string name, int request_id) = 0; 119 120 // End the profileing. 121 // Arguments: 122 // name: the name of the node to be profiled. Should be the same in Start(). 123 // request_id: frame requesd id. 124 virtual void End(const std::string name, int request_id) = 0; 125 126 // Print out the profiling result in the standard output (ANDROID_LOG_ERROR). 127 virtual void PrintResult() = 0; 128 129 protected: Profiler()130 Profiler(){}; 131 }; 132 133 // A scoped utility class to facilitate profiling. 134 class ScopedProfiler { 135 public: 136 // Constructor. 137 // Arguments: 138 // profiler: profiler object. 139 // target: the name of the target to be profiled. 140 // request_id: frame requesd id. ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target,int request_id)141 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target, 142 int request_id) 143 : profiler_(profiler), 144 target_(std::move(target)), 145 request_id_(request_id) { 146 profiler_->Start(target_, request_id_); 147 } 148 ScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string target)149 ScopedProfiler(std::shared_ptr<Profiler> profiler, const std::string target) 150 : profiler_(profiler), target_(std::move(target)) { 151 request_id_ = Profiler::kInvalidRequestId; 152 profiler_->Start(target_, request_id_); 153 } 154 ScopedProfiler(const std::string target,int option)155 ScopedProfiler(const std::string target, int option) 156 : target_(std::move(target)) { 157 profiler_ = Profiler::Create(option); 158 request_id_ = Profiler::kInvalidRequestId; 159 profiler_->Start(target_, request_id_); 160 } 161 ~ScopedProfiler()162 ~ScopedProfiler() { 163 profiler_->End(target_, request_id_); 164 } 165 166 private: 167 std::shared_ptr<Profiler> profiler_; 168 const std::string target_; 169 int request_id_; 170 }; 171 172 } // namespace camera_common 173 } // namespace google 174 175 #endif // HARDWARE_GOOGLE_CAMERA_COMMON_PROFILER_H 176