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