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