summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adithya Srinivasan <adsrini@google.com> 2019-10-09 11:43:01 -0700
committer Adithya Srinivasan <adsrini@google.com> 2019-10-23 11:43:11 -0700
commit2e43438757b21add0fd12feaa4a41926aab13c1a (patch)
treee8b5c1eb38a2e4e8a403294a1924795fb8498518
parent10d01dba75b64190628af247d5b312cf9ea9c74d (diff)
Add tracing for dequeueBuffer, detachBuffer and cancelBuffer
The FrameTracer prototype currently doesn't have some of the events traced. This change adds the plumbing required to emit dequeueBuffer, detachBuffer and cancelBuffer. Only the dequeueBuffer is made to emit the event in this CL while enabling detach and cancel to have a place if emitting is required. Test: Build and trace with GAPID and FrameTracer perfetto changes. Bug: 142502670 Change-Id: I2ba90b32d7b309a7c8145f75387c8e6f8f6bd0fb
-rw-r--r--libs/gui/BufferQueue.cpp21
-rw-r--r--libs/gui/BufferQueueProducer.cpp13
-rw-r--r--libs/gui/ConsumerBase.cpp42
-rw-r--r--libs/gui/IConsumerListener.cpp26
-rw-r--r--libs/gui/include/gui/BufferQueue.h3
-rw-r--r--libs/gui/include/gui/ConsumerBase.h6
-rw-r--r--libs/gui/include/gui/IConsumerListener.h11
-rw-r--r--services/surfaceflinger/BufferQueueLayer.cpp8
-rw-r--r--services/surfaceflinger/BufferQueueLayer.h1
-rw-r--r--services/surfaceflinger/FrameTracer/FrameTracer.cpp4
-rw-r--r--services/surfaceflinger/FrameTracer/FrameTracer.h2
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;