diff options
| -rw-r--r-- | libs/gui/BufferQueue.cpp | 21 | ||||
| -rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 13 | ||||
| -rw-r--r-- | libs/gui/ConsumerBase.cpp | 42 | ||||
| -rw-r--r-- | libs/gui/IConsumerListener.cpp | 26 | ||||
| -rw-r--r-- | libs/gui/include/gui/BufferQueue.h | 3 | ||||
| -rw-r--r-- | libs/gui/include/gui/ConsumerBase.h | 6 | ||||
| -rw-r--r-- | libs/gui/include/gui/IConsumerListener.h | 11 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/FrameTracer/FrameTracer.cpp | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/FrameTracer/FrameTracer.h | 2 |
11 files changed, 133 insertions, 4 deletions
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 5fb3f0b80f..c1d92a2a7f 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -43,6 +43,27 @@ void BufferQueue::ProxyConsumerListener::onDisconnect() { } } +void BufferQueue::ProxyConsumerListener::onFrameDequeued(const uint64_t bufferId) { + sp<ConsumerListener> listener(mConsumerListener.promote()); + if (listener != nullptr) { + listener->onFrameDequeued(bufferId); + } +} + +void BufferQueue::ProxyConsumerListener::onFrameCancelled(const uint64_t bufferId) { + sp<ConsumerListener> listener(mConsumerListener.promote()); + if (listener != nullptr) { + listener->onFrameCancelled(bufferId); + } +} + +void BufferQueue::ProxyConsumerListener::onFrameDetached(const uint64_t bufferId) { + sp<ConsumerListener> listener(mConsumerListener.promote()); + if (listener != nullptr) { + listener->onFrameDetached(bufferId); + } +} + void BufferQueue::ProxyConsumerListener::onFrameAvailable( const BufferItem& item) { sp<ConsumerListener> listener(mConsumerListener.promote()); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 56746749b9..09c74deee4 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -580,6 +580,11 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou } addAndGetFrameTimestamps(nullptr, outTimestamps); + { // Autolock scope + std::lock_guard<std::mutex> lock(mCore->mMutex); + mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId()); + } + return returnFlags; } @@ -621,13 +626,16 @@ status_t BufferQueueProducer::detachBuffer(int slot) { return BAD_VALUE; } + listener = mCore->mConsumerListener; + if (listener != nullptr) { + listener->onFrameDetached(mSlots[slot].mGraphicBuffer->getId()); + } mSlots[slot].mBufferState.detachProducer(); mCore->mActiveBuffers.erase(slot); mCore->mFreeSlots.insert(slot); mCore->clearBufferSlotLocked(slot); mCore->mDequeueCondition.notify_all(); VALIDATE_CONSISTENCY(); - listener = mCore->mConsumerListener; } if (listener != nullptr) { @@ -1083,6 +1091,9 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { mCore->mFreeBuffers.push_back(slot); } + if (mCore->mConsumerListener != nullptr) { + mCore->mConsumerListener->onFrameCancelled(mSlots[slot].mGraphicBuffer->getId()); + } mSlots[slot].mFence = fence; mCore->mDequeueCondition.notify_all(); VALIDATE_CONSISTENCY(); diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index abd9921fa9..9f91d9d3aa 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -101,6 +101,48 @@ void ConsumerBase::freeBufferLocked(int slotIndex) { mSlots[slotIndex].mFrameNumber = 0; } +void ConsumerBase::onFrameDequeued(const uint64_t bufferId) { + CB_LOGV("onFrameDequeued"); + + sp<FrameAvailableListener> listener; + { + Mutex::Autolock lock(mFrameAvailableMutex); + listener = mFrameAvailableListener.promote(); + } + + if (listener != nullptr) { + listener->onFrameDequeued(bufferId); + } +} + +void ConsumerBase::onFrameCancelled(const uint64_t bufferId) { + CB_LOGV("onFrameCancelled"); + + sp<FrameAvailableListener> listener; + { + Mutex::Autolock lock(mFrameAvailableMutex); + listener = mFrameAvailableListener.promote(); + } + + if (listener != nullptr) { + listener->onFrameCancelled(bufferId); + } +} + +void ConsumerBase::onFrameDetached(const uint64_t bufferId) { + CB_LOGV("onFrameDetached"); + + sp<FrameAvailableListener> listener; + { + Mutex::Autolock lock(mFrameAvailableMutex); + listener = mFrameAvailableListener.promote(); + } + + if (listener != nullptr) { + listener->onFrameDetached(bufferId); + } +} + void ConsumerBase::onFrameAvailable(const BufferItem& item) { CB_LOGV("onFrameAvailable"); diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp index 85ac304ab8..48cb4b9db8 100644 --- a/libs/gui/IConsumerListener.cpp +++ b/libs/gui/IConsumerListener.cpp @@ -28,7 +28,10 @@ enum class Tag : uint32_t { ON_FRAME_REPLACED, ON_BUFFERS_RELEASED, ON_SIDEBAND_STREAM_CHANGED, - LAST = ON_SIDEBAND_STREAM_CHANGED, + ON_FRAME_DEQUEUED, + ON_FRAME_CANCELLED, + ON_FRAME_DETACHED, + LAST = ON_FRAME_DETACHED, }; } // Anonymous namespace @@ -44,6 +47,21 @@ public: callRemoteAsync<decltype(&IConsumerListener::onDisconnect)>(Tag::ON_DISCONNECT); } + void onFrameDequeued(const uint64_t bufferId) override { + callRemoteAsync<decltype(&IConsumerListener::onFrameDequeued)>(Tag::ON_FRAME_DEQUEUED, + bufferId); + } + + void onFrameDetached(const uint64_t bufferId) override { + callRemoteAsync<decltype(&IConsumerListener::onFrameDetached)>(Tag::ON_FRAME_DETACHED, + bufferId); + } + + void onFrameCancelled(const uint64_t bufferId) override { + callRemoteAsync<decltype(&IConsumerListener::onFrameCancelled)>(Tag::ON_FRAME_CANCELLED, + bufferId); + } + void onFrameAvailable(const BufferItem& item) override { callRemoteAsync<decltype(&IConsumerListener::onFrameAvailable)>(Tag::ON_FRAME_AVAILABLE, item); @@ -93,6 +111,12 @@ status_t BnConsumerListener::onTransact(uint32_t code, const Parcel& data, Parce return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased); case Tag::ON_SIDEBAND_STREAM_CHANGED: return callLocalAsync(data, reply, &IConsumerListener::onSidebandStreamChanged); + case Tag::ON_FRAME_DEQUEUED: + return callLocalAsync(data, reply, &IConsumerListener::onFrameDequeued); + case Tag::ON_FRAME_CANCELLED: + return callLocalAsync(data, reply, &IConsumerListener::onFrameCancelled); + case Tag::ON_FRAME_DETACHED: + return callLocalAsync(data, reply, &IConsumerListener::onFrameDetached); } } diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h index da952744f3..91f80d2f17 100644 --- a/libs/gui/include/gui/BufferQueue.h +++ b/libs/gui/include/gui/BufferQueue.h @@ -63,6 +63,9 @@ public: void onFrameReplaced(const BufferItem& item) override; void onBuffersReleased() override; void onSidebandStreamChanged() override; + void onFrameDequeued(const uint64_t bufferId) override; + void onFrameCancelled(const uint64_t bufferId) override; + void onFrameDetached(const uint64_t bufferID) override; void addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) override; diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h index 366ced380b..8ff0cd0f6e 100644 --- a/libs/gui/include/gui/ConsumerBase.h +++ b/libs/gui/include/gui/ConsumerBase.h @@ -45,6 +45,9 @@ public: // See IConsumerListener::onFrame{Available,Replaced} virtual void onFrameAvailable(const BufferItem& item) = 0; virtual void onFrameReplaced(const BufferItem& /* item */) {} + virtual void onFrameDequeued(const uint64_t){}; + virtual void onFrameCancelled(const uint64_t){}; + virtual void onFrameDetached(const uint64_t){}; }; ~ConsumerBase() override; @@ -141,6 +144,9 @@ protected: // classes if they want the notification. virtual void onFrameAvailable(const BufferItem& item) override; virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onFrameDequeued(const uint64_t bufferId) override; + virtual void onFrameCancelled(const uint64_t bufferId) override; + virtual void onFrameDetached(const uint64_t bufferId) override; virtual void onBuffersReleased() override; virtual void onSidebandStreamChanged() override; diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h index c0828820e3..046f6e10d0 100644 --- a/libs/gui/include/gui/IConsumerListener.h +++ b/libs/gui/include/gui/IConsumerListener.h @@ -43,6 +43,17 @@ public: // onDisconnect is called when a producer disconnects from the BufferQueue. virtual void onDisconnect() {} /* Asynchronous */ + // onFrameDequeued is called when a call to the BufferQueueProducer::dequeueBuffer successfully + // returns a slot from the BufferQueue. + virtual void onFrameDequeued(const uint64_t) {} + + // onFrameCancelled is called when the client calls cancelBuffer, thereby releasing the slot + // back to the BufferQueue. + virtual void onFrameCancelled(const uint64_t) {} + + // onFrameDetached is called after a successful detachBuffer() call while in asynchronous mode. + virtual void onFrameDetached(const uint64_t) {} + // onFrameAvailable is called from queueBuffer each time an additional frame becomes available // for consumption. This means that frames that are queued while in asynchronous mode only // trigger the callback if no previous frames are pending. Frames queued while in synchronous diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index d80a70e4c6..b0d8287522 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -372,11 +372,17 @@ void BufferQueueLayer::latchPerFrameState( // Interface implementation for BufferLayerConsumer::ContentsChangedListener // ----------------------------------------------------------------------- +void BufferQueueLayer::onFrameDequeued(const uint64_t bufferId) { + const int32_t layerID = getSequence(); + mFlinger->mFrameTracer->traceTimestamp(layerID, bufferId, FrameTracer::UNSPECIFIED_FRAME_NUMBER, + systemTime(), FrameTracer::FrameEvent::DEQUEUE, 3000); +} + void BufferQueueLayer::onFrameAvailable(const BufferItem& item) { const int32_t layerID = getSequence(); mFlinger->mFrameTracer->traceNewLayer(layerID, getName().c_str()); mFlinger->mFrameTracer->traceTimestamp(layerID, item.mGraphicBuffer->getId(), item.mFrameNumber, - systemTime(), FrameTracer::FrameEvent::POST); + systemTime(), FrameTracer::FrameEvent::QUEUE); ATRACE_CALL(); // Add this buffer from our internal queue tracker diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index f3e8a19a7d..95e0b106d4 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -93,6 +93,7 @@ protected: void onFrameAvailable(const BufferItem& item) override; void onFrameReplaced(const BufferItem& item) override; void onSidebandStreamChanged() override; + void onFrameDequeued(const uint64_t bufferId) override; // ----------------------------------------------------------------------- public: diff --git a/services/surfaceflinger/FrameTracer/FrameTracer.cpp b/services/surfaceflinger/FrameTracer/FrameTracer.cpp index 006dbfe67e..3a0408edbd 100644 --- a/services/surfaceflinger/FrameTracer/FrameTracer.cpp +++ b/services/surfaceflinger/FrameTracer/FrameTracer.cpp @@ -133,7 +133,9 @@ void FrameTracer::traceLocked(FrameTracerDataSource::TraceContext& ctx, int32_t packet->set_timestamp(timestamp); auto* event = packet->set_graphics_frame_event()->set_buffer_event(); event->set_buffer_id(static_cast<uint32_t>(bufferID)); - event->set_frame_number(frameNumber); + if (frameNumber != UNSPECIFIED_FRAME_NUMBER) { + event->set_frame_number(frameNumber); + } event->set_type(type); if (mTraceTracker.find(layerID) != mTraceTracker.end() && diff --git a/services/surfaceflinger/FrameTracer/FrameTracer.h b/services/surfaceflinger/FrameTracer/FrameTracer.h index d4dfab94eb..e91a7503cd 100644 --- a/services/surfaceflinger/FrameTracer/FrameTracer.h +++ b/services/surfaceflinger/FrameTracer/FrameTracer.h @@ -33,6 +33,8 @@ public: virtual void OnStop(const StopArgs&) override{}; }; + static const uint64_t UNSPECIFIED_FRAME_NUMBER = std::numeric_limits<uint64_t>::max(); + using FrameEvent = perfetto::protos::pbzero::GraphicsFrameEvent; ~FrameTracer() = default; |