Loading libs/gui/Android.bp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -162,6 +162,7 @@ cc_library_static { filegroup { filegroup { name: "libgui_bufferqueue_sources", name: "libgui_bufferqueue_sources", srcs: [ srcs: [ "BatchBufferOps.cpp", "BufferItem.cpp", "BufferItem.cpp", "BufferQueue.cpp", "BufferQueue.cpp", "BufferQueueConsumer.cpp", "BufferQueueConsumer.cpp", Loading @@ -172,7 +173,7 @@ filegroup { "FrameTimestamps.cpp", "FrameTimestamps.cpp", "GLConsumerUtils.cpp", "GLConsumerUtils.cpp", "HdrMetadata.cpp", "HdrMetadata.cpp", "QueueBufferInputOutput.cpp", "IGraphicBufferProducerFlattenables.cpp", "bufferqueue/1.0/Conversion.cpp", "bufferqueue/1.0/Conversion.cpp", "bufferqueue/1.0/H2BProducerListener.cpp", "bufferqueue/1.0/H2BProducerListener.cpp", "bufferqueue/1.0/WProducerListener.cpp", "bufferqueue/1.0/WProducerListener.cpp", Loading libs/gui/BatchBufferOps.cpp 0 → 100644 +125 −0 Original line number Original line Diff line number Diff line /* * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <inttypes.h> #define LOG_TAG "IGBPBatchOps" #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 #include <gui/IGraphicBufferProducer.h> namespace android { /** * Default implementation of batched buffer operations. These default * implementations call into the non-batched version of the same operation. */ status_t IGraphicBufferProducer::requestBuffers( const std::vector<int32_t>& slots, std::vector<RequestBufferOutput>* outputs) { outputs->clear(); outputs->reserve(slots.size()); for (int32_t slot : slots) { RequestBufferOutput& output = outputs->emplace_back(); output.result = requestBuffer(static_cast<int>(slot), &output.buffer); } return NO_ERROR; } status_t IGraphicBufferProducer::dequeueBuffers( const std::vector<DequeueBufferInput>& inputs, std::vector<DequeueBufferOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (const DequeueBufferInput& input : inputs) { DequeueBufferOutput& output = outputs->emplace_back(); output.result = dequeueBuffer( &output.slot, &output.fence, input.width, input.height, input.format, input.usage, &output.bufferAge, input.getTimestamps ? &output.timestamps.emplace() : nullptr); } return NO_ERROR; } status_t IGraphicBufferProducer::detachBuffers( const std::vector<int32_t>& slots, std::vector<status_t>* results) { results->clear(); results->reserve(slots.size()); for (int32_t slot : slots) { results->emplace_back(detachBuffer(slot)); } return NO_ERROR; } status_t IGraphicBufferProducer::attachBuffers( const std::vector<sp<GraphicBuffer>>& buffers, std::vector<AttachBufferOutput>* outputs) { outputs->clear(); outputs->reserve(buffers.size()); for (const sp<GraphicBuffer>& buffer : buffers) { AttachBufferOutput& output = outputs->emplace_back(); output.result = attachBuffer(&output.slot, buffer); } return NO_ERROR; } status_t IGraphicBufferProducer::queueBuffers( const std::vector<QueueBufferInput>& inputs, std::vector<QueueBufferOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (const QueueBufferInput& input : inputs) { QueueBufferOutput& output = outputs->emplace_back(); output.result = queueBuffer(input.slot, input, &output); } return NO_ERROR; } status_t IGraphicBufferProducer::cancelBuffers( const std::vector<CancelBufferInput>& inputs, std::vector<status_t>* results) { results->clear(); results->reserve(inputs.size()); for (const CancelBufferInput& input : inputs) { results->emplace_back() = cancelBuffer(input.slot, input.fence); } return NO_ERROR; } status_t IGraphicBufferProducer::query(const std::vector<int32_t> inputs, std::vector<QueryOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (int32_t input : inputs) { QueryOutput& output = outputs->emplace_back(); int value{}; output.result = static_cast<status_t>( query(static_cast<int>(input), &value)); output.value = static_cast<int64_t>(value); } return NO_ERROR; } } // namespace android libs/gui/IGraphicBufferProducer.cpp +339 −9 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,13 @@ enum { GET_CONSUMER_USAGE, GET_CONSUMER_USAGE, SET_LEGACY_BUFFER_DROP, SET_LEGACY_BUFFER_DROP, SET_AUTO_PREROTATION, SET_AUTO_PREROTATION, REQUEST_BUFFERS, DEQUEUE_BUFFERS, DETACH_BUFFERS, ATTACH_BUFFERS, QUEUE_BUFFERS, CANCEL_BUFFERS, QUERY_MULTIPLE, }; }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> Loading Loading @@ -107,6 +114,27 @@ public: return result; 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) { virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken( data.writeInterfaceToken( Loading Loading @@ -183,6 +211,29 @@ public: return result; 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) { virtual status_t detachBuffer(int slot) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -195,6 +246,19 @@ public: return result; 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, virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) { sp<Fence>* outFence) { if (outBuffer == nullptr) { if (outBuffer == nullptr) { Loading Loading @@ -256,6 +320,39 @@ public: return result; 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, virtual status_t queueBuffer(int buf, const QueueBufferInput& input, QueueBufferOutput* output) { const QueueBufferInput& input, QueueBufferOutput* output) { Parcel data, reply; Parcel data, reply; Loading @@ -278,6 +375,28 @@ public: return result; 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) { virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -291,6 +410,23 @@ public: return result; 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) { virtual int query(int what, int* value) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -304,6 +440,25 @@ public: return result; 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, virtual status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) { int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; Parcel data, reply; Loading Loading @@ -576,6 +731,12 @@ public: return mBase->requestBuffer(slot, buf); 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 { status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override { return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers); return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers); } } Loading @@ -590,10 +751,21 @@ public: return mBase->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps); 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 { status_t detachBuffer(int slot) override { return mBase->detachBuffer(slot); 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( status_t detachNextBuffer( sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { return mBase->detachNextBuffer(outBuffer, outFence); return mBase->detachNextBuffer(outBuffer, outFence); Loading @@ -604,6 +776,12 @@ public: return mBase->attachBuffer(outSlot, buffer); 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( status_t queueBuffer( int slot, int slot, const QueueBufferInput& input, const QueueBufferInput& input, Loading @@ -611,14 +789,30 @@ public: return mBase->queueBuffer(slot, input, output); 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 { status_t cancelBuffer(int slot, const sp<Fence>& fence) override { return mBase->cancelBuffer(slot, fence); 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 { int query(int what, int* value) override { return mBase->query(what, value); 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( status_t connect( const sp<IProducerListener>& listener, const sp<IProducerListener>& listener, int api, bool producerControlledByApp, int api, bool producerControlledByApp, Loading Loading @@ -799,6 +993,24 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case SET_MAX_DEQUEUED_BUFFER_COUNT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int maxDequeuedBuffers = data.readInt32(); int maxDequeuedBuffers = data.readInt32(); Loading Loading @@ -841,6 +1053,30 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case DETACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int slot = data.readInt32(); int slot = data.readInt32(); Loading @@ -848,6 +1084,17 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case DETACH_NEXT_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer; sp<GraphicBuffer> buffer; Loading Loading @@ -878,6 +1125,31 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case QUEUE_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); Loading @@ -890,6 +1162,30 @@ status_t BnGraphicBufferProducer::onTransact( return NO_ERROR; 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: { case CANCEL_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); int buf = data.readInt32(); Loading @@ -901,6 +1197,26 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case QUERY: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int value = 0; int value = 0; Loading @@ -910,6 +1226,27 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(res); reply->writeInt32(res); return NO_ERROR; 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: { case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<IProducerListener> listener; sp<IProducerListener> listener; Loading Loading @@ -1083,11 +1420,4 @@ status_t BnGraphicBufferProducer::onTransact( return BBinder::onTransact(code, data, reply, flags); return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { parcel.read(*this); } }; // namespace android }; // namespace android Loading
libs/gui/Android.bp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -162,6 +162,7 @@ cc_library_static { filegroup { filegroup { name: "libgui_bufferqueue_sources", name: "libgui_bufferqueue_sources", srcs: [ srcs: [ "BatchBufferOps.cpp", "BufferItem.cpp", "BufferItem.cpp", "BufferQueue.cpp", "BufferQueue.cpp", "BufferQueueConsumer.cpp", "BufferQueueConsumer.cpp", Loading @@ -172,7 +173,7 @@ filegroup { "FrameTimestamps.cpp", "FrameTimestamps.cpp", "GLConsumerUtils.cpp", "GLConsumerUtils.cpp", "HdrMetadata.cpp", "HdrMetadata.cpp", "QueueBufferInputOutput.cpp", "IGraphicBufferProducerFlattenables.cpp", "bufferqueue/1.0/Conversion.cpp", "bufferqueue/1.0/Conversion.cpp", "bufferqueue/1.0/H2BProducerListener.cpp", "bufferqueue/1.0/H2BProducerListener.cpp", "bufferqueue/1.0/WProducerListener.cpp", "bufferqueue/1.0/WProducerListener.cpp", Loading
libs/gui/BatchBufferOps.cpp 0 → 100644 +125 −0 Original line number Original line Diff line number Diff line /* * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <inttypes.h> #define LOG_TAG "IGBPBatchOps" #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 #include <gui/IGraphicBufferProducer.h> namespace android { /** * Default implementation of batched buffer operations. These default * implementations call into the non-batched version of the same operation. */ status_t IGraphicBufferProducer::requestBuffers( const std::vector<int32_t>& slots, std::vector<RequestBufferOutput>* outputs) { outputs->clear(); outputs->reserve(slots.size()); for (int32_t slot : slots) { RequestBufferOutput& output = outputs->emplace_back(); output.result = requestBuffer(static_cast<int>(slot), &output.buffer); } return NO_ERROR; } status_t IGraphicBufferProducer::dequeueBuffers( const std::vector<DequeueBufferInput>& inputs, std::vector<DequeueBufferOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (const DequeueBufferInput& input : inputs) { DequeueBufferOutput& output = outputs->emplace_back(); output.result = dequeueBuffer( &output.slot, &output.fence, input.width, input.height, input.format, input.usage, &output.bufferAge, input.getTimestamps ? &output.timestamps.emplace() : nullptr); } return NO_ERROR; } status_t IGraphicBufferProducer::detachBuffers( const std::vector<int32_t>& slots, std::vector<status_t>* results) { results->clear(); results->reserve(slots.size()); for (int32_t slot : slots) { results->emplace_back(detachBuffer(slot)); } return NO_ERROR; } status_t IGraphicBufferProducer::attachBuffers( const std::vector<sp<GraphicBuffer>>& buffers, std::vector<AttachBufferOutput>* outputs) { outputs->clear(); outputs->reserve(buffers.size()); for (const sp<GraphicBuffer>& buffer : buffers) { AttachBufferOutput& output = outputs->emplace_back(); output.result = attachBuffer(&output.slot, buffer); } return NO_ERROR; } status_t IGraphicBufferProducer::queueBuffers( const std::vector<QueueBufferInput>& inputs, std::vector<QueueBufferOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (const QueueBufferInput& input : inputs) { QueueBufferOutput& output = outputs->emplace_back(); output.result = queueBuffer(input.slot, input, &output); } return NO_ERROR; } status_t IGraphicBufferProducer::cancelBuffers( const std::vector<CancelBufferInput>& inputs, std::vector<status_t>* results) { results->clear(); results->reserve(inputs.size()); for (const CancelBufferInput& input : inputs) { results->emplace_back() = cancelBuffer(input.slot, input.fence); } return NO_ERROR; } status_t IGraphicBufferProducer::query(const std::vector<int32_t> inputs, std::vector<QueryOutput>* outputs) { outputs->clear(); outputs->reserve(inputs.size()); for (int32_t input : inputs) { QueryOutput& output = outputs->emplace_back(); int value{}; output.result = static_cast<status_t>( query(static_cast<int>(input), &value)); output.value = static_cast<int64_t>(value); } return NO_ERROR; } } // namespace android
libs/gui/IGraphicBufferProducer.cpp +339 −9 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,13 @@ enum { GET_CONSUMER_USAGE, GET_CONSUMER_USAGE, SET_LEGACY_BUFFER_DROP, SET_LEGACY_BUFFER_DROP, SET_AUTO_PREROTATION, SET_AUTO_PREROTATION, REQUEST_BUFFERS, DEQUEUE_BUFFERS, DETACH_BUFFERS, ATTACH_BUFFERS, QUEUE_BUFFERS, CANCEL_BUFFERS, QUERY_MULTIPLE, }; }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> Loading Loading @@ -107,6 +114,27 @@ public: return result; 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) { virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken( data.writeInterfaceToken( Loading Loading @@ -183,6 +211,29 @@ public: return result; 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) { virtual status_t detachBuffer(int slot) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -195,6 +246,19 @@ public: return result; 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, virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) { sp<Fence>* outFence) { if (outBuffer == nullptr) { if (outBuffer == nullptr) { Loading Loading @@ -256,6 +320,39 @@ public: return result; 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, virtual status_t queueBuffer(int buf, const QueueBufferInput& input, QueueBufferOutput* output) { const QueueBufferInput& input, QueueBufferOutput* output) { Parcel data, reply; Parcel data, reply; Loading @@ -278,6 +375,28 @@ public: return result; 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) { virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -291,6 +410,23 @@ public: return result; 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) { virtual int query(int what, int* value) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); Loading @@ -304,6 +440,25 @@ public: return result; 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, virtual status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) { int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; Parcel data, reply; Loading Loading @@ -576,6 +731,12 @@ public: return mBase->requestBuffer(slot, buf); 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 { status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override { return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers); return mBase->setMaxDequeuedBufferCount(maxDequeuedBuffers); } } Loading @@ -590,10 +751,21 @@ public: return mBase->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps); 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 { status_t detachBuffer(int slot) override { return mBase->detachBuffer(slot); 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( status_t detachNextBuffer( sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { return mBase->detachNextBuffer(outBuffer, outFence); return mBase->detachNextBuffer(outBuffer, outFence); Loading @@ -604,6 +776,12 @@ public: return mBase->attachBuffer(outSlot, buffer); 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( status_t queueBuffer( int slot, int slot, const QueueBufferInput& input, const QueueBufferInput& input, Loading @@ -611,14 +789,30 @@ public: return mBase->queueBuffer(slot, input, output); 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 { status_t cancelBuffer(int slot, const sp<Fence>& fence) override { return mBase->cancelBuffer(slot, fence); 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 { int query(int what, int* value) override { return mBase->query(what, value); 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( status_t connect( const sp<IProducerListener>& listener, const sp<IProducerListener>& listener, int api, bool producerControlledByApp, int api, bool producerControlledByApp, Loading Loading @@ -799,6 +993,24 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case SET_MAX_DEQUEUED_BUFFER_COUNT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int maxDequeuedBuffers = data.readInt32(); int maxDequeuedBuffers = data.readInt32(); Loading Loading @@ -841,6 +1053,30 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case DETACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int slot = data.readInt32(); int slot = data.readInt32(); Loading @@ -848,6 +1084,17 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case DETACH_NEXT_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer; sp<GraphicBuffer> buffer; Loading Loading @@ -878,6 +1125,31 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case QUEUE_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); Loading @@ -890,6 +1162,30 @@ status_t BnGraphicBufferProducer::onTransact( return NO_ERROR; 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: { case CANCEL_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); int buf = data.readInt32(); Loading @@ -901,6 +1197,26 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); reply->writeInt32(result); return NO_ERROR; 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: { case QUERY: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int value = 0; int value = 0; Loading @@ -910,6 +1226,27 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(res); reply->writeInt32(res); return NO_ERROR; 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: { case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<IProducerListener> listener; sp<IProducerListener> listener; Loading Loading @@ -1083,11 +1420,4 @@ status_t BnGraphicBufferProducer::onTransact( return BBinder::onTransact(code, data, reply, flags); return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { parcel.read(*this); } }; // namespace android }; // namespace android