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 
37   // Wait until the requested streams have enough buffers and track
38   // the requested buffers.
39   // first_requested_stream_ids will be filled with the stream IDs that
40   // have not been requested previously.
41   status_t WaitAndTrackRequestBuffers(
42       const CaptureRequest& request,
43       std::vector<int32_t>* first_requested_stream_ids);
44 
45   // Track buffers returned, which was counted at request arrival time
46   status_t TrackReturnedResultBuffers(
47       const std::vector<StreamBuffer>& returned_buffers);
48 
49   // Wait until the actually acquired buffers have drop below the max buffer
50   // count and then release the lock to continue the work.
51   status_t WaitAndTrackAcquiredBuffers(int32_t stream_id, uint32_t num_buffers);
52 
53   // Decrease from the tracker the amount of buffer added previously in
54   // WaitAndTrackAcquiredBuffers but was not actually acquired due to buffer
55   // acquisition failure.
56   void TrackBufferAcquisitionFailure(int32_t stream_id, uint32_t num_buffers);
57 
58   // Track buffers returned, which was counted at buffer acquisition time
59   status_t TrackReturnedAcquiredBuffers(
60       const std::vector<StreamBuffer>& returned_buffers);
61 
62   virtual ~PendingRequestsTracker() = default;
63 
64  protected:
65   PendingRequestsTracker() = default;
66 
67  private:
68   // Duration to wait for stream buffers to be available.
69   static constexpr uint32_t kTrackerTimeoutMs = 3000;
70 
71   // Duration to wait for when requesting buffer
72   static constexpr uint32_t kAcquireBufferTimeoutMs = 50;
73 
74   // Initialize the tracker.
75   status_t Initialize(const std::vector<HalStream>& hal_configured_streams);
76 
77   // Return if all the buffers' streams have enough buffers to be requested.
78   // Must be protected with pending_requests_mutex_.
79   bool DoStreamsHaveEnoughBuffersLocked(
80       const std::vector<StreamBuffer>& buffers) const;
81 
82   // Return if the stream with stream_id have enough buffers to be requested.
83   // Must be protected with pending_acquisition_mutex_.
84   bool DoesStreamHaveEnoughBuffersToAcquireLocked(int32_t stream_id,
85                                                   uint32_t num_buffers) const;
86 
87   // Update requested stream ID and return the stream IDs that have not been
88   // requested previously in first_requested_stream_ids.
89   // Must be protected with pending_requests_mutex_.
90   status_t UpdateRequestedStreamIdsLocked(
91       const std::vector<StreamBuffer>& requested_buffers,
92       std::vector<int32_t>* first_requested_stream_ids);
93 
94   // Track buffers in capture requests.
95   // Must be protected with pending_requests_mutex_.
96   void TrackRequestBuffersLocked(
97       const std::vector<StreamBuffer>& requested_buffers);
98 
99   // Return if a stream ID is configured when Create() was called.
100   bool IsStreamConfigured(int32_t stream_id) const;
101 
102   // Map from stream ID to the stream's max number of buffers.
103   std::unordered_map<int32_t, uint32_t> stream_max_buffers_;
104 
105   // Condition to signal when a buffer is returned to the client.
106   std::condition_variable tracker_request_condition_;
107 
108   std::mutex pending_requests_mutex_;
109 
110   // Map from stream ID to the stream's number of pending buffers.
111   // It must have an entry for keys present in stream_max_buffers_.
112   // Must be protected with pending_requests_mutex_.
113   std::unordered_map<int32_t, uint32_t> stream_pending_buffers_;
114 
115   // Condition to signal when a buffer is returned to the client through process
116   // capture result or return stream buffer api.
117   std::condition_variable tracker_acquisition_condition_;
118 
119   std::mutex pending_acquisition_mutex_;
120 
121   // Map from stream ID to the stream's number of actually acquired buffers.
122   // It must have an entry for keys present in stream_max_buffers_.
123   // Must be protected with pending_acquisition_mutex_.
124   std::unordered_map<int32_t, uint32_t> stream_acquired_buffers_;
125 
126   // Contains the stream IDs that have been requested previously.
127   // Must be protected with pending_requests_mutex_.
128   std::unordered_set<int32_t> requested_stream_ids_;
129 };
130 
131 }  // namespace google_camera_hal
132 }  // namespace android
133 
134 #endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_PENDING_REQUESTS_TRACKER_H_
135