1cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen/* 2cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * Copyright 2016 The Android Open Source Project 3cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * 4cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 5cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * you may not use this file except in compliance with the License. 6cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * You may obtain a copy of the License at 7cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * 8cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * http://www.apache.org/licenses/LICENSE-2.0 9cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * 10cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * Unless required by applicable law or agreed to in writing, software 11cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * distributed under the License is distributed on an "AS IS" BASIS, 12cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * See the License for the specific language governing permissions and 14cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen * limitations under the License. 15cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen */ 16cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 17cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen#include "request_tracker.h" 18cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 19cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen// #define LOG_NDEBUG 0 20cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen#define LOG_TAG "RequestTracker" 21cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen#include <cutils/log.h> 22cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 23cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohennamespace default_camera_hal { 24cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 25cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-CohenRequestTracker::RequestTracker() {} 26cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 27cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-CohenRequestTracker::~RequestTracker() {} 28cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 29cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenvoid RequestTracker::SetStreamConfiguration( 30cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen const camera3_stream_configuration_t& config) { 31cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Clear the old configuration. 32cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen ClearStreamConfiguration(); 33cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Add an entry to the buffer tracking map for each configured stream. 34cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen for (size_t i = 0; i < config.num_streams; ++i) { 35cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen buffers_in_flight_.emplace(config.streams[i], 0); 36cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 37cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 38cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 39cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenvoid RequestTracker::ClearStreamConfiguration() { 40cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // The keys of the in flight buffer map are the configured streams. 41cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen buffers_in_flight_.clear(); 42cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 43cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 44cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen// Helper: get the streams used by a request. 45cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenstd::set<camera3_stream_t*> RequestStreams(const CaptureRequest& request) { 46cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen std::set<camera3_stream_t*> result; 47cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (request.input_buffer) { 48cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen result.insert(request.input_buffer->stream); 49cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 50cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen for (const auto& output_buffer : request.output_buffers) { 51cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen result.insert(output_buffer.stream); 52cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 53cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return std::move(result); 54cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 55cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 560b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohenbool RequestTracker::Add(std::shared_ptr<CaptureRequest> request) { 57cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (!CanAddRequest(*request)) { 58cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return false; 59cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 60cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 61cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Add to the count for each stream used. 62cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen for (const auto stream : RequestStreams(*request)) { 63cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen ++buffers_in_flight_[stream]; 64cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 65cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 66cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Store the request. 670b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen frames_in_flight_[request->frame_number] = request; 68cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 69cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return true; 70cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 71cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 720b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohenbool RequestTracker::Remove(std::shared_ptr<CaptureRequest> request) { 73c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen if (!request) { 74c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen return false; 75c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen } 76c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen 77cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Get the request. 78c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen const auto frame_number_request = 79c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen frames_in_flight_.find(request->frame_number); 800b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen if (frame_number_request == frames_in_flight_.end()) { 810b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen ALOGE("%s: Frame %u is not in flight.", __func__, request->frame_number); 820b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen return false; 830b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen } else if (request != frame_number_request->second) { 840b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen ALOGE( 850b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen "%s: Request for frame %u cannot be removed: " 860b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen "does not matched the stored request.", 870b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen __func__, 880b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen request->frame_number); 89cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return false; 90cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 910b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen 920b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen frames_in_flight_.erase(frame_number_request); 93cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 94cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Decrement the counts of used streams. 950b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen for (const auto stream : RequestStreams(*request)) { 96cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen --buffers_in_flight_[stream]; 97cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 98cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 99cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return true; 100cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 101cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 102cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenvoid RequestTracker::Clear( 1030b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen std::set<std::shared_ptr<CaptureRequest>>* requests) { 104cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // If desired, extract all the currently in-flight requests. 105cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (requests) { 106cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen for (auto& frame_number_request : frames_in_flight_) { 1070b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen requests->insert(frame_number_request.second); 108cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 109cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 110cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 111cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Clear out all tracking. 112cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen frames_in_flight_.clear(); 113c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // Maintain the configuration, but reset counts. 114c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen for (auto& stream_count : buffers_in_flight_) { 115c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen stream_count.second = 0; 116c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen } 117cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 118cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 119cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenbool RequestTracker::CanAddRequest(const CaptureRequest& request) const { 120cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Check that it's not a duplicate. 121cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (frames_in_flight_.count(request.frame_number) > 0) { 122cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen ALOGE("%s: Already tracking a request with frame number %d.", 123cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen __func__, 124cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen request.frame_number); 125cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return false; 126cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 127cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 128cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Check that each stream has space 129cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // (which implicitly checks if it is configured). 130cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen bool result = true; 131cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen for (const auto stream : RequestStreams(request)) { 132cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (StreamFull(stream)) { 133cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen ALOGE("%s: Stream %p is full.", __func__, stream); 134cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return false; 135cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 136cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 137cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return true; 138cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 139cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 140cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenbool RequestTracker::StreamFull(const camera3_stream_t* handle) const { 141cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen const auto it = buffers_in_flight_.find(handle); 142cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen if (it == buffers_in_flight_.end()) { 143cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen // Unconfigured streams are implicitly full. 144cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen ALOGV("%s: Stream %p is not a configured stream.", __func__, handle); 145cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return true; 146cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } else { 147cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return it->second >= it->first->max_buffers; 148cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen } 149cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 150cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 151cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenbool RequestTracker::InFlight(uint32_t frame_number) const { 152cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return frames_in_flight_.count(frame_number) > 0; 153cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 154cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 155cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohenbool RequestTracker::Empty() const { 156cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen return frames_in_flight_.empty(); 157cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} 158cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen 159cb11a4df53c3d70c6603ba1416d5c23df7765835Ari Hausman-Cohen} // namespace default_camera_hal 160