• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 stream buffers to be available.
78   static constexpr uint32_t kTrackerTimeoutMs = 3000;
79 
80   // Duration to wait for when requesting buffer
81   static constexpr uint32_t kAcquireBufferTimeoutMs = 50;
82 
83   // Initialize the tracker.
84   status_t Initialize(
85       const std::vector<HalStream>& hal_configured_streams,
86       const std::unordered_map<int32_t, int32_t>& grouped_stream_id_map,
87       const std::set<int32_t>& hal_buffer_managed_stream_ids);
88 
89   // Return if all the buffers' streams have enough buffers to be requested.
90   // Must be protected with pending_requests_mutex_.
91   bool DoStreamsHaveEnoughBuffersLocked(
92       const std::vector<StreamBuffer>& buffers) const;
93 
94   // Return if the stream with stream_id have enough buffers to be requested.
95   // Must be protected with pending_acquisition_mutex_.
96   bool DoesStreamHaveEnoughBuffersToAcquireLocked(int32_t stream_id,
97                                                   uint32_t num_buffers) const;
98 
99   // Update requested stream ID and return the stream IDs that have not been
100   // requested previously in first_requested_stream_ids.
101   // Must be protected with pending_requests_mutex_.
102   status_t UpdateRequestedStreamIdsLocked(
103       const std::vector<StreamBuffer>& requested_buffers,
104       std::vector<int32_t>* first_requested_stream_ids);
105 
106   // Track buffers in capture requests.
107   // Must be protected with pending_requests_mutex_.
108   void TrackRequestBuffersLocked(
109       const std::vector<StreamBuffer>& requested_buffers);
110 
111   // Return if a stream ID is configured when Create() was called.
112   bool IsStreamConfigured(int32_t stream_id) const;
113 
114   // If the stream is part of a stream group, return the single stream id
115   // representing the group. Otherwise, return the id that's passed in.
116   int32_t OverrideStreamIdForGroup(int32_t stream_id) const;
117 
118   // Map from stream ID to the stream's max number of buffers.
119   std::unordered_map<int32_t, uint32_t> stream_max_buffers_;
120 
121   // Condition to signal when a buffer is returned to the client.
122   std::condition_variable tracker_request_condition_;
123 
124   std::mutex pending_requests_mutex_;
125 
126   // Map from stream ID to the stream's number of pending buffers.
127   // It must have an entry for keys present in stream_max_buffers_.
128   // Must be protected with pending_requests_mutex_.
129   std::unordered_map<int32_t, uint32_t> stream_pending_buffers_;
130 
131   // Condition to signal when a buffer is returned to the client through process
132   // capture result or return stream buffer api.
133   std::condition_variable tracker_acquisition_condition_;
134 
135   std::mutex pending_acquisition_mutex_;
136 
137   // Map from stream ID to the stream's number of actually acquired buffers.
138   // It must have an entry for keys present in stream_max_buffers_.
139   // Must be protected with pending_acquisition_mutex_.
140   std::unordered_map<int32_t, uint32_t> stream_acquired_buffers_;
141 
142   // Contains the stream IDs that have been requested previously.
143   // Must be protected with pending_requests_mutex_.
144   std::unordered_set<int32_t> requested_stream_ids_;
145 
146   // Map from stream IDs within a stream group to one stream ID for tracking
147   // purposes. For multi-resolution output, the HWL gets to decide which stream
148   // within a stream group outputs images.
149   std::unordered_map<int32_t, int32_t> grouped_stream_id_map_;
150 
151   std::set<int32_t> hal_buffer_managed_stream_ids_;
152 };
153 
154 }  // namespace google_camera_hal
155 }  // namespace android
156 
157 #endif  // HARDWARE_GOOGLE_CAMERA_HAL_GOOGLE_CAMERA_HAL_PENDING_REQUESTS_TRACKER_H_
158