diff options
23 files changed, 169 insertions, 102 deletions
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index a523cd80bf..c95c535363 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -62,11 +62,12 @@ public: public: explicit ProxyConsumerListener(const wp<ConsumerListener>& consumerListener); virtual ~ProxyConsumerListener(); - virtual void onFrameAvailable(const BufferItem& item) override; - virtual void onFrameReplaced(const BufferItem& item) override; - virtual void onBuffersReleased() override; - virtual void onSidebandStreamChanged() override; - virtual void addAndGetFrameTimestamps( + void onDisconnect() override; + void onFrameAvailable(const BufferItem& item) override; + void onFrameReplaced(const BufferItem& item) override; + void onBuffersReleased() override; + void onSidebandStreamChanged() override; + void addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) override; private: diff --git a/include/gui/FrameTimestamps.h b/include/gui/FrameTimestamps.h index 9e1ae9409e..bda3c5cf94 100644 --- a/include/gui/FrameTimestamps.h +++ b/include/gui/FrameTimestamps.h @@ -41,7 +41,7 @@ enum class FrameEvent { ACQUIRE, FIRST_REFRESH_START, LAST_REFRESH_START, - GL_COMPOSITION_DONE, + GPU_COMPOSITION_DONE, DISPLAY_PRESENT, DISPLAY_RETIRE, DEQUEUE_READY, @@ -52,6 +52,16 @@ enum class FrameEvent { // A collection of timestamps corresponding to a single frame. struct FrameEvents { + static constexpr auto EVENT_COUNT = + static_cast<size_t>(FrameEvent::EVENT_COUNT); + static_assert(EVENT_COUNT <= 32, "Event count sanity check failed."); + static constexpr nsecs_t TIMESTAMP_PENDING = + std::numeric_limits<nsecs_t>::max(); + + static inline bool isValidTimestamp(nsecs_t time) { + return time != TIMESTAMP_PENDING; + } + bool hasPostedInfo() const; bool hasRequestedPresentInfo() const; bool hasLatchInfo() const; @@ -67,11 +77,8 @@ struct FrameEvents { void checkFencesForCompletion(); void dump(String8& outString) const; - static constexpr size_t EVENT_COUNT = - static_cast<size_t>(FrameEvent::EVENT_COUNT); - static_assert(EVENT_COUNT <= 32, "Event count sanity check failed."); - bool valid{false}; + int connectId{0}; uint64_t frameNumber{0}; // Whether or not certain points in the frame's life cycle have been @@ -81,12 +88,12 @@ struct FrameEvents { bool addRetireCalled{false}; bool addReleaseCalled{false}; - nsecs_t postedTime{-1}; - nsecs_t requestedPresentTime{-1}; - nsecs_t latchTime{-1}; - nsecs_t firstRefreshStartTime{-1}; - nsecs_t lastRefreshStartTime{-1}; - nsecs_t dequeueReadyTime{-1}; + nsecs_t postedTime{TIMESTAMP_PENDING}; + nsecs_t requestedPresentTime{TIMESTAMP_PENDING}; + nsecs_t latchTime{TIMESTAMP_PENDING}; + nsecs_t firstRefreshStartTime{TIMESTAMP_PENDING}; + nsecs_t lastRefreshStartTime{TIMESTAMP_PENDING}; + nsecs_t dequeueReadyTime{TIMESTAMP_PENDING}; std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE}; std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE}; @@ -206,6 +213,8 @@ class ConsumerFrameEventHistory : public FrameEventHistory { public: ~ConsumerFrameEventHistory() override; + void onDisconnect(); + void initializeCompositorTiming(const CompositorTiming& compositorTiming); void addQueue(const NewFrameEventsEntry& newEntry); @@ -227,11 +236,13 @@ private: const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame); std::array<FrameEventDirtyFields, MAX_FRAME_HISTORY> mFramesDirty; + size_t mQueueOffset{0}; size_t mCompositionOffset{0}; size_t mRetireOffset{0}; size_t mReleaseOffset{0}; + int mCurrentConnectId{0}; bool mProducerWantsEvents{false}; }; @@ -273,12 +284,12 @@ private: bool mAddRetireCalled{0}; bool mAddReleaseCalled{0}; - nsecs_t mPostedTime{0}; - nsecs_t mRequestedPresentTime{0}; - nsecs_t mLatchTime{0}; - nsecs_t mFirstRefreshStartTime{0}; - nsecs_t mLastRefreshStartTime{0}; - nsecs_t mDequeueReadyTime{0}; + nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING}; FenceTime::Snapshot mGpuCompositionDoneFence; FenceTime::Snapshot mDisplayPresentFence; diff --git a/include/gui/IConsumerListener.h b/include/gui/IConsumerListener.h index 93dd4acf96..a3c7d6496d 100644 --- a/include/gui/IConsumerListener.h +++ b/include/gui/IConsumerListener.h @@ -43,6 +43,9 @@ public: ConsumerListener() { } virtual ~ConsumerListener(); + // onDisconnect is called when a producer disconnects from the BufferQueue. + virtual void onDisconnect() {} /* Asynchronous */ + // 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 diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index f76a282af6..13692eb982 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -31,6 +31,13 @@ BufferQueue::ProxyConsumerListener::ProxyConsumerListener( BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} +void BufferQueue::ProxyConsumerListener::onDisconnect() { + sp<ConsumerListener> listener(mConsumerListener.promote()); + if (listener != NULL) { + listener->onDisconnect(); + } +} + 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 0cbafcf864..27ced6180b 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1275,6 +1275,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); + listener->onDisconnect(); } return status; diff --git a/libs/gui/FrameTimestamps.cpp b/libs/gui/FrameTimestamps.cpp index a6fa38aae5..019a11e2b3 100644 --- a/libs/gui/FrameTimestamps.cpp +++ b/libs/gui/FrameTimestamps.cpp @@ -16,6 +16,8 @@ #include <gui/FrameTimestamps.h> +#define LOG_TAG "FrameEvents" + #include <cutils/compiler.h> // For CC_[UN]LIKELY #include <inttypes.h> #include <utils/Log.h> @@ -33,19 +35,19 @@ namespace android { // ============================================================================ bool FrameEvents::hasPostedInfo() const { - return Fence::isValidTimestamp(postedTime); + return FrameEvents::isValidTimestamp(postedTime); } bool FrameEvents::hasRequestedPresentInfo() const { - return Fence::isValidTimestamp(requestedPresentTime); + return FrameEvents::isValidTimestamp(requestedPresentTime); } bool FrameEvents::hasLatchInfo() const { - return Fence::isValidTimestamp(latchTime); + return FrameEvents::isValidTimestamp(latchTime); } bool FrameEvents::hasFirstRefreshStartInfo() const { - return Fence::isValidTimestamp(firstRefreshStartTime); + return FrameEvents::isValidTimestamp(firstRefreshStartTime); } bool FrameEvents::hasLastRefreshStartInfo() const { @@ -56,7 +58,7 @@ bool FrameEvents::hasLastRefreshStartInfo() const { } bool FrameEvents::hasDequeueReadyInfo() const { - return Fence::isValidTimestamp(dequeueReadyTime); + return FrameEvents::isValidTimestamp(dequeueReadyTime); } bool FrameEvents::hasAcquireInfo() const { @@ -117,21 +119,21 @@ void FrameEvents::dump(String8& outString) const outString.appendFormat("--- Req. Present\t%" PRId64 "\n", requestedPresentTime); outString.appendFormat("--- Latched \t"); - if (Fence::isValidTimestamp(latchTime)) { + if (FrameEvents::isValidTimestamp(latchTime)) { outString.appendFormat("%" PRId64 "\n", latchTime); } else { outString.appendFormat("Pending\n"); } outString.appendFormat("--- Refresh (First)\t"); - if (Fence::isValidTimestamp(firstRefreshStartTime)) { + if (FrameEvents::isValidTimestamp(firstRefreshStartTime)) { outString.appendFormat("%" PRId64 "\n", firstRefreshStartTime); } else { outString.appendFormat("Pending\n"); } outString.appendFormat("--- Refresh (Last)\t"); - if (Fence::isValidTimestamp(lastRefreshStartTime)) { + if (FrameEvents::isValidTimestamp(lastRefreshStartTime)) { outString.appendFormat("%" PRId64 "\n", lastRefreshStartTime); } else { outString.appendFormat("Pending\n"); @@ -147,7 +149,7 @@ void FrameEvents::dump(String8& outString) const !addRetireCalled, *displayRetireFence); outString.appendFormat("--- DequeueReady \t"); - if (Fence::isValidTimestamp(dequeueReadyTime)) { + if (FrameEvents::isValidTimestamp(dequeueReadyTime)) { outString.appendFormat("%" PRId64 "\n", dequeueReadyTime); } else { outString.appendFormat("Pending\n"); @@ -256,8 +258,7 @@ void ProducerFrameEventHistory::updateAcquireFence( uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire) { FrameEvents* frame = getFrame(frameNumber, &mAcquireOffset); if (frame == nullptr) { - ALOGE("ProducerFrameEventHistory::updateAcquireFence: " - "Did not find frame."); + ALOGE("updateAcquireFence: Did not find frame."); return; } @@ -277,8 +278,8 @@ void ProducerFrameEventHistory::applyDelta( for (auto& d : delta.mDeltas) { // Avoid out-of-bounds access. - if (d.mIndex >= mFrames.size()) { - ALOGE("ProducerFrameEventHistory::applyDelta: Bad index."); + if (CC_UNLIKELY(d.mIndex >= mFrames.size())) { + ALOGE("applyDelta: Bad index."); return; } @@ -328,7 +329,7 @@ void ProducerFrameEventHistory::updateSignalTimes() { void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline, std::shared_ptr<FenceTime>* dst, const FenceTime::Snapshot& src) const { - if (CC_UNLIKELY(dst == nullptr)) { + if (CC_UNLIKELY(dst == nullptr || dst->get() == nullptr)) { ALOGE("applyFenceDelta: dst is null."); return; } @@ -337,9 +338,7 @@ void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline, case FenceTime::Snapshot::State::EMPTY: return; case FenceTime::Snapshot::State::FENCE: - if (CC_UNLIKELY((*dst)->isValid())) { - ALOGE("applyFenceDelta: Unexpected fence."); - } + ALOGE_IF((*dst)->isValid(), "applyFenceDelta: Unexpected fence."); *dst = createFenceTime(src.fence); timeline->push(*dst); return; @@ -365,6 +364,11 @@ std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime( ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default; +void ConsumerFrameEventHistory::onDisconnect() { + mCurrentConnectId++; + mProducerWantsEvents = false; +} + void ConsumerFrameEventHistory::initializeCompositorTiming( const CompositorTiming& compositorTiming) { mCompositorTiming = compositorTiming; @@ -373,6 +377,7 @@ void ConsumerFrameEventHistory::initializeCompositorTiming( void ConsumerFrameEventHistory::addQueue(const NewFrameEventsEntry& newEntry) { // Overwrite all fields of the frame with default values unless set here. FrameEvents newTimestamps; + newTimestamps.connectId = mCurrentConnectId; newTimestamps.frameNumber = newEntry.frameNumber; newTimestamps.postedTime = newEntry.postedTime; newTimestamps.requestedPresentTime = newEntry.requestedPresentTime; @@ -409,7 +414,7 @@ void ConsumerFrameEventHistory::addPreComposition( } frame->lastRefreshStartTime = refreshStartTime; mFramesDirty[mCompositionOffset].setDirty<FrameEvent::LAST_REFRESH_START>(); - if (!Fence::isValidTimestamp(frame->firstRefreshStartTime)) { + if (!FrameEvents::isValidTimestamp(frame->firstRefreshStartTime)) { frame->firstRefreshStartTime = refreshStartTime; mFramesDirty[mCompositionOffset].setDirty<FrameEvent::FIRST_REFRESH_START>(); } @@ -431,7 +436,7 @@ void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber, if (!frame->addPostCompositeCalled) { frame->addPostCompositeCalled = true; frame->gpuCompositionDoneFence = gpuCompositionDone; - mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GL_COMPOSITION_DONE>(); + mFramesDirty[mCompositionOffset].setDirty<FrameEvent::GPU_COMPOSITION_DONE>(); if (!frame->displayPresentFence->isValid()) { frame->displayPresentFence = displayPresent; mFramesDirty[mCompositionOffset].setDirty<FrameEvent::DISPLAY_PRESENT>(); @@ -455,7 +460,7 @@ void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime, std::shared_ptr<FenceTime>&& release) { FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset); if (frame == nullptr) { - ALOGE("ConsumerFrameEventHistory::addRelease: Did not find frame."); + ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame."); return; } frame->addReleaseCalled = true; @@ -470,13 +475,19 @@ void ConsumerFrameEventHistory::getFrameDelta( mProducerWantsEvents = true; size_t i = static_cast<size_t>(std::distance(mFrames.begin(), frame)); if (mFramesDirty[i].anyDirty()) { - delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]); + // Make sure only to send back deltas for the current connection + // since the producer won't have the correct state to apply a delta + // from a previous connection. + if (mFrames[i].connectId == mCurrentConnectId) { + delta->mDeltas.emplace_back(i, *frame, mFramesDirty[i]); + } mFramesDirty[i].reset(); } } void ConsumerFrameEventHistory::getAndResetDelta( FrameEventHistoryDelta* delta) { + mProducerWantsEvents = true; delta->mCompositorTiming = mCompositorTiming; // Write these in order of frame number so that it is easy to @@ -512,7 +523,7 @@ FrameEventsDelta::FrameEventsDelta( mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime), mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime), mDequeueReadyTime(frameTimestamps.dequeueReadyTime) { - if (dirtyFields.isDirty<FrameEvent::GL_COMPOSITION_DONE>()) { + if (dirtyFields.isDirty<FrameEvent::GPU_COMPOSITION_DONE>()) { mGpuCompositionDoneFence = frameTimestamps.gpuCompositionDoneFence->getSnapshot(); } @@ -648,7 +659,7 @@ FrameEventHistoryDelta& FrameEventHistoryDelta::operator=( mCompositorTiming = src.mCompositorTiming; if (CC_UNLIKELY(!mDeltas.empty())) { - ALOGE("FrameEventHistoryDelta: Clobbering history."); + ALOGE("FrameEventHistoryDelta assign clobbering history."); } mDeltas = std::move(src.mDeltas); ALOGE_IF(src.mDeltas.empty(), "Source mDeltas not empty."); diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp index 3d893b15d5..8cadc4de1b 100644 --- a/libs/gui/IConsumerListener.cpp +++ b/libs/gui/IConsumerListener.cpp @@ -28,7 +28,8 @@ namespace android { // --------------------------------------------------------------------------- enum { - ON_FRAME_AVAILABLE = IBinder::FIRST_CALL_TRANSACTION, + ON_DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, + ON_FRAME_AVAILABLE, ON_BUFFER_RELEASED, ON_SIDEBAND_STREAM_CHANGED, GET_FRAME_TIMESTAMPS @@ -43,6 +44,12 @@ public: virtual ~BpConsumerListener(); + virtual void onDisconnect() { + Parcel data, reply; + data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor()); + remote()->transact(ON_DISCONNECT, data, &reply, IBinder::FLAG_ONEWAY); + } + virtual void onFrameAvailable(const BufferItem& item) { Parcel data, reply; data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor()); @@ -75,6 +82,10 @@ status_t BnConsumerListener::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { + case ON_DISCONNECT: { + CHECK_INTERFACE(IConsumerListener, data, reply); + onDisconnect(); + return NO_ERROR; } case ON_FRAME_AVAILABLE: { CHECK_INTERFACE(IConsumerListener, data, reply); BufferItem item; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index d285ef0ce9..efb15245a6 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -196,7 +196,7 @@ static bool checkConsumerForUpdates( const nsecs_t* outLatchTime, const nsecs_t* outFirstRefreshStartTime, const nsecs_t* outLastRefreshStartTime, - const nsecs_t* outGlCompositionDoneTime, + const nsecs_t* outGpuCompositionDoneTime, const nsecs_t* outDisplayPresentTime, const nsecs_t* outDisplayRetireTime, const nsecs_t* outDequeueReadyTime, @@ -204,7 +204,7 @@ static bool checkConsumerForUpdates( bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo(); bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) && !e->hasFirstRefreshStartInfo(); - bool checkForGlCompositionDone = (outGlCompositionDoneTime != nullptr) && + bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) && !e->hasGpuCompositionDoneInfo(); bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && !e->hasDisplayPresentInfo(); @@ -223,14 +223,14 @@ static bool checkConsumerForUpdates( // RequestedPresent and Acquire info are always available producer-side. return checkForLatch || checkForFirstRefreshStart || - checkForLastRefreshStart || checkForGlCompositionDone || + checkForLastRefreshStart || checkForGpuCompositionDone || checkForDisplayPresent || checkForDisplayRetire || checkForDequeueReady || checkForRelease; } static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { if (dst != nullptr) { - *dst = Fence::isValidTimestamp(src) ? src : 0; + *dst = FrameEvents::isValidTimestamp(src) ? src : 0; } } @@ -244,7 +244,7 @@ static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime status_t Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime, - nsecs_t* outLastRefreshStartTime, nsecs_t* outGlCompositionDoneTime, + nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime, nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, nsecs_t* outDequeueReadyTime, nsecs_t* outReleaseTime) { ATRACE_CALL(); @@ -274,7 +274,7 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, // Update our cache of events if the requested events are not available. if (checkConsumerForUpdates(events, mLastFrameNumber, outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime, - outGlCompositionDoneTime, outDisplayPresentTime, + outGpuCompositionDoneTime, outDisplayPresentTime, outDisplayRetireTime, outDequeueReadyTime, outReleaseTime)) { FrameEventHistoryDelta delta; mGraphicBufferProducer->getFrameTimestamps(&delta); @@ -296,7 +296,7 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, getFrameTimestampFence(outAcquireTime, events->acquireFence); getFrameTimestampFence( - outGlCompositionDoneTime, events->gpuCompositionDoneFence); + outGpuCompositionDoneTime, events->gpuCompositionDoneFence); getFrameTimestampFence( outDisplayPresentTime, events->displayPresentFence); getFrameTimestampFence(outDisplayRetireTime, events->displayRetireFence); @@ -1032,7 +1032,7 @@ int Surface::dispatchGetFrameTimestamps(va_list args) { nsecs_t* outLatchTime = va_arg(args, int64_t*); nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*); nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*); - nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*); + nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*); nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*); nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*); @@ -1040,7 +1040,7 @@ int Surface::dispatchGetFrameTimestamps(va_list args) { return getFrameTimestamps(frameId, outRequestedPresentTime, outAcquireTime, outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime, - outGlCompositionDoneTime, outDisplayPresentTime, + outGpuCompositionDoneTime, outDisplayPresentTime, outDisplayRetireTime, outDequeueReadyTime, outReleaseTime); } diff --git a/libs/gui/tests/DummyConsumer.h b/libs/gui/tests/DummyConsumer.h index 0511e165c2..502bdf981b 100644 --- a/libs/gui/tests/DummyConsumer.h +++ b/libs/gui/tests/DummyConsumer.h @@ -19,9 +19,9 @@ namespace android { struct DummyConsumer : public BnConsumerListener { - virtual void onFrameAvailable(const BufferItem& /* item */) {} - virtual void onBuffersReleased() {} - virtual void onSidebandStreamChanged() {} + void onFrameAvailable(const BufferItem& /* item */) override {} + void onBuffersReleased() override {} + void onSidebandStreamChanged() override {} }; } // namespace android diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 0329a6d61f..aa071f68b0 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -17,6 +17,8 @@ #define LOG_TAG "IGraphicBufferProducer_test" //#define LOG_NDEBUG 0 +#include "DummyConsumer.h" + #include <gtest/gtest.h> #include <utils/String8.h> @@ -64,12 +66,6 @@ namespace { const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE; }; // namespace anonymous -struct DummyConsumer : public BnConsumerListener { - virtual void onFrameAvailable(const BufferItem& /* item */) {} - virtual void onBuffersReleased() {} - virtual void onSidebandStreamChanged() {} -}; - class IGraphicBufferProducerTest : public ::testing::Test { protected: diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 52980270f2..ceeb90a4f6 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -364,7 +364,7 @@ public: FrameEvent::LATCH, FrameEvent::FIRST_REFRESH_START, FrameEvent::LAST_REFRESH_START, - FrameEvent::GL_COMPOSITION_DONE, + FrameEvent::GPU_COMPOSITION_DONE, FrameEvent::DEQUEUE_READY, FrameEvent::RELEASE }; diff --git a/libs/ui/FenceTime.cpp b/libs/ui/FenceTime.cpp index 8106b16009..14147663de 100644 --- a/libs/ui/FenceTime.cpp +++ b/libs/ui/FenceTime.cpp @@ -16,6 +16,8 @@ #include <ui/FenceTime.h> +#define LOG_TAG "FenceTime" + #include <cutils/compiler.h> // For CC_[UN]LIKELY #include <utils/Log.h> #include <inttypes.h> @@ -62,8 +64,11 @@ FenceTime::FenceTime(sp<Fence>&& fence) FenceTime::FenceTime(nsecs_t signalTime) : mState(Fence::isValidTimestamp(signalTime) ? State::VALID : State::INVALID), mFence(nullptr), - mSignalTime(signalTime == Fence::SIGNAL_TIME_PENDING ? - Fence::SIGNAL_TIME_INVALID : signalTime) { + mSignalTime(signalTime) { + if (CC_UNLIKELY(mSignalTime == Fence::SIGNAL_TIME_PENDING)) { + ALOGE("Pending signal time not allowed after signal."); + mSignalTime = Fence::SIGNAL_TIME_INVALID; + } } void FenceTime::applyTrustedSnapshot(const Snapshot& src) { @@ -71,7 +76,7 @@ void FenceTime::applyTrustedSnapshot(const Snapshot& src) { // Applying Snapshot::State::FENCE, could change the valid state of the // FenceTime, which is not allowed. Callers should create a new // FenceTime from the snapshot instead. - ALOGE("FenceTime::applyTrustedSnapshot: Unexpected fence."); + ALOGE("applyTrustedSnapshot: Unexpected fence."); return; } @@ -332,16 +337,13 @@ void FenceToFenceTimeMap::signalAllForTest( continue; } ALOGE_IF(!fenceTime->isValid(), - "FenceToFenceTimeMap::signalAllForTest: " - "Signaling invalid fence."); + "signalAllForTest: Signaling invalid fence."); fenceTime->signalForTest(signalTime); signaled = true; } } - if (!signaled) { - ALOGE("FenceToFenceTimeMap::signalAllForTest: Nothing to signal."); - } + ALOGE_IF(!signaled, "signalAllForTest: Nothing to signal."); } void FenceToFenceTimeMap::garbageCollectLocked() { diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h index df84c934de..0ac74db07d 100644 --- a/opengl/include/EGL/eglext.h +++ b/opengl/include/EGL/eglext.h @@ -650,7 +650,7 @@ typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const #define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3153 #define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3154 #define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3155 -#define EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID 0x3156 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3156 #define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3157 #define EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3158 #define EGL_DEQUEUE_READY_TIME_ANDROID 0x3159 diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index ef3d7a3fa2..f15c29d4ad 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -2214,7 +2214,7 @@ EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, nsecs_t* acquireTime = nullptr; nsecs_t* latchTime = nullptr; nsecs_t* firstRefreshStartTime = nullptr; - nsecs_t* GLCompositionDoneTime = nullptr; + nsecs_t* gpuCompositionDoneTime = nullptr; nsecs_t* lastRefreshStartTime = nullptr; nsecs_t* displayPresentTime = nullptr; nsecs_t* displayRetireTime = nullptr; @@ -2238,8 +2238,8 @@ EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, case EGL_LAST_COMPOSITION_START_TIME_ANDROID: lastRefreshStartTime = &values[i]; break; - case EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID: - GLCompositionDoneTime = &values[i]; + case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID: + gpuCompositionDoneTime = &values[i]; break; case EGL_DISPLAY_PRESENT_TIME_ANDROID: displayPresentTime = &values[i]; @@ -2260,7 +2260,7 @@ EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, status_t ret = native_window_get_frame_timestamps(s->win.get(), frameId, requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime, - lastRefreshStartTime, GLCompositionDoneTime, displayPresentTime, + lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime, displayRetireTime, dequeueReadyTime, releaseTime); switch (ret) { @@ -2311,7 +2311,7 @@ EGLBoolean eglGetFrameTimestampSupportedANDROID( case EGL_COMPOSITION_LATCH_TIME_ANDROID: case EGL_FIRST_COMPOSITION_START_TIME_ANDROID: case EGL_LAST_COMPOSITION_START_TIME_ANDROID: - case EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID: + case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID: case EGL_DEQUEUE_READY_TIME_ANDROID: case EGL_READS_DONE_TIME_ANDROID: return EGL_TRUE; diff --git a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt index d0ed8e172f..e32d9e66a3 100644 --- a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt +++ b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt @@ -90,7 +90,7 @@ New Tokens EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3153 EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3154 EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3155 - EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID 0x3156 + EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3156 EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3157 EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3158 EGL_DEQUEUE_READY_TIME_ANDROID 0x3159 @@ -189,10 +189,10 @@ Changes to Chapter 3 of the EGL 1.5 Specification (EGL Functions and Errors) that indicates the subsequent frame was not submitted in time to be latched by the compositor. Note: The value may not be updated for every display refresh if the compositor becomes idle. - - EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID - The time at which the - compositor's rendering work for this frame finished. This will be zero - if composition was handled by the display and the compositor didn't do - any rendering. + - EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID - The time at which + the compositor's rendering work for this frame finished. This will be + zero if composition was handled by the display and the compositor + didn't do any rendering. - EGL_DISPLAY_PRESENT_TIME_ANDROID - The time at which this frame started to scan out to the physical display. - EGL_DISPLAY_RETIRE_TIME_ANDROID - The time at which this frame was diff --git a/opengl/specs/README b/opengl/specs/README index 0c49023f08..a7a9785d56 100644 --- a/opengl/specs/README +++ b/opengl/specs/README @@ -28,7 +28,7 @@ for use by Android extensions. 0x3153 EGL_COMPOSITION_LATCH_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) 0x3154 EGL_FIRST_COMPOSITION_START_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) 0x3155 EGL_LAST_COMPOSITION_START_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) -0x3156 EGL_FIRST_COMPOSITION_FINISHED_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) +0x3156 EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) 0x3157 EGL_DISPLAY_PRESENT_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) 0x3158 EGL_DISPLAY_RETIRE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) 0x3159 EGL_DEQUEUE_READY_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps) diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp index 1cd40b3957..1b3086be69 100644 --- a/opengl/tests/EGLTest/EGL_test.cpp +++ b/opengl/tests/EGLTest/EGL_test.cpp @@ -106,9 +106,9 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs)); struct DummyConsumer : public BnConsumerListener { - virtual void onFrameAvailable(const BufferItem& /* item */) {} - virtual void onBuffersReleased() {} - virtual void onSidebandStreamChanged() {} + void onFrameAvailable(const BufferItem& /* item */) override {} + void onBuffersReleased() override {} + void onSidebandStreamChanged() override {} }; // Create a EGLSurface diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 46a7338b10..4ea029f5b1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -82,7 +82,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mCurrentOpacity(true), mBufferLatched(false), mCurrentFrameNumber(0), - mPreviousFrameNumber(-1U), + mPreviousFrameNumber(0), mRefreshPending(false), mFrameLatencyNeeded(false), mFiltering(false), @@ -1904,8 +1904,10 @@ bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, compositorTiming); - mFrameEventHistory.addRetire(mPreviousFrameNumber, - retireFence); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRetire(mPreviousFrameNumber, + retireFence); + } } // Update mFrameTracker. @@ -1943,14 +1945,19 @@ bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, #ifdef USE_HWC2 void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) { - mSurfaceFlingerConsumer->releasePendingBuffer(); + if (!mSurfaceFlingerConsumer->releasePendingBuffer()) { + return; + } + auto releaseFenceTime = std::make_shared<FenceTime>( mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); mReleaseTimeline.push(releaseFenceTime); Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addRelease( - mPreviousFrameNumber, dequeueReadyTime, std::move(releaseFenceTime)); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRelease(mPreviousFrameNumber, + dequeueReadyTime, std::move(releaseFenceTime)); + } } #endif @@ -2136,8 +2143,10 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) auto releaseFenceTime = std::make_shared<FenceTime>( mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); mReleaseTimeline.push(releaseFenceTime); - mFrameEventHistory.addRelease( - mPreviousFrameNumber, latchTime, std::move(releaseFenceTime)); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRelease(mPreviousFrameNumber, + latchTime, std::move(releaseFenceTime)); + } #endif } @@ -2372,6 +2381,11 @@ void Layer::dumpFrameEvents(String8& result) { mFrameEventHistory.dump(result); } +void Layer::onDisconnect() { + Mutex::Autolock lock(mFrameEventHistoryMutex); + mFrameEventHistory.onDisconnect(); +} + void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta *outDelta) { Mutex::Autolock lock(mFrameEventHistoryMutex); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c578e077fe..ae2c962588 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -444,6 +444,7 @@ public: std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush); + void onDisconnect(); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, FrameEventHistoryDelta* outDelta); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 462e5a6758..215628de0f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -639,7 +639,7 @@ status_t SurfaceFlinger::getSupportedFrameTimestamps( FrameEvent::LATCH, FrameEvent::FIRST_REFRESH_START, FrameEvent::LAST_REFRESH_START, - FrameEvent::GL_COMPOSITION_DONE, + FrameEvent::GPU_COMPOSITION_DONE, getHwComposer().presentFenceRepresentsStartOfScanout() ? FrameEvent::DISPLAY_PRESENT : FrameEvent::DISPLAY_RETIRE, FrameEvent::DEQUEUE_READY, diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index 942af139ec..bb1ff06065 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -211,11 +211,11 @@ void SurfaceFlingerConsumer::setReleaseFence(const sp<Fence>& fence) } } -void SurfaceFlingerConsumer::releasePendingBuffer() +bool SurfaceFlingerConsumer::releasePendingBuffer() { if (!mPendingRelease.isPending) { ALOGV("Pending buffer already released"); - return; + return false; } ALOGV("Releasing pending buffer"); Mutex::Autolock lock(mMutex); @@ -225,6 +225,7 @@ void SurfaceFlingerConsumer::releasePendingBuffer() ALOGE_IF(result != NO_ERROR, "releasePendingBuffer failed: %s (%d)", strerror(-result), result); mPendingRelease = PendingRelease(); + return true; } #endif @@ -261,6 +262,13 @@ void SurfaceFlingerConsumer::onSidebandStreamChanged() { } } +void SurfaceFlingerConsumer::onDisconnect() { + sp<Layer> l = mLayer.promote(); + if (l.get()) { + l->onDisconnect(); + } +} + void SurfaceFlingerConsumer::addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta *outDelta) { diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 7713ed2408..1531e2c5ca 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -82,10 +82,11 @@ public: sp<Fence> getPrevFinalReleaseFence() const; #ifdef USE_HWC2 virtual void setReleaseFence(const sp<Fence>& fence) override; - void releasePendingBuffer(); + bool releasePendingBuffer(); #endif - virtual void addAndGetFrameTimestamps( + void onDisconnect() override; + void addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) override; diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index 477eb27063..e6ab29a4fb 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -640,7 +640,7 @@ status_t SurfaceFlinger::getSupportedFrameTimestamps( FrameEvent::LATCH, FrameEvent::FIRST_REFRESH_START, FrameEvent::LAST_REFRESH_START, - FrameEvent::GL_COMPOSITION_DONE, + FrameEvent::GPU_COMPOSITION_DONE, FrameEvent::DISPLAY_RETIRE, FrameEvent::DEQUEUE_READY, FrameEvent::RELEASE, |