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