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_TrackedProfiler"
19 #include "tracked_profiler.h"
20 
21 #include <log/log.h>
22 
23 #include <cstdint>
24 #include <memory>
25 #include <mutex>
26 
27 #include "aidl_profiler.h"
28 #include "profiler.h"
29 #include "profiler_util.h"
30 
31 namespace android {
32 namespace google_camera_hal {
33 
34 using ::google::camera_common::Profiler;
35 
SetUseCase(std::string name)36 void TrackedProfiler::SetUseCase(std::string name) {
37   profiler_->SetUseCase(name);
38 }
39 
ShouldDelete(EventType incoming)40 bool TrackedProfiler::ShouldDelete(EventType incoming) {
41   if (incoming == EventType::kOpen &&
42       (state_ == EventType::kConfigureStream || state_ == EventType::kOpen)) {
43     return true;
44   }
45   if (state_ == EventType::kFirstFrameEnd || state_ == EventType::kClose) {
46     return true;
47   }
48   return false;
49 }
50 
UpdateStateLocked(EventType incoming)51 void TrackedProfiler::UpdateStateLocked(EventType incoming) {
52   state_ = incoming;
53 }
54 
AcceptNextState(EventType incoming)55 std::unique_ptr<AidlScopedProfiler> TrackedProfiler::AcceptNextState(
56     EventType incoming) {
57   std::lock_guard<std::mutex> lock(tracked_api_mutex_);
58   int32_t id = 0;
59   switch (state_) {
60     case (EventType::kNone):
61       if (incoming == EventType::kOpen) {
62         SetUseCase(camera_id_string_ + "-Open");
63         break;
64       } else if (incoming == EventType::kFlush) {
65         break;
66       }
67       return nullptr;
68     case (EventType::kOpen):
69       if (incoming == EventType::kConfigureStream) {
70         break;
71       }
72       return nullptr;
73     case (EventType::kConfigureStream):
74       if (incoming == EventType::kConfigureStream ||
75           incoming == EventType::kFirstFrameStart) {
76         break;
77       }
78       return nullptr;
79     case (EventType::kFirstFrameStart):
80       if (incoming == EventType::kFirstFrameEnd) {
81         break;
82       }
83       return nullptr;
84     case (EventType::kFlush):
85       if (incoming == EventType::kFlush || incoming == EventType::kClose) {
86         SetUseCase(camera_id_string_ + "-Close");
87         break;
88       }
89       if (incoming == EventType::kConfigureStream) {
90         SetUseCase(camera_id_string_ + "-Reconfiguration");
91         break;
92       }
93       return nullptr;
94     case (EventType::kClose):
95       return nullptr;
96     case (EventType::kFirstFrameEnd):
97       ALOGE("%s: Warning: Operation %s should have already been deleted.",
98             __FUNCTION__, EventTypeToString(state_).c_str());
99       return nullptr;
100   }
101   UpdateStateLocked(incoming);
102   IdleEndLocked();
103   if (incoming == EventType::kConfigureStream) {
104     id = config_count_++;
105   } else if (incoming == EventType::kFlush) {
106     id = flush_count_++;
107   }
108 
109   return std::make_unique<AidlScopedProfiler>(
110       profiler_, EventTypeToString(incoming), id, [this, incoming]() {
111         if (incoming == EventType::kClose) {
112           DeleteProfiler();
113         } else {
114           IdleStart();
115         }
116       });
117 }
118 
AcceptFirstFrameStart()119 bool TrackedProfiler::AcceptFirstFrameStart() {
120   std::lock_guard<std::mutex> lock(tracked_api_mutex_);
121   if (state_ == EventType::kConfigureStream) {
122     UpdateStateLocked(EventType::kFirstFrameStart);
123     IdleEndLocked();
124     profiler_->Start(kFirstFrame, Profiler::kInvalidRequestId);
125     profiler_->Start(kHalTotal, Profiler::kInvalidRequestId);
126     return true;
127   }
128   return false;
129 }
130 
AcceptFirstFrameEnd()131 bool TrackedProfiler::AcceptFirstFrameEnd() {
132   std::lock_guard<std::mutex> lock(tracked_api_mutex_);
133   if (state_ == EventType::kFirstFrameStart) {
134     UpdateStateLocked(EventType::kFirstFrameEnd);
135     profiler_->End(kFirstFrame, Profiler::kInvalidRequestId);
136     profiler_->End(kHalTotal, Profiler::kInvalidRequestId);
137     DeleteProfilerLocked();
138     return true;
139   }
140   return false;
141 }
142 
DeleteProfilerLocked()143 void TrackedProfiler::DeleteProfilerLocked() {
144   if (profiler_ != nullptr) {
145     profiler_->End(kOverall, Profiler::kInvalidRequestId);
146     profiler_ = nullptr;  // Deletes the camera_latency_profiler, causing it
147                           // to write the data to the Camer latency analyzer
148   }
149 }
150 
DeleteProfiler()151 void TrackedProfiler::DeleteProfiler() {
152   std::lock_guard<std::mutex> lock(tracked_api_mutex_);
153   DeleteProfilerLocked();
154 }
155 
IdleStartLocked()156 void TrackedProfiler::IdleStartLocked() {
157   if (idle_start_count_ > idle_end_count_) {
158     ALOGE("%s: Error: Starting another idle before previous finished.",
159           __FUNCTION__);
160   } else if (idle_start_count_ < idle_end_count_) {
161     ALOGE("%s: Error: More idles have finished than have started.",
162           __FUNCTION__);
163   }
164   if (profiler_ != nullptr) {
165     profiler_->Start(kIdleString, idle_start_count_++);
166   }
167 }
168 
IdleStart()169 void TrackedProfiler::IdleStart() {
170   std::lock_guard<std::mutex> lock(tracked_api_mutex_);
171   IdleStartLocked();
172 }
173 
IdleEndLocked()174 void TrackedProfiler::IdleEndLocked() {
175   if (profiler_ != nullptr && idle_start_count_ - 1 == idle_end_count_) {
176     profiler_->End(kIdleString, idle_end_count_++);
177   }
178 }
179 
180 }  // namespace google_camera_hal
181 }  // namespace android