/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // #define LOG_NDEBUG 0 #define LOG_TAG "GCH_TrackedProfiler" #include "tracked_profiler.h" #include #include #include #include #include "aidl_profiler.h" #include "profiler.h" #include "profiler_util.h" namespace android { namespace google_camera_hal { using ::google::camera_common::Profiler; void TrackedProfiler::SetUseCase(std::string name) { profiler_->SetUseCase(name); } bool TrackedProfiler::ShouldDelete(EventType incoming) { if (incoming == EventType::kOpen && (state_ == EventType::kConfigureStream || state_ == EventType::kOpen)) { return true; } if (state_ == EventType::kFirstFrameEnd || state_ == EventType::kClose) { return true; } return false; } void TrackedProfiler::UpdateStateLocked(EventType incoming) { state_ = incoming; } std::unique_ptr TrackedProfiler::AcceptNextState( EventType incoming) { std::lock_guard lock(tracked_api_mutex_); int32_t id = 0; switch (state_) { case (EventType::kNone): if (incoming == EventType::kOpen) { SetUseCase(camera_id_string_ + "-Open"); break; } else if (incoming == EventType::kFlush) { break; } return nullptr; case (EventType::kOpen): if (incoming == EventType::kConfigureStream) { break; } return nullptr; case (EventType::kConfigureStream): if (incoming == EventType::kConfigureStream || incoming == EventType::kFirstFrameStart) { break; } return nullptr; case (EventType::kFirstFrameStart): if (incoming == EventType::kFirstFrameEnd) { break; } return nullptr; case (EventType::kFlush): if (incoming == EventType::kFlush || incoming == EventType::kClose) { SetUseCase(camera_id_string_ + "-Close"); break; } if (incoming == EventType::kConfigureStream) { SetUseCase(camera_id_string_ + "-Reconfiguration"); break; } return nullptr; case (EventType::kClose): return nullptr; case (EventType::kFirstFrameEnd): ALOGE("%s: Warning: Operation %s should have already been deleted.", __FUNCTION__, EventTypeToString(state_).c_str()); return nullptr; } UpdateStateLocked(incoming); IdleEndLocked(); if (incoming == EventType::kConfigureStream) { id = config_count_++; } else if (incoming == EventType::kFlush) { id = flush_count_++; } return std::make_unique( profiler_, EventTypeToString(incoming), id, [this, incoming]() { if (incoming == EventType::kClose) { DeleteProfiler(); } else { IdleStart(); } }); } bool TrackedProfiler::AcceptFirstFrameStart() { std::lock_guard lock(tracked_api_mutex_); if (state_ == EventType::kConfigureStream) { UpdateStateLocked(EventType::kFirstFrameStart); IdleEndLocked(); profiler_->Start(kFirstFrame, Profiler::kInvalidRequestId); profiler_->Start(kHalTotal, Profiler::kInvalidRequestId); return true; } return false; } bool TrackedProfiler::AcceptFirstFrameEnd() { std::lock_guard lock(tracked_api_mutex_); if (state_ == EventType::kFirstFrameStart) { UpdateStateLocked(EventType::kFirstFrameEnd); profiler_->End(kFirstFrame, Profiler::kInvalidRequestId); profiler_->End(kHalTotal, Profiler::kInvalidRequestId); DeleteProfilerLocked(); return true; } return false; } void TrackedProfiler::DeleteProfilerLocked() { if (profiler_ != nullptr) { profiler_->End(kOverall, Profiler::kInvalidRequestId); profiler_ = nullptr; // Deletes the camera_latency_profiler, causing it // to write the data to the Camer latency analyzer } } void TrackedProfiler::DeleteProfiler() { std::lock_guard lock(tracked_api_mutex_); DeleteProfilerLocked(); } void TrackedProfiler::IdleStartLocked() { if (idle_start_count_ > idle_end_count_) { ALOGE("%s: Error: Starting another idle before previous finished.", __FUNCTION__); } else if (idle_start_count_ < idle_end_count_) { ALOGE("%s: Error: More idles have finished than have started.", __FUNCTION__); } if (profiler_ != nullptr) { profiler_->Start(kIdleString, idle_start_count_++); } } void TrackedProfiler::IdleStart() { std::lock_guard lock(tracked_api_mutex_); IdleStartLocked(); } void TrackedProfiler::IdleEndLocked() { if (profiler_ != nullptr && idle_start_count_ - 1 == idle_end_count_) { profiler_->End(kIdleString, idle_end_count_++); } } } // namespace google_camera_hal } // namespace android