• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_AidlProfiler"
19 
20 #include "aidl_profiler.h"
21 
22 #include <log/log.h>
23 
24 #include <memory>
25 #include <mutex>
26 #include <utility>
27 
28 #include "profiler.h"
29 
30 namespace android {
31 namespace hardware {
32 namespace camera {
33 namespace implementation {
34 namespace {
35 
36 using ::google::camera_common::Profiler;
37 
38 // setprop key for profiling open/close camera
39 constexpr char kPropKeyProfileOpenClose[] =
40     "persist.vendor.camera.profiler.open_close";
41 // setprop key for profiling camera fps
42 constexpr char kPropKeyProfileFps[] = "persist.vendor.camera.profiler.fps";
43 
44 constexpr char kFirstFrame[] = "First frame";
45 constexpr char kHalTotal[] = "HAL Total";
46 constexpr char kIdleString[] = "<-- IDLE -->";
47 constexpr char kOverall[] = "Overall";
48 
49 class AidlProfilerImpl : public AidlProfiler {
50  public:
AidlProfilerImpl(uint32_t camera_id,int32_t latency_flag,int32_t fps_flag)51   AidlProfilerImpl(uint32_t camera_id, int32_t latency_flag, int32_t fps_flag)
52       : camera_id_string_("Cam" + std::to_string(camera_id)),
53         camera_id_(camera_id),
54         latency_flag_(latency_flag),
55         fps_flag_(fps_flag) {
56   }
57 
MakeScopedProfiler(ScopedType type,std::unique_ptr<google::camera_common::Profiler> custom_latency_profiler,std::unique_ptr<google::camera_common::Profiler> custom_fps_profiler)58   std::unique_ptr<AidlScopedProfiler> MakeScopedProfiler(
59       ScopedType type,
60       std::unique_ptr<google::camera_common::Profiler> custom_latency_profiler,
61       std::unique_ptr<google::camera_common::Profiler> custom_fps_profiler)
62       override {
63     std::lock_guard lock(api_mutex_);
64     if (type == ScopedType::kConfigureStream && fps_profiler_ == nullptr) {
65       if (SetFpsProfiler(std::move(custom_fps_profiler)) == false) {
66         fps_profiler_ = CreateFpsProfiler();
67       }
68     }
69 
70     if (latency_profiler_ == nullptr) {
71       if (SetLatencyProfiler(std::move(custom_latency_profiler)) == false) {
72         latency_profiler_ = CreateLatencyProfiler();
73       }
74       if (latency_profiler_ != nullptr) {
75         has_camera_open_ = false;
76         config_count_ = 0;
77         flush_count_ = 0;
78         idle_count_ = 0;
79       } else {
80         return nullptr;
81       }
82     }
83 
84     IdleEndLocked();
85 
86     const char* name = nullptr;
87     int32_t id = 0;
88     switch (type) {
89       case ScopedType::kOpen:
90         name = "Open";
91         has_camera_open_ = true;
92         latency_profiler_->SetUseCase(camera_id_string_ + "-Open");
93         break;
94       case ScopedType::kConfigureStream:
95         name = "ConfigureStream";
96         if (!has_camera_open_) {
97           latency_profiler_->SetUseCase(camera_id_string_ + "-Reconfiguration");
98         }
99         id = config_count_++;
100         break;
101       case ScopedType::kFlush:
102         name = "Flush";
103         latency_profiler_->SetUseCase(camera_id_string_ + "-Flush");
104         id = flush_count_++;
105         break;
106       case ScopedType::kClose:
107         name = "Close";
108         latency_profiler_->SetUseCase(camera_id_string_ + "-Close");
109         break;
110       default:
111         ALOGE("%s: Unknown type %d", __FUNCTION__, type);
112         return nullptr;
113     }
114     return std::make_unique<AidlScopedProfiler>(
115         latency_profiler_, name, id, [this, type]() {
116           std::lock_guard lock(api_mutex_);
117           if (type == ScopedType::kClose) {
118             DeleteProfilerLocked();
119           } else {
120             IdleStartLocked();
121           }
122         });
123   }
124 
FirstFrameStart()125   void FirstFrameStart() override {
126     std::lock_guard lock(api_mutex_);
127     IdleEndLocked();
128     if (latency_profiler_ != nullptr) {
129       latency_profiler_->Start(kFirstFrame, Profiler::kInvalidRequestId);
130       latency_profiler_->Start(kHalTotal, Profiler::kInvalidRequestId);
131     }
132   }
133 
FirstFrameEnd()134   void FirstFrameEnd() override {
135     std::lock_guard lock(api_mutex_);
136     if (latency_profiler_ != nullptr) {
137       latency_profiler_->End(kFirstFrame, Profiler::kInvalidRequestId);
138       latency_profiler_->End(kHalTotal, Profiler::kInvalidRequestId);
139       DeleteProfilerLocked();
140     }
141   }
142 
ProfileFrameRate(const std::string & name)143   void ProfileFrameRate(const std::string& name) override {
144     std::lock_guard lock(api_mutex_);
145     if (fps_profiler_ != nullptr) {
146       fps_profiler_->ProfileFrameRate(name);
147     }
148   }
149 
150  private:
CreateLatencyProfiler()151   std::shared_ptr<Profiler> CreateLatencyProfiler() {
152     if (latency_flag_ == Profiler::SetPropFlag::kDisable) {
153       return nullptr;
154     }
155     std::shared_ptr<Profiler> profiler = Profiler::Create(latency_flag_);
156     if (profiler == nullptr) {
157       ALOGE("%s: Failed to create profiler", __FUNCTION__);
158       return nullptr;
159     }
160     profiler->SetDumpFilePrefix(
161         "/data/vendor/camera/profiler/aidl_open_close_");
162     profiler->Start(kOverall, Profiler::kInvalidRequestId);
163     return profiler;
164   }
165 
CreateFpsProfiler()166   std::shared_ptr<Profiler> CreateFpsProfiler() {
167     if (fps_flag_ == Profiler::SetPropFlag::kDisable) {
168       return nullptr;
169     }
170     std::shared_ptr<Profiler> profiler = Profiler::Create(fps_flag_);
171     if (profiler == nullptr) {
172       ALOGE("%s: Failed to create profiler", __FUNCTION__);
173       return nullptr;
174     }
175     profiler->SetDumpFilePrefix("/data/vendor/camera/profiler/aidl_fps_");
176     return profiler;
177   }
178 
DeleteProfilerLocked()179   void DeleteProfilerLocked() {
180     if (latency_profiler_ != nullptr) {
181       latency_profiler_->End(kOverall, Profiler::kInvalidRequestId);
182       latency_profiler_ = nullptr;
183     }
184   }
185 
IdleStartLocked()186   void IdleStartLocked() {
187     if (latency_profiler_ != nullptr) {
188       latency_profiler_->Start(kIdleString, idle_count_++);
189     }
190   }
191 
IdleEndLocked()192   void IdleEndLocked() {
193     if (latency_profiler_ != nullptr && idle_count_ > 0) {
194       latency_profiler_->End(kIdleString, idle_count_ - 1);
195     }
196   }
197 
GetCameraId() const198   uint32_t GetCameraId() const {
199     return camera_id_;
200   }
GetLatencyFlag() const201   int32_t GetLatencyFlag() const {
202     return latency_flag_;
203   }
GetFpsFlag() const204   int32_t GetFpsFlag() const {
205     return fps_flag_;
206   }
207 
SetLatencyProfiler(std::unique_ptr<Profiler> profiler)208   bool SetLatencyProfiler(std::unique_ptr<Profiler> profiler) {
209     if (profiler == nullptr) {
210       return false;
211     }
212     latency_profiler_ = std::move(profiler);
213     if (latency_profiler_ != nullptr) {
214       latency_profiler_->SetDumpFilePrefix(
215           "/data/vendor/camera/profiler/aidl_open_close_");
216       latency_profiler_->Start(kOverall, Profiler::kInvalidRequestId);
217       return true;
218     }
219     return false;
220   }
221 
SetFpsProfiler(std::unique_ptr<Profiler> profiler)222   bool SetFpsProfiler(std::unique_ptr<Profiler> profiler) {
223     if (profiler == nullptr) {
224       return false;
225     }
226     fps_profiler_ = std::move(profiler);
227     if (fps_profiler_ != nullptr) {
228       fps_profiler_->SetDumpFilePrefix(
229           "/data/vendor/camera/profiler/aidl_fps_");
230       return true;
231     }
232     return false;
233   }
234 
235   const std::string camera_id_string_;
236   const uint32_t camera_id_;
237   const int32_t latency_flag_;
238   const int32_t fps_flag_;
239 
240   // Protect all API functions mutually exclusive, all member variables should
241   // also be protected by this mutex.
242   std::mutex api_mutex_;
243   std::shared_ptr<Profiler> latency_profiler_;
244   std::shared_ptr<Profiler> fps_profiler_;
245   bool has_camera_open_;
246   uint8_t config_count_;
247   uint8_t flush_count_;
248   uint8_t idle_count_;
249 };
250 
251 class AidlProfilerMock : public AidlProfiler {
MakeScopedProfiler(ScopedType,std::unique_ptr<google::camera_common::Profiler>,std::unique_ptr<google::camera_common::Profiler>)252   std::unique_ptr<AidlScopedProfiler> MakeScopedProfiler(
253       ScopedType, std::unique_ptr<google::camera_common::Profiler>,
254       std::unique_ptr<google::camera_common::Profiler>) override {
255     return nullptr;
256   }
257 
FirstFrameStart()258   void FirstFrameStart() override{};
FirstFrameEnd()259   void FirstFrameEnd() override{};
ProfileFrameRate(const std::string &)260   void ProfileFrameRate(const std::string&) override{};
261 
GetCameraId() const262   uint32_t GetCameraId() const override {
263     return 0;
264   }
GetLatencyFlag() const265   int32_t GetLatencyFlag() const override {
266     return 0;
267   }
GetFpsFlag() const268   int32_t GetFpsFlag() const override {
269     return 0;
270   }
271 };
272 
273 }  // anonymous namespace
274 
Create(uint32_t camera_id)275 std::shared_ptr<AidlProfiler> AidlProfiler::Create(uint32_t camera_id) {
276   int32_t latency_flag = property_get_int32(
277       kPropKeyProfileOpenClose, Profiler::SetPropFlag::kCustomProfiler);
278   int32_t fps_flag = property_get_int32(kPropKeyProfileFps,
279                                         Profiler::SetPropFlag::kCustomProfiler);
280   if (latency_flag == Profiler::SetPropFlag::kDisable &&
281       fps_flag == Profiler::SetPropFlag::kDisable) {
282     return std::make_shared<AidlProfilerMock>();
283   }
284   // Use stopwatch flag to print result.
285   if ((latency_flag & Profiler::SetPropFlag::kPrintBit) != 0) {
286     latency_flag |= Profiler::SetPropFlag::kStopWatch;
287   }
288   // Use interval flag to print fps instead of print on end.
289   if ((fps_flag & Profiler::SetPropFlag::kPrintBit) != 0) {
290     fps_flag |= Profiler::SetPropFlag::kPrintFpsPerIntervalBit;
291     fps_flag &= ~Profiler::SetPropFlag::kPrintBit;
292   }
293   return std::make_shared<AidlProfilerImpl>(camera_id, latency_flag, fps_flag);
294 }
295 
AidlScopedProfiler(std::shared_ptr<Profiler> profiler,const std::string name,int id,std::function<void ()> end_callback)296 AidlScopedProfiler::AidlScopedProfiler(std::shared_ptr<Profiler> profiler,
297                                        const std::string name, int id,
298                                        std::function<void()> end_callback)
299     : profiler_(profiler),
300       name_(std::move(name)),
301       id_(id),
302       end_callback_(end_callback) {
303   profiler_->Start(name_, id_);
304   profiler_->Start(kHalTotal, Profiler::kInvalidRequestId);
305 }
306 
~AidlScopedProfiler()307 AidlScopedProfiler::~AidlScopedProfiler() {
308   profiler_->End(kHalTotal, Profiler::kInvalidRequestId);
309   profiler_->End(name_, id_);
310   if (end_callback_) {
311     end_callback_();
312   }
313 }
314 
315 }  // namespace implementation
316 }  // namespace camera
317 }  // namespace hardware
318 }  // namespace android
319