Camera: batching dequeueBuffer call for batched requests

Add plumbing to call into batched version of getBuffer call.
Also add some logic so batched version can be used even
when camera HAL is request buffer one at a time.

Camera3OutputStream will batch dequeue buffers on a batch unit.
This way we can save extra IPCs even when the client (camera
framework or camera HAL) does not call into batch dequeue API
(dequeueBuffers) directly.

As a safety measure, right before client is about to return
all outstanding buffers, all prefetched buffers will also
be returned.

TODO:
  - Consider also batch queueBuffer path
  - switch to batch API in requestStreamBuffer API

Test: GCA high speed recording
Bug: 113788435
Change-Id: I3cc0b62e8a6891d6ff6cad0e3c78e1d7abff6317
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index f504171..366d22a 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA3_OUTPUT_STREAM_H
 #define ANDROID_SERVERS_CAMERA3_OUTPUT_STREAM_H
 
+#include <mutex>
 #include <utils/RefBase.h>
 #include <gui/IProducerListener.h>
 #include <gui/Surface.h>
@@ -206,6 +207,19 @@
             KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
 
     /**
+     * Set the batch size for buffer operations. The output stream will request
+     * buffers from buffer queue on a batch basis. Currently only video streams
+     * are allowed to set the batch size. Also if the stream is managed by
+     * buffer manager (Surface group in Java API) then batching is also not
+     * supported. Changing batch size on the fly while there is already batched
+     * buffers in the stream is also not supported.
+     * If the batch size is larger than the max dequeue count set
+     * by the camera HAL, the batch size will be set to the max dequeue count
+     * instead.
+     */
+    virtual status_t setBatchSize(size_t batchSize = 1) override;
+
+    /**
      * Apply ZSL related consumer usage quirk.
      */
     static void applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/);
@@ -292,12 +306,26 @@
     // Whether to drop valid buffers.
     bool mDropBuffers;
 
+
+    // Protecting batch states below, must be acquired after mLock
+    std::mutex mBatchLock;
+
+    // The batch size for buffer operation
+    size_t mBatchSize = 1;
+
+    // Prefetched buffers (ready to be handed to client)
+    std::vector<Surface::BatchBuffer> mBatchedBuffers;
+
+    // ---- End of mBatchLock protected scope ----
+
     /**
      * Internal Camera3Stream interface
      */
     virtual status_t getBufferLocked(camera_stream_buffer *buffer,
             const std::vector<size_t>& surface_ids);
 
+    virtual status_t getBuffersLocked(/*out*/std::vector<OutstandingBuffer>* buffers) override;
+
     virtual status_t returnBufferLocked(
             const camera_stream_buffer &buffer,
             nsecs_t timestamp, const std::vector<size_t>& surface_ids);
@@ -330,6 +358,8 @@
     // Dump images to disk before returning to consumer
     void dumpImageToDisk(nsecs_t timestamp, ANativeWindowBuffer* anwBuffer, int fence);
 
+    void returnPrefetchedBuffersLocked();
+
     static const int32_t kDequeueLatencyBinSize = 5; // in ms
     CameraLatencyHistogram mDequeueBufferLatency;