Add batching to IGBP functions

The batching functions has a default implementation that calls
into the implementation of corresponding non-batched version.

Bug: 113788435
Bug: 137244088

Test: atest libgui_test

Change-Id: I068a05b8bfc7c64f893649dec2ef2233f16a22f6
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index ad00939..c1f9b85 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -74,6 +74,13 @@
     GET_CONSUMER_USAGE,
     SET_LEGACY_BUFFER_DROP,
     SET_AUTO_PREROTATION,
+    REQUEST_BUFFERS,
+    DEQUEUE_BUFFERS,
+    DETACH_BUFFERS,
+    ATTACH_BUFFERS,
+    QUEUE_BUFFERS,
+    CANCEL_BUFFERS,
+    QUERY_MULTIPLE,
 };
 
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -90,7 +97,7 @@
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
         data.writeInt32(bufferIdx);
-        status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
+        status_t result = remote()->transact(REQUEST_BUFFER, data, &reply);
         if (result != NO_ERROR) {
             return result;
         }
@@ -107,6 +114,27 @@
         return result;
     }
 
+    virtual status_t requestBuffers(
+            const std::vector<int32_t>& slots,
+            std::vector<RequestBufferOutput>* outputs) override {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32Vector(slots);
+        status_t result = remote()->transact(REQUEST_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.resizeOutVector(outputs);
+        for (RequestBufferOutput& output : *outputs) {
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply.read(output);
+        }
+
+        return result;
+    }
+
     virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
         Parcel data, reply;
         data.writeInterfaceToken(
@@ -183,6 +211,29 @@
         return result;
     }
 
+    virtual status_t dequeueBuffers(
+            const std::vector<DequeueBufferInput>& inputs,
+            std::vector<DequeueBufferOutput>* outputs) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeVectorSize(inputs);
+        for (const auto& input : inputs) {
+            data.write(input);
+        }
+        status_t result = remote()->transact(DEQUEUE_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.resizeOutVector(outputs);
+        for (auto& output : *outputs) {
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply.read(output);
+        }
+        return result;
+    }
+
     virtual status_t detachBuffer(int slot) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
@@ -195,6 +246,19 @@
         return result;
     }
 
+    virtual status_t detachBuffers(const std::vector<int32_t>& slots,
+                                   std::vector<status_t>* results) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32Vector(slots);
+        status_t result = remote()->transact(DETACH_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.readInt32Vector(results);
+        return result;
+    }
+
     virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
             sp<Fence>* outFence) {
         if (outBuffer == nullptr) {
@@ -256,6 +320,39 @@
         return result;
     }
 
+    virtual status_t attachBuffers(
+            const std::vector<sp<GraphicBuffer>>& buffers,
+            std::vector<AttachBufferOutput>* outputs) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeVectorSize(buffers);
+        for (const sp<GraphicBuffer>& buffer : buffers) {
+            data.write(*buffer.get());
+        }
+        status_t result = remote()->transact(ATTACH_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.resizeOutVector(outputs);
+        for (AttachBufferOutput& output : *outputs) {
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply.read(output);
+        }
+        if (result == NO_ERROR) {
+            for (AttachBufferOutput& output : *outputs) {
+                if (output.result == NO_ERROR && output.slot < 0) {
+                    ALOGE("attachBuffers returned invalid slot %d",
+                          output.slot);
+                    android_errorWriteLog(0x534e4554, "37478824");
+                    output.result = UNKNOWN_ERROR;
+                }
+            }
+        }
+        return result;
+    }
+
     virtual status_t queueBuffer(int buf,
             const QueueBufferInput& input, QueueBufferOutput* output) {
         Parcel data, reply;
@@ -278,6 +375,28 @@
         return result;
     }
 
+    virtual status_t queueBuffers(const std::vector<QueueBufferInput>& inputs,
+                                  std::vector<QueueBufferOutput>* outputs) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeVectorSize(inputs);
+        for (const QueueBufferInput& input : inputs) {
+            data.write(input);
+        }
+        status_t result = remote()->transact(QUEUE_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.resizeOutVector(outputs);
+        for (QueueBufferOutput& output : *outputs) {
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply.read(output);
+        }
+        return result;
+    }
+
     virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
@@ -291,6 +410,23 @@
         return result;
     }
 
+    virtual status_t cancelBuffers(
+            const std::vector<CancelBufferInput>& inputs,
+            std::vector<status_t>* results) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeVectorSize(inputs);
+        for (const CancelBufferInput& input : inputs) {
+            data.write(input);
+        }
+        status_t result = remote()->transact(CANCEL_BUFFERS, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.readInt32Vector(results);
+        return result;
+    }
+
     virtual int query(int what, int* value) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
@@ -304,6 +440,25 @@
         return result;
     }
 
+    virtual status_t query(const std::vector<int32_t> inputs,
+                           std::vector<QueryOutput>* outputs) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        data.writeInt32Vector(inputs);
+        status_t result = remote()->transact(QUERY_MULTIPLE, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = reply.resizeOutVector(outputs);
+        for (QueryOutput& output : *outputs) {
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply.read(output);
+        }
+        return result;
+    }
+
     virtual status_t connect(const sp<IProducerListener>& listener,
             int api, bool producerControlledByApp, QueueBufferOutput* output) {
         Parcel data, reply;
@@ -576,6 +731,12 @@
         return mBase->requestBuffer(slot, buf);
     }
 
+    status_t requestBuffers(
+            const std::vector<int32_t>& slots,
+            std::vector<RequestBufferOutput>* outputs) override {
+        return mBase->requestBuffers(slots, outputs);
+    }
+
     status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override {
         return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers);
     }
@@ -590,10 +751,21 @@
         return mBase->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps);
     }
 
+    status_t dequeueBuffers(
+            const std::vector<DequeueBufferInput>& inputs,
+            std::vector<DequeueBufferOutput>* outputs) override {
+        return mBase->dequeueBuffers(inputs, outputs);
+    }
+
     status_t detachBuffer(int slot) override {
         return mBase->detachBuffer(slot);
     }
 
+    status_t detachBuffers(const std::vector<int32_t>& slots,
+                           std::vector<status_t>* results) override {
+        return mBase->detachBuffers(slots, results);
+    }
+
     status_t detachNextBuffer(
             sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override {
         return mBase->detachNextBuffer(outBuffer, outFence);
@@ -604,6 +776,12 @@
         return mBase->attachBuffer(outSlot, buffer);
     }
 
+    status_t attachBuffers(
+            const std::vector<sp<GraphicBuffer>>& buffers,
+            std::vector<AttachBufferOutput>* outputs) override {
+        return mBase->attachBuffers(buffers, outputs);
+    }
+
     status_t queueBuffer(
             int slot,
             const QueueBufferInput& input,
@@ -611,14 +789,30 @@
         return mBase->queueBuffer(slot, input, output);
     }
 
+    status_t queueBuffers(const std::vector<QueueBufferInput>& inputs,
+                          std::vector<QueueBufferOutput>* outputs) override {
+        return mBase->queueBuffers(inputs, outputs);
+    }
+
     status_t cancelBuffer(int slot, const sp<Fence>& fence) override {
         return mBase->cancelBuffer(slot, fence);
     }
 
+    status_t cancelBuffers(
+            const std::vector<CancelBufferInput>& inputs,
+            std::vector<status_t>* results) override {
+        return mBase->cancelBuffers(inputs, results);
+    }
+
     int query(int what, int* value) override {
         return mBase->query(what, value);
     }
 
+    status_t query(const std::vector<int32_t> inputs,
+                   std::vector<QueryOutput>* outputs) override {
+        return mBase->query(inputs, outputs);
+    }
+
     status_t connect(
             const sp<IProducerListener>& listener,
             int api, bool producerControlledByApp,
@@ -789,7 +983,7 @@
     switch(code) {
         case REQUEST_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
-            int bufferIdx   = data.readInt32();
+            int bufferIdx = data.readInt32();
             sp<GraphicBuffer> buffer;
             int result = requestBuffer(bufferIdx, &buffer);
             reply->writeInt32(buffer != nullptr);
@@ -799,6 +993,24 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case REQUEST_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<int32_t> slots;
+            std::vector<RequestBufferOutput> outputs;
+            status_t result = data.readInt32Vector(&slots);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            (void)requestBuffers(slots, &outputs);
+            result = reply->writeVectorSize(outputs);
+            for (const RequestBufferOutput& output : outputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = reply->write(output);
+            }
+            return result;
+        }
         case SET_MAX_DEQUEUED_BUFFER_COUNT: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             int maxDequeuedBuffers = data.readInt32();
@@ -841,6 +1053,30 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case DEQUEUE_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<DequeueBufferInput> inputs;
+            std::vector<DequeueBufferOutput> outputs;
+            status_t result = data.resizeOutVector(&inputs);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            for (DequeueBufferInput& input : inputs) {
+                result = data.read(input);
+                if (result != NO_ERROR) {
+                    return result;
+                }
+            }
+            (void)dequeueBuffers(inputs, &outputs);
+            result = reply->writeVectorSize(outputs);
+            for (const DequeueBufferOutput& output : outputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = reply->write(output);
+            }
+            return result;
+        }
         case DETACH_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             int slot = data.readInt32();
@@ -848,6 +1084,17 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case DETACH_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<int32_t> slots;
+            std::vector<status_t> results;
+            status_t result = data.readInt32Vector(&slots);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            (void)detachBuffers(slots, &results);
+            return reply->writeInt32Vector(results);
+        }
         case DETACH_NEXT_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             sp<GraphicBuffer> buffer;
@@ -878,6 +1125,31 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case ATTACH_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<sp<GraphicBuffer>> buffers;
+            status_t result = data.resizeOutVector(&buffers);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            for (sp<GraphicBuffer>& buffer : buffers) {
+                buffer = new GraphicBuffer();
+                result = data.read(*buffer.get());
+                if (result != NO_ERROR) {
+                    return result;
+                }
+            }
+            std::vector<AttachBufferOutput> outputs;
+            (void)attachBuffers(buffers, &outputs);
+            result = reply->writeVectorSize(outputs);
+            for (const AttachBufferOutput& output : outputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = reply->write(output);
+            }
+            return result;
+        }
         case QUEUE_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
 
@@ -890,6 +1162,30 @@
 
             return NO_ERROR;
         }
+        case QUEUE_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<QueueBufferInput> inputs;
+            status_t result = data.resizeOutVector(&inputs);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            for (QueueBufferInput& input : inputs) {
+                result = data.read(input);
+                if (result != NO_ERROR) {
+                    return result;
+                }
+            }
+            std::vector<QueueBufferOutput> outputs;
+            (void)queueBuffers(inputs, &outputs);
+            result = reply->writeVectorSize(outputs);
+            for (const QueueBufferOutput& output : outputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = reply->write(output);
+            }
+            return result;
+        }
         case CANCEL_BUFFER: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             int buf = data.readInt32();
@@ -901,6 +1197,26 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case CANCEL_BUFFERS: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<CancelBufferInput> inputs;
+            status_t result = data.resizeOutVector(&inputs);
+            for (CancelBufferInput& input : inputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = data.read(input);
+            }
+            if (result != NO_ERROR) {
+                return result;
+            }
+            std::vector<status_t> results;
+            result = cancelBuffers(inputs, &results);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            return reply->writeInt32Vector(results);
+        }
         case QUERY: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             int value = 0;
@@ -910,6 +1226,27 @@
             reply->writeInt32(res);
             return NO_ERROR;
         }
+        case QUERY_MULTIPLE: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            std::vector<int32_t> inputs;
+            status_t result = data.readInt32Vector(&inputs);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            std::vector<QueryOutput> outputs;
+            result = query(inputs, &outputs);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply->writeVectorSize(outputs);
+            for (const QueryOutput& output : outputs) {
+                if (result != NO_ERROR) {
+                    return result;
+                }
+                result = reply->write(output);
+            }
+            return result;
+        }
         case CONNECT: {
             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
             sp<IProducerListener> listener;
@@ -1083,11 +1420,4 @@
     return BBinder::onTransact(code, data, reply, flags);
 }
 
-// ----------------------------------------------------------------------------
-
-IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
-    parcel.read(*this);
-}
-
-
 }; // namespace android