Loading libs/gui/BufferQueueConsumer.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -166,7 +166,9 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, mCore->mFreeBuffers.push_back(front->mSlot); } if (mCore->mBufferReleasedCbEnabled) { listener = mCore->mConnectedProducerListener; } ++numDroppedBuffers; } Loading Loading @@ -457,7 +459,9 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, mCore->mFreeBuffers.push_back(slot); } if (mCore->mBufferReleasedCbEnabled) { listener = mCore->mConnectedProducerListener; } BQ_LOGV("releaseBuffer: releasing slot %d", slot); mCore->mDequeueCondition.notify_all(); Loading Loading @@ -668,7 +672,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { if (delta < 0 && mCore->mBufferReleasedCbEnabled) { listener = mCore->mConsumerListener; } } Loading libs/gui/BufferQueueCore.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ BufferQueueCore::BufferQueueCore() : mConnectedApi(NO_CONNECTED_API), mLinkedToDeath(), mConnectedProducerListener(), mBufferReleasedCbEnabled(false), mSlots(), mQueue(), mFreeSlots(), Loading Loading @@ -260,6 +261,12 @@ void BufferQueueCore::freeAllBuffersLocked() { } void BufferQueueCore::discardFreeBuffersLocked() { // Notify producer about the discarded buffers. if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) { std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end()); mConnectedProducerListener->onBuffersDiscarded(freeBuffers); } for (int s : mFreeBuffers) { mFreeSlots.insert(s); clearBufferSlotLocked(s); Loading libs/gui/BufferQueueProducer.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -1221,9 +1221,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, } mCore->mLinkedToDeath = listener; } if (listener->needsReleaseNotify()) { mCore->mConnectedProducerListener = listener; } mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify(); } break; default: Loading libs/gui/IProducerListener.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ namespace android { enum { ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION, NEEDS_RELEASE_NOTIFY, ON_BUFFERS_DISCARDED, }; class BpProducerListener : public BpInterface<IProducerListener> Loading Loading @@ -56,6 +57,13 @@ public: } return result; } virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) { Parcel data, reply; data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); data.writeInt32Vector(discardedSlots); remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY); } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading @@ -76,6 +84,10 @@ public: virtual bool needsReleaseNotify() override { return mBase->needsReleaseNotify(); } virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override { return mBase->onBuffersDiscarded(discardedSlots); } }; IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener, Loading @@ -92,6 +104,17 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, CHECK_INTERFACE(IProducerListener, data, reply); reply->writeBool(needsReleaseNotify()); return NO_ERROR; case ON_BUFFERS_DISCARDED: { CHECK_INTERFACE(IProducerListener, data, reply); std::vector<int32_t> discardedSlots; status_t result = data.readInt32Vector(&discardedSlots); if (result != NO_ERROR) { ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result); return result; } onBuffersDiscarded(discardedSlots); return NO_ERROR; } } return BBinder::onTransact(code, data, reply, flags); } Loading @@ -104,4 +127,7 @@ bool BnProducerListener::needsReleaseNotify() { return true; } void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) { } } // namespace android libs/gui/Surface.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <ui/DisplayStatInfo.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> #include <ui/HdrCapabilities.h> #include <ui/Region.h> Loading Loading @@ -1286,6 +1287,14 @@ int Surface::connect(int api, const sp<IProducerListener>& listener) { return connect(api, listener, false); } int Surface::connect( int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) { if (sListener != nullptr) { mListenerProxy = new ProducerListenerProxy(this, sListener); } return connect(api, mListenerProxy, reportBufferRemoval); } int Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { ATRACE_CALL(); Loading Loading @@ -1684,6 +1693,28 @@ void Surface::freeAllBuffers() { } } status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots, std::vector<sp<GraphicBuffer>>* outBuffers) { ALOGV("Surface::getAndFlushBuffersFromSlots"); for (int32_t i : slots) { if (i < 0 || i >= NUM_BUFFER_SLOTS) { ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i); return BAD_VALUE; } } Mutex::Autolock lock(mMutex); for (int32_t i : slots) { if (mSlots[i].buffer == nullptr) { ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i); continue; } outBuffers->push_back(mSlots[i].buffer); mSlots[i].buffer = nullptr; } return OK; } void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { ATRACE_CALL(); ALOGV("Surface::setSurfaceDamage"); Loading Loading @@ -1951,4 +1982,22 @@ status_t Surface::attachAndQueueBufferWithDataspace(Surface* surface, sp<Graphic return err; } void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) { ATRACE_CALL(); sp<Surface> parent = mParent.promote(); if (parent == nullptr) { return; } std::vector<sp<GraphicBuffer>> discardedBufs; status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs); if (res != OK) { ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__, strerror(-res), res); return; } mSurfaceListener->onBuffersDiscarded(discardedBufs); } }; // namespace android Loading
libs/gui/BufferQueueConsumer.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -166,7 +166,9 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, mCore->mFreeBuffers.push_back(front->mSlot); } if (mCore->mBufferReleasedCbEnabled) { listener = mCore->mConnectedProducerListener; } ++numDroppedBuffers; } Loading Loading @@ -457,7 +459,9 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, mCore->mFreeBuffers.push_back(slot); } if (mCore->mBufferReleasedCbEnabled) { listener = mCore->mConnectedProducerListener; } BQ_LOGV("releaseBuffer: releasing slot %d", slot); mCore->mDequeueCondition.notify_all(); Loading Loading @@ -668,7 +672,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { if (delta < 0 && mCore->mBufferReleasedCbEnabled) { listener = mCore->mConsumerListener; } } Loading
libs/gui/BufferQueueCore.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ BufferQueueCore::BufferQueueCore() : mConnectedApi(NO_CONNECTED_API), mLinkedToDeath(), mConnectedProducerListener(), mBufferReleasedCbEnabled(false), mSlots(), mQueue(), mFreeSlots(), Loading Loading @@ -260,6 +261,12 @@ void BufferQueueCore::freeAllBuffersLocked() { } void BufferQueueCore::discardFreeBuffersLocked() { // Notify producer about the discarded buffers. if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) { std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end()); mConnectedProducerListener->onBuffersDiscarded(freeBuffers); } for (int s : mFreeBuffers) { mFreeSlots.insert(s); clearBufferSlotLocked(s); Loading
libs/gui/BufferQueueProducer.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -1221,9 +1221,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, } mCore->mLinkedToDeath = listener; } if (listener->needsReleaseNotify()) { mCore->mConnectedProducerListener = listener; } mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify(); } break; default: Loading
libs/gui/IProducerListener.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ namespace android { enum { ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION, NEEDS_RELEASE_NOTIFY, ON_BUFFERS_DISCARDED, }; class BpProducerListener : public BpInterface<IProducerListener> Loading Loading @@ -56,6 +57,13 @@ public: } return result; } virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) { Parcel data, reply; data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); data.writeInt32Vector(discardedSlots); remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY); } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading @@ -76,6 +84,10 @@ public: virtual bool needsReleaseNotify() override { return mBase->needsReleaseNotify(); } virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override { return mBase->onBuffersDiscarded(discardedSlots); } }; IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener, Loading @@ -92,6 +104,17 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, CHECK_INTERFACE(IProducerListener, data, reply); reply->writeBool(needsReleaseNotify()); return NO_ERROR; case ON_BUFFERS_DISCARDED: { CHECK_INTERFACE(IProducerListener, data, reply); std::vector<int32_t> discardedSlots; status_t result = data.readInt32Vector(&discardedSlots); if (result != NO_ERROR) { ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result); return result; } onBuffersDiscarded(discardedSlots); return NO_ERROR; } } return BBinder::onTransact(code, data, reply, flags); } Loading @@ -104,4 +127,7 @@ bool BnProducerListener::needsReleaseNotify() { return true; } void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) { } } // namespace android
libs/gui/Surface.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <ui/DisplayStatInfo.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> #include <ui/HdrCapabilities.h> #include <ui/Region.h> Loading Loading @@ -1286,6 +1287,14 @@ int Surface::connect(int api, const sp<IProducerListener>& listener) { return connect(api, listener, false); } int Surface::connect( int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) { if (sListener != nullptr) { mListenerProxy = new ProducerListenerProxy(this, sListener); } return connect(api, mListenerProxy, reportBufferRemoval); } int Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { ATRACE_CALL(); Loading Loading @@ -1684,6 +1693,28 @@ void Surface::freeAllBuffers() { } } status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots, std::vector<sp<GraphicBuffer>>* outBuffers) { ALOGV("Surface::getAndFlushBuffersFromSlots"); for (int32_t i : slots) { if (i < 0 || i >= NUM_BUFFER_SLOTS) { ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i); return BAD_VALUE; } } Mutex::Autolock lock(mMutex); for (int32_t i : slots) { if (mSlots[i].buffer == nullptr) { ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i); continue; } outBuffers->push_back(mSlots[i].buffer); mSlots[i].buffer = nullptr; } return OK; } void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { ATRACE_CALL(); ALOGV("Surface::setSurfaceDamage"); Loading Loading @@ -1951,4 +1982,22 @@ status_t Surface::attachAndQueueBufferWithDataspace(Surface* surface, sp<Graphic return err; } void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) { ATRACE_CALL(); sp<Surface> parent = mParent.promote(); if (parent == nullptr) { return; } std::vector<sp<GraphicBuffer>> discardedBufs; status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs); if (res != OK) { ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__, strerror(-res), res); return; } mSurfaceListener->onBuffersDiscarded(discardedBufs); } }; // namespace android