1 /*
2  * Copyright (C) 2019 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 #ifndef HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_PENDING_REQUESTS_TRACKER_H_
18 #define HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_PENDING_REQUESTS_TRACKER_H_
19 
20 #include <memory>
21 #include <unordered_map>
22 #include <unordered_set>
23 
24 #include "hal_types.h"
25 
26 namespace android {
27 namespace google_camera_hal {
28 
29 // PendingRequestsTracker tracks pending requests and can be used to throttle
30 // capture requests so the number of stream buffers won't exceed its stream's
31 // max number of buffers.
32 class PendingRequestsTracker {
33  public:
34   static std::unique_ptr<PendingRequestsTracker> Create(
35       const std::vector<HalStream>& hal_configured_streams,
36       const std::unordered_map<int32_t, int32_t>& grouped_stream_id_map);
37 
38   // Wait until the requested streams have enough buffers and track
39   // the requested buffers.
40   // first_requested_stream_ids will be filled with the stream IDs that
41   // have not been requested previously.
42   status_t WaitAndTrackRequestBuffers(
43       const CaptureRequest& request,
44       std::vector<int32_t>* first_requested_stream_ids);
45 
46   // Track buffers returned, which was counted at request arrival time
47   status_t TrackReturnedResultBuffers(
48       const std::vector<StreamBuffer>& returned_buffers);
49 
50   // Wait until the actually acquired buffers have drop below the max buffer
51   // count and then release the lock to continue the work.
52   status_t WaitAndTrackAcquiredBuffers(int32_t stream_id, uint32_t num_buffers);
53 
54   // Decrease from the tracker the amount of buffer added previously in
55   // WaitAndTrackAcquiredBuffers but was not actually acquired due to buffer
56   // acquisition failure.
57   void TrackBufferAcquisitionFailure(int32_t stream_id, uint32_t num_buffers);
58 
59   // Track buffers returned, which was counted at buffer acquisition time
60   status_t TrackReturnedAcquiredBuffers(
61       const std::vector<StreamBuffer>& returned_buffers);
62 
63   // Notify the request tracker that the buffer cache manager has been flushed.
64   void OnBufferCacheFlushed();
65 
66   virtual ~PendingRequestsTracker() = default;
67 
68  protected:
69   PendingRequestsTracker() = default;
70 
71  private:
72   // Duration to wait for stream buffers to be available.
73   static constexpr uint32_t kTrackerTimeoutMs = 3000;
74 
75   // Duration to wait for when requesting buffer
76   static constexpr uint32_t kAcquireBufferTimeoutMs = 50;
77 
78   // Initialize the tracker.
79   status_t Initialize(
80       const std::vector<HalStream>& hal_configured_streams,
81       const std::unordered_map<int32_t, int32_t>& grouped_stream_id_map);
82 
83   // Return if all the buffers' streams have enough buffers to be requested.
84   // Must be protected with pending_requests_mutex_.
85   bool DoStreamsHaveEnoughBuffersLocked(
86       const std::vector<StreamBuffer>& buffers) const;
87 
88   // Return if the stream with stream_id have enough buffers to be requested.
89   // Must be protected with pending_acquisition_mutex_.
90   bool DoesStreamHaveEnoughBuffersToAcquireLocked(int32_t stream_id,
91                                                   uint32_t num_buffers) const;
92 
93   // Update requested stream ID and return the stream IDs that have not been
94   // requested previously in first_requested_stream_ids.
95   // Must be protected with pending_requests_mutex_.
96   status_t UpdateRequestedStreamIdsLocked(
97       const std::vector<StreamBuffer>& requested_buffers,
98       std::vector<int32_t>* first_requested_stream_ids);
99 
100   // Track buffers in capture requests.
101   // Must be protected with pending_requests_mutex_.
102   void TrackRequestBuffersLocked(
103       const std::vector<StreamBuffer>& requested_buffers);
104 
105   // Return if a stream ID is configured when Create() was called.
106   bool IsStreamConfigured(int32_t stream_id) const;
107 
108   // If the stream is part of a stream group, return the single stream id
109   // representing the group. Otherwise, return the id that's passed in.
110   int32_t OverrideStreamIdForGroup(int32_t stream_id) const;
111 
112   // Map from stream ID to the stream's max number of buffers.
113   std::unordered_map<int32_t, uint32_t> stream_max_buffers_;
114 
115   // Condition to signal when a buffer is returned to the client.
116   std::condition_variable tracker_request_condition_;
117 
118   std::mutex pending_requests_mutex_;
119 
120   // Map from stream ID to the stream's number of pending buffers.
121   // It must have an entry for keys present in stream_max_buffers_.
122   // Must be protected with pending_requests_mutex_.
123   std::unordered_map<int32_t, uint32_t> stream_pending_buffers_;
124 
125   // Condition to signal when a buffer is returned to the client through process
126   // capture result or return stream buffer api.
127   std::condition_variable tracker_acquisition_condition_;
128 
129   std::mutex pending_acquisition_mutex_;
130 
131   // Map from stream ID to the stream's number of actually acquired buffers.
132   // It must have an entry for keys present in stream_max_buffers_.
133   // Must be protected with pending_acquisition_mutex_.
134   std::unordered_map<int32_t, uint32_t> stream_acquired_buffers_;
135 
136   // Contains the stream IDs that have been requested previously.
137   // Must be protected with pending_requests_mutex_.
138   std::unordered_set<int32_t> requested_stream_ids_;
139 
140   // Map from stream IDs within a stream group to one stream ID for tracking
141   // purposes. For multi-resolution output, the HWL gets to decide which stream
142   // within a stream group outputs images.
143   std::unordered_map<int32_t, int32_t> grouped_stream_id_map_;
144 };
145 
146 }  // namespace google_camera_hal
147 }  // namespace android
148 
149 #endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_PENDING_REQUESTS_TRACKER_H_
150