From 8cc8b10e27d515a6962ae6c66a62387ced45f5fe Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Oct 2016 12:43:09 -0700 Subject: Clean up FrameTimestamp log messages. Test: Log message changes only. Existing tests pass. Change-Id: I032c76393a4949b291c3a650279367caf05a775c --- services/surfaceflinger/Layer.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'services/surfaceflinger') diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a854aec4bd..8a6ec3c355 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -82,7 +82,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, mCurrentOpacity(true), mBufferLatched(false), mCurrentFrameNumber(0), - mPreviousFrameNumber(-1U), + mPreviousFrameNumber(0), mRefreshPending(false), mFrameLatencyNeeded(false), mFiltering(false), @@ -1903,8 +1903,10 @@ bool Layer::onPostComposition(const std::shared_ptr& glDoneFence, Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, compositorTiming); - mFrameEventHistory.addRetire(mPreviousFrameNumber, - retireFence); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRetire(mPreviousFrameNumber, + retireFence); + } } // Update mFrameTracker. @@ -1948,8 +1950,10 @@ void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) { 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 @@ -2135,8 +2139,10 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) auto releaseFenceTime = std::make_shared( mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); mReleaseTimeline.push(releaseFenceTime); - mFrameEventHistory.addRelease( - mPreviousFrameNumber, latchTime, std::move(releaseFenceTime)); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRelease(mPreviousFrameNumber, + latchTime, std::move(releaseFenceTime)); + } #endif } -- cgit v1.2.3-59-g8ed1b From b04c6f03a2334b03ae0105ec005aeecfa61f4a90 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Oct 2016 12:57:46 -0700 Subject: Change GL references to GPU for getFrameTimestamps. Test: Rename only. Change-Id: Idaf7ab38f78f58aa8387823f47dac084e21eb1f0 --- include/gui/FrameTimestamps.h | 2 +- libs/gui/FrameTimestamps.cpp | 4 ++-- libs/gui/Surface.cpp | 16 ++++++++-------- libs/gui/tests/Surface_test.cpp | 2 +- opengl/include/EGL/eglext.h | 2 +- opengl/libs/EGL/eglApi.cpp | 10 +++++----- opengl/specs/EGL_ANDROID_get_frame_timestamps.txt | 10 +++++----- opengl/specs/README | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 2 +- services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 2 +- 10 files changed, 26 insertions(+), 26 deletions(-) (limited to 'services/surfaceflinger') diff --git a/include/gui/FrameTimestamps.h b/include/gui/FrameTimestamps.h index 9e1ae9409e..174c5ea525 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, diff --git a/libs/gui/FrameTimestamps.cpp b/libs/gui/FrameTimestamps.cpp index 1b44e3a425..f11ffdd546 100644 --- a/libs/gui/FrameTimestamps.cpp +++ b/libs/gui/FrameTimestamps.cpp @@ -430,7 +430,7 @@ void ConsumerFrameEventHistory::addPostComposition(uint64_t frameNumber, if (!frame->addPostCompositeCalled) { frame->addPostCompositeCalled = true; frame->gpuCompositionDoneFence = gpuCompositionDone; - mFramesDirty[mCompositionOffset].setDirty(); + mFramesDirty[mCompositionOffset].setDirty(); if (!frame->displayPresentFence->isValid()) { frame->displayPresentFence = displayPresent; mFramesDirty[mCompositionOffset].setDirty(); @@ -511,7 +511,7 @@ FrameEventsDelta::FrameEventsDelta( mFirstRefreshStartTime(frameTimestamps.firstRefreshStartTime), mLastRefreshStartTime(frameTimestamps.lastRefreshStartTime), mDequeueReadyTime(frameTimestamps.dequeueReadyTime) { - if (dirtyFields.isDirty()) { + if (dirtyFields.isDirty()) { mGpuCompositionDoneFence = frameTimestamps.gpuCompositionDoneFence->getSnapshot(); } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index d285ef0ce9..45bf8c8a6b 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,7 +223,7 @@ static bool checkConsumerForUpdates( // RequestedPresent and Acquire info are always available producer-side. return checkForLatch || checkForFirstRefreshStart || - checkForLastRefreshStart || checkForGlCompositionDone || + checkForLastRefreshStart || checkForGpuCompositionDone || checkForDisplayPresent || checkForDisplayRetire || checkForDequeueReady || checkForRelease; } @@ -244,7 +244,7 @@ static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptrgetFrameTimestamps(&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/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/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h index 6572cab466..3cb7322633 100644 --- a/opengl/include/EGL/eglext.h +++ b/opengl/include/EGL/eglext.h @@ -640,7 +640,7 @@ typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROID) (co #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 4681b89aa6..32818f0f93 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -2197,7 +2197,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; @@ -2221,8 +2221,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]; @@ -2243,7 +2243,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) { @@ -2294,7 +2294,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/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d2dddba27d..0ad6287a07 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -649,7 +649,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/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, -- cgit v1.2.3-59-g8ed1b From 5ea5e5905170f32d5cf45ad35c552d64743892c3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 1 Dec 2016 16:54:33 -0800 Subject: Fix unexpected FrameEvents on BufferQueue reconnect Helps reduce the number of ALOGE's being hit when switching between apps. * Notify Layer when the Producer disconnects. * Avoid sending event deltas from a previous connection. * Avoid releasing a frame more than once. Test: adb shell /data/nativetest/libgui_test/libgui_test --gtest_filter=*GetFrameTimestamps* Change-Id: I64f314be72ddb154b584d726ac382cd468e345bf --- include/gui/BufferQueue.h | 11 ++++++----- include/gui/FrameTimestamps.h | 5 +++++ include/gui/IConsumerListener.h | 3 +++ libs/gui/BufferQueue.cpp | 7 +++++++ libs/gui/BufferQueueProducer.cpp | 1 + libs/gui/FrameTimestamps.cpp | 20 ++++++++++++++++---- libs/gui/IConsumerListener.cpp | 13 ++++++++++++- libs/gui/tests/DummyConsumer.h | 6 +++--- libs/gui/tests/IGraphicBufferProducer_test.cpp | 8 ++------ opengl/tests/EGLTest/EGL_test.cpp | 6 +++--- services/surfaceflinger/Layer.cpp | 10 +++++++++- services/surfaceflinger/Layer.h | 1 + services/surfaceflinger/SurfaceFlingerConsumer.cpp | 12 ++++++++++-- services/surfaceflinger/SurfaceFlingerConsumer.h | 5 +++-- 14 files changed, 81 insertions(+), 27 deletions(-) (limited to 'services/surfaceflinger') 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); 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 0c4af469c4..bda3c5cf94 100644 --- a/include/gui/FrameTimestamps.h +++ b/include/gui/FrameTimestamps.h @@ -78,6 +78,7 @@ struct FrameEvents { void dump(String8& outString) const; bool valid{false}; + int connectId{0}; uint64_t frameNumber{0}; // Whether or not certain points in the frame's life cycle have been @@ -212,6 +213,8 @@ class ConsumerFrameEventHistory : public FrameEventHistory { public: ~ConsumerFrameEventHistory() override; + void onDisconnect(); + void initializeCompositorTiming(const CompositorTiming& compositorTiming); void addQueue(const NewFrameEventsEntry& newEntry); @@ -233,11 +236,13 @@ private: const std::array::iterator& frame); std::array mFramesDirty; + size_t mQueueOffset{0}; size_t mCompositionOffset{0}; size_t mRetireOffset{0}; size_t mReleaseOffset{0}; + int mCurrentConnectId{0}; bool mProducerWantsEvents{false}; }; 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 listener(mConsumerListener.promote()); + if (listener != NULL) { + listener->onDisconnect(); + } +} + void BufferQueue::ProxyConsumerListener::onFrameAvailable( const BufferItem& item) { sp listener(mConsumerListener.promote()); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 3f69b1f602..be0dc20bab 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1272,6 +1272,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 f427e6899f..019a11e2b3 100644 --- a/libs/gui/FrameTimestamps.cpp +++ b/libs/gui/FrameTimestamps.cpp @@ -329,7 +329,7 @@ void ProducerFrameEventHistory::updateSignalTimes() { void ProducerFrameEventHistory::applyFenceDelta(FenceTimeline* timeline, std::shared_ptr* 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; } @@ -364,6 +364,11 @@ std::shared_ptr ProducerFrameEventHistory::createFenceTime( ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default; +void ConsumerFrameEventHistory::onDisconnect() { + mCurrentConnectId++; + mProducerWantsEvents = false; +} + void ConsumerFrameEventHistory::initializeCompositorTiming( const CompositorTiming& compositorTiming) { mCompositorTiming = compositorTiming; @@ -372,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; @@ -453,8 +459,8 @@ void ConsumerFrameEventHistory::addRetire( void ConsumerFrameEventHistory::addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime, std::shared_ptr&& release) { FrameEvents* frame = getFrame(frameNumber, &mReleaseOffset); - if (CC_UNLIKELY(frame == nullptr)) { - ALOGE("addRelease: Did not find frame (%" PRIu64 ").", frameNumber); + if (frame == nullptr) { + ALOGE_IF(mProducerWantsEvents, "addRelease: Did not find frame."); return; } frame->addReleaseCalled = true; @@ -469,13 +475,19 @@ void ConsumerFrameEventHistory::getFrameDelta( mProducerWantsEvents = true; size_t i = static_cast(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 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/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 #include @@ -64,12 +66,6 @@ namespace { const sp 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/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 8a6ec3c355..49f7480ffb 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1944,7 +1944,10 @@ bool Layer::onPostComposition(const std::shared_ptr& glDoneFence, #ifdef USE_HWC2 void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) { - mSurfaceFlingerConsumer->releasePendingBuffer(); + if (!mSurfaceFlingerConsumer->releasePendingBuffer()) { + return; + } + auto releaseFenceTime = std::make_shared( mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); mReleaseTimeline.push(releaseFenceTime); @@ -2377,6 +2380,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 8227daec8d..d979a41527 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -446,6 +446,7 @@ public: std::vector getOccupancyHistory(bool forceFlush); + void onDisconnect(); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, FrameEventHistoryDelta* outDelta); 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) } } -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 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 getPrevFinalReleaseFence() const; #ifdef USE_HWC2 virtual void setReleaseFence(const sp& fence) override; - void releasePendingBuffer(); + bool releasePendingBuffer(); #endif - virtual void addAndGetFrameTimestamps( + void onDisconnect() override; + void addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) override; -- cgit v1.2.3-59-g8ed1b