From ce796e78a57018f186b062199c75d94545318aca Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 4 Feb 2016 19:10:51 -0800 Subject: Plumbing for getting FenceTracker timestamps Change-Id: I1ebee9e42e28658bd3a2b161fdaabb7da756d8f3 --- libs/gui/Surface.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 6811269a39..85c194d457 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -133,6 +133,39 @@ status_t Surface::getLastQueuedBuffer(sp* outBuffer, outTransformMatrix); } +bool Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outPostedTime, + nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime, + nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime, + nsecs_t* outReleaseTime) { + ATRACE_CALL(); + + FrameTimestamps timestamps; + bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber, + ×tamps); + if (found) { + if (outPostedTime) { + *outPostedTime = timestamps.postedTime; + } + if (outAcquireTime) { + *outAcquireTime = timestamps.acquireTime; + } + if (outRefreshStartTime) { + *outRefreshStartTime = timestamps.refreshStartTime; + } + if (outGlCompositionDoneTime) { + *outGlCompositionDoneTime = timestamps.glCompositionDoneTime; + } + if (outDisplayRetireTime) { + *outDisplayRetireTime = timestamps.displayRetireTime; + } + if (outReleaseTime) { + *outReleaseTime = timestamps.releaseTime; + } + return true; + } + return false; +} + int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { Surface* c = getSelf(window); return c->setSwapInterval(interval); @@ -614,6 +647,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_AUTO_REFRESH: res = dispatchSetAutoRefresh(args); break; + case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS: + res = dispatchGetFrameTimestamps(args); + break; default: res = NAME_NOT_FOUND; break; @@ -734,6 +770,20 @@ int Surface::dispatchSetAutoRefresh(va_list args) { return setAutoRefresh(autoRefresh); } +int Surface::dispatchGetFrameTimestamps(va_list args) { + uint32_t framesAgo = va_arg(args, uint32_t); + nsecs_t* outPostedTime = va_arg(args, int64_t*); + nsecs_t* outAcquireTime = va_arg(args, int64_t*); + nsecs_t* outRefreshStartTime = va_arg(args, int64_t*); + nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*); + nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*); + nsecs_t* outReleaseTime = va_arg(args, int64_t*); + bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, + outPostedTime, outAcquireTime, outRefreshStartTime, + outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime); + return ret ? NO_ERROR : BAD_VALUE; +} + int Surface::connect(int api) { static sp listener = new DummyProducerListener(); return connect(api, listener); -- cgit v1.2.3-59-g8ed1b From 8e3e92b906db431c4fa822f21242977d4ee99942 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Mon, 27 Jun 2016 17:56:53 -0700 Subject: BQ: Add and expose a unique id Bug 29422927 Change-Id: I80eab94f073ebc378302f00fa86a740c3643657e --- include/gui/BufferQueueCore.h | 2 ++ include/gui/BufferQueueProducer.h | 3 ++ include/gui/IGraphicBufferProducer.h | 3 ++ include/gui/Surface.h | 2 ++ libs/gui/BufferQueueCore.cpp | 9 +++++- libs/gui/BufferQueueProducer.cpp | 7 +++++ libs/gui/IGraphicBufferProducer.cpp | 34 ++++++++++++++++++++++ libs/gui/Surface.cpp | 5 ++++ .../DisplayHardware/VirtualDisplaySurface.cpp | 5 ++++ .../DisplayHardware/VirtualDisplaySurface.h | 1 + services/surfaceflinger/MonitoredProducer.cpp | 4 +++ services/surfaceflinger/MonitoredProducer.h | 1 + 12 files changed, 75 insertions(+), 1 deletion(-) (limited to 'libs/gui/Surface.cpp') diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h index 4337da9b04..0371db780b 100644 --- a/include/gui/BufferQueueCore.h +++ b/include/gui/BufferQueueCore.h @@ -322,6 +322,8 @@ private: // The slot of the last queued buffer int mLastQueuedSlot; + const uint64_t mUniqueId; + }; // class BufferQueueCore } // namespace android diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h index a75ed98b57..48c3396ce4 100644 --- a/include/gui/BufferQueueProducer.h +++ b/include/gui/BufferQueueProducer.h @@ -186,6 +186,9 @@ public: virtual status_t getLastQueuedBuffer(sp* outBuffer, sp* outFence, float outTransformMatrix[16]) override; + // See IGraphicBufferProducer::getUniqueId + virtual status_t getUniqueId(uint64_t* outId) const override; + private: // This is required by the IBinder::DeathRecipient interface virtual void binderDied(const wp& who); diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index 37ae6df39e..336ca70746 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -568,6 +568,9 @@ public: // Returns NO_ERROR or the status of the Binder transaction virtual status_t getLastQueuedBuffer(sp* outBuffer, sp* outFence, float outTransformMatrix[16]) = 0; + + // Returns a unique id for this BufferQueue + virtual status_t getUniqueId(uint64_t* outId) const = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 646203bd9a..bcce14a42e 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -134,6 +134,8 @@ public: status_t getLastQueuedBuffer(sp* outBuffer, sp* outFence, float outTransformMatrix[16]); + status_t getUniqueId(uint64_t* outId) const; + protected: virtual ~Surface(); diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index ba34eb6695..569b8f9d06 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -44,6 +44,12 @@ static String8 getUniqueName() { android_atomic_inc(&counter)); } +static uint64_t getUniqueId() { + static std::atomic counter{0}; + static uint64_t id = static_cast(getpid()) << 32; + return id | counter++; +} + BufferQueueCore::BufferQueueCore(const sp& allocator) : mAllocator(allocator), mMutex(), @@ -82,7 +88,8 @@ BufferQueueCore::BufferQueueCore(const sp& allocator) : mAutoRefresh(false), mSharedBufferSlot(INVALID_BUFFER_SLOT), mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE, - HAL_DATASPACE_UNKNOWN) + HAL_DATASPACE_UNKNOWN), + mUniqueId(getUniqueId()) { if (allocator == NULL) { sp composer(ComposerService::getComposerService()); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index be3b6c3389..234a86313e 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1422,4 +1422,11 @@ void BufferQueueProducer::binderDied(const wp& /* who */) { disconnect(api); } +status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const { + BQ_LOGV("getUniqueId"); + + *outId = mCore->mUniqueId; + return NO_ERROR; +} + } // namespace android diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 2c48d83d96..7d7d09d144 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -55,6 +55,7 @@ enum { SET_AUTO_REFRESH, SET_DEQUEUE_TIMEOUT, GET_LAST_QUEUED_BUFFER, + GET_UNIQUE_ID, }; class BpGraphicBufferProducer : public BpInterface @@ -418,6 +419,25 @@ public: *outFence = fence; return result; } + + virtual status_t getUniqueId(uint64_t* outId) const { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + status_t result = remote()->transact(GET_UNIQUE_ID, data, &reply); + if (result != NO_ERROR) { + ALOGE("getUniqueId failed to transact: %d", result); + } + status_t actualResult = NO_ERROR; + result = reply.readInt32(&actualResult); + if (result != NO_ERROR) { + return result; + } + result = reply.readUint64(outId); + if (result != NO_ERROR) { + return result; + } + return actualResult; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -659,6 +679,20 @@ status_t BnGraphicBufferProducer::onTransact( } return NO_ERROR; } + case GET_UNIQUE_ID: { + CHECK_INTERFACE(IGraphicBufferProducer, data, reply); + uint64_t outId = 0; + status_t actualResult = getUniqueId(&outId); + status_t result = reply->writeInt32(actualResult); + if (result != NO_ERROR) { + return result; + } + result = reply->writeUint64(outId); + if (result != NO_ERROR) { + return result; + } + return NO_ERROR; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9d130cd974..bcfe714bc9 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1279,6 +1279,11 @@ bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; } +status_t Surface::getUniqueId(uint64_t* outId) const { + Mutex::Autolock lock(mMutex); + return mGraphicBufferProducer->getUniqueId(outId); +} + namespace view { status_t Surface::writeToParcel(Parcel* parcel) const { diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index bc8dfbb5b6..c0baa49f85 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -612,6 +612,11 @@ status_t VirtualDisplaySurface::getLastQueuedBuffer( return INVALID_OPERATION; } +status_t VirtualDisplaySurface::getUniqueId(uint64_t* /*outId*/) const { + ALOGE("getUniqueId not supported on VirtualDisplaySurface"); + return INVALID_OPERATION; +} + void VirtualDisplaySurface::updateQueueBufferOutput( const QueueBufferOutput& qbo) { uint32_t w, h, transformHint, numPendingBuffers; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 29563b6a06..5b82355dcd 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -128,6 +128,7 @@ private: virtual status_t setDequeueTimeout(nsecs_t timeout) override; virtual status_t getLastQueuedBuffer(sp* outBuffer, sp* outFence, float outTransformMatrix[16]) override; + virtual status_t getUniqueId(uint64_t* outId) const override; // // Utility methods diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index faab62cb4e..fd33d5cd3e 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -149,6 +149,10 @@ status_t MonitoredProducer::getLastQueuedBuffer(sp* outBuffer, outTransformMatrix); } +status_t MonitoredProducer::getUniqueId(uint64_t* outId) const { + return mProducer->getUniqueId(outId); +} + IBinder* MonitoredProducer::onAsBinder() { return IInterface::asBinder(mProducer).get(); } diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index ce756dc822..71b6b5915d 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -64,6 +64,7 @@ public: virtual IBinder* onAsBinder(); virtual status_t setSharedBufferMode(bool sharedBufferMode) override; virtual status_t setAutoRefresh(bool autoRefresh) override; + virtual status_t getUniqueId(uint64_t* outId) const override; private: sp mProducer; -- cgit v1.2.3-59-g8ed1b From bc8c1928e1dbdaf6a2820f6e426c96ed61284043 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Fri, 1 Jul 2016 14:15:41 -0700 Subject: BQ: Remove getNextFrameNumber Binder call - Return the value in queueBuffer instead and cache it in Surface Change-Id: I10ab112afb03cf0231b047d4a4569cd641827043 --- include/gui/BufferQueueProducer.h | 3 --- include/gui/IGraphicBufferProducer.h | 12 +++++++----- include/gui/Surface.h | 2 ++ libs/gui/BufferQueueProducer.cpp | 14 ++++---------- libs/gui/IGraphicBufferProducer.cpp | 19 ------------------- libs/gui/Surface.cpp | 13 +++++++------ libs/gui/tests/IGraphicBufferProducer_test.cpp | 5 ++++- .../DisplayHardware/VirtualDisplaySurface.cpp | 16 ++++++++-------- .../DisplayHardware/VirtualDisplaySurface.h | 1 - services/surfaceflinger/MonitoredProducer.cpp | 4 ---- services/surfaceflinger/MonitoredProducer.h | 1 - 11 files changed, 32 insertions(+), 58 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h index 579ffb9db5..838632c26d 100644 --- a/include/gui/BufferQueueProducer.h +++ b/include/gui/BufferQueueProducer.h @@ -170,9 +170,6 @@ public: // See IGraphicBufferProducer::getConsumerName virtual String8 getConsumerName() const override; - // See IGraphicBufferProducer::getNextFrameNumber - virtual uint64_t getNextFrameNumber() const override; - // See IGraphicBufferProducer::setSharedBufferMode virtual status_t setSharedBufferMode(bool sharedBufferMode) override; diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index 47bb43a009..c62bc5899c 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -361,24 +361,29 @@ public: inline void deflate(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransformHint, - uint32_t* outNumPendingBuffers) const { + uint32_t* outNumPendingBuffers, + uint64_t* outNextFrameNumber) const { *outWidth = width; *outHeight = height; *outTransformHint = transformHint; *outNumPendingBuffers = numPendingBuffers; + *outNextFrameNumber = nextFrameNumber; } inline void inflate(uint32_t inWidth, uint32_t inHeight, - uint32_t inTransformHint, uint32_t inNumPendingBuffers) { + uint32_t inTransformHint, uint32_t inNumPendingBuffers, + uint64_t inNextFrameNumber) { width = inWidth; height = inHeight; transformHint = inTransformHint; numPendingBuffers = inNumPendingBuffers; + nextFrameNumber = inNextFrameNumber; } private: uint32_t width; uint32_t height; uint32_t transformHint; uint32_t numPendingBuffers; + uint64_t nextFrameNumber{0}; }; virtual status_t queueBuffer(int slot, const QueueBufferInput& input, @@ -523,9 +528,6 @@ public: // Returns the name of the connected consumer. virtual String8 getConsumerName() const = 0; - // Returns the number of the next frame which will be dequeued. - virtual uint64_t getNextFrameNumber() const = 0; - // Used to enable/disable shared buffer mode. // // When shared buffer mode is enabled the first buffer that is queued or diff --git a/include/gui/Surface.h b/include/gui/Surface.h index af9dd50099..37e2becc92 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -371,6 +371,8 @@ private: bool mSharedBufferHasBeenQueued; Condition mQueueBufferCondition; + + uint64_t mNextFrameNumber; }; namespace view { diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 49db4aa815..b7b56f03f2 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -900,7 +900,8 @@ status_t BufferQueueProducer::queueBuffer(int slot, output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, mCore->mTransformHint, - static_cast(mCore->mQueue.size())); + static_cast(mCore->mQueue.size()), + mCore->mFrameCounter + 1); ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size()); @@ -1107,7 +1108,8 @@ status_t BufferQueueProducer::connect(const sp& listener, mCore->mConnectedApi = api; output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, mCore->mTransformHint, - static_cast(mCore->mQueue.size())); + static_cast(mCore->mQueue.size()), + mCore->mFrameCounter + 1); // Set up a death notification so that we can disconnect // automatically if the remote producer dies @@ -1342,14 +1344,6 @@ String8 BufferQueueProducer::getConsumerName() const { return mConsumerName; } -uint64_t BufferQueueProducer::getNextFrameNumber() const { - ATRACE_CALL(); - - Mutex::Autolock lock(mCore->mMutex); - uint64_t nextFrameNumber = mCore->mFrameCounter + 1; - return nextFrameNumber; -} - status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) { ATRACE_CALL(); BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index c177922492..a6252af1a9 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -50,7 +50,6 @@ enum { GET_CONSUMER_NAME, SET_MAX_DEQUEUED_BUFFER_COUNT, SET_ASYNC_MODE, - GET_NEXT_FRAME_NUMBER, SET_SHARED_BUFFER_MODE, SET_AUTO_REFRESH, SET_DEQUEUE_TIMEOUT, @@ -334,18 +333,6 @@ public: return reply.readString8(); } - virtual uint64_t getNextFrameNumber() const { - Parcel data, reply; - data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); - status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply); - if (result != NO_ERROR) { - ALOGE("getNextFrameNumber failed to transact: %d", result); - return 0; - } - uint64_t frameNumber = reply.readUint64(); - return frameNumber; - } - virtual status_t setSharedBufferMode(bool sharedBufferMode) { Parcel data, reply; data.writeInterfaceToken( @@ -659,12 +646,6 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeString8(getConsumerName()); return NO_ERROR; } - case GET_NEXT_FRAME_NUMBER: { - CHECK_INTERFACE(IGraphicBufferProducer, data, reply); - uint64_t frameNumber = getNextFrameNumber(); - reply->writeUint64(frameNumber); - return NO_ERROR; - } case SET_SHARED_BUFFER_MODE: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); bool sharedBufferMode = data.readInt32(); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9760a0e87c..55a776963e 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -48,7 +48,8 @@ Surface::Surface( mSharedBufferMode(false), mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), - mSharedBufferHasBeenQueued(false) + mSharedBufferHasBeenQueued(false), + mNextFrameNumber(1) { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = hook_setSwapInterval; @@ -116,7 +117,8 @@ status_t Surface::setGenerationNumber(uint32_t generation) { } uint64_t Surface::getNextFrameNumber() const { - return mGraphicBufferProducer->getNextFrameNumber(); + Mutex::Autolock lock(mMutex); + return mNextFrameNumber; } String8 Surface::getConsumerName() const { @@ -504,7 +506,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { uint32_t numPendingBuffers = 0; uint32_t hint = 0; output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, - &numPendingBuffers); + &numPendingBuffers, &mNextFrameNumber); // Disable transform hint if sticky transform is set. if (mStickyTransform == 0) { @@ -802,7 +804,7 @@ int Surface::connect(int api, const sp& listener) { uint32_t numPendingBuffers = 0; uint32_t hint = 0; output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, - &numPendingBuffers); + &numPendingBuffers, &mNextFrameNumber); // Disable transform hint if sticky transform is set. if (mStickyTransform == 0) { @@ -1322,8 +1324,7 @@ status_t Surface::unlockAndPost() bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { Mutex::Autolock lock(mMutex); - uint64_t currentFrame = mGraphicBufferProducer->getNextFrameNumber(); - if (currentFrame > lastFrame) { + if (mNextFrameNumber > lastFrame) { return true; } return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 45b64639d2..9f3304731e 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -370,13 +370,16 @@ TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) { uint32_t height; uint32_t transformHint; uint32_t numPendingBuffers; + uint64_t nextFrameNumber; - output.deflate(&width, &height, &transformHint, &numPendingBuffers); + output.deflate(&width, &height, &transformHint, &numPendingBuffers, + &nextFrameNumber); EXPECT_EQ(DEFAULT_WIDTH, width); EXPECT_EQ(DEFAULT_HEIGHT, height); EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint); EXPECT_EQ(1u, numPendingBuffers); // since queueBuffer was called exactly once + EXPECT_EQ(2u, nextFrameNumber); } // Buffer was not in the dequeued state diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c0baa49f85..61bb0bd8d9 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -304,8 +304,11 @@ void VirtualDisplaySurface::dumpAsString(String8& /* result */) const { void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) { uint32_t tmpW, tmpH, transformHint, numPendingBuffers; - mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers); - mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers); + uint64_t nextFrameNumber; + mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers, + &nextFrameNumber); + mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers, + nextFrameNumber); mSinkBufferWidth = w; mSinkBufferHeight = h; @@ -586,10 +589,6 @@ String8 VirtualDisplaySurface::getConsumerName() const { return String8("VirtualDisplaySurface"); } -uint64_t VirtualDisplaySurface::getNextFrameNumber() const { - return 0; -} - status_t VirtualDisplaySurface::setSharedBufferMode(bool /*sharedBufferMode*/) { ALOGE("setSharedBufferMode not supported on VirtualDisplaySurface"); return INVALID_OPERATION; @@ -620,8 +619,9 @@ status_t VirtualDisplaySurface::getUniqueId(uint64_t* /*outId*/) const { void VirtualDisplaySurface::updateQueueBufferOutput( const QueueBufferOutput& qbo) { uint32_t w, h, transformHint, numPendingBuffers; - qbo.deflate(&w, &h, &transformHint, &numPendingBuffers); - mQueueBufferOutput.inflate(w, h, 0, numPendingBuffers); + uint64_t nextFrameNumber; + qbo.deflate(&w, &h, &transformHint, &numPendingBuffers, &nextFrameNumber); + mQueueBufferOutput.inflate(w, h, 0, numPendingBuffers, nextFrameNumber); } void VirtualDisplaySurface::resetPerFrameState() { diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 5b82355dcd..bf9b39c50d 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -122,7 +122,6 @@ private: virtual status_t allowAllocation(bool allow); virtual status_t setGenerationNumber(uint32_t generationNumber); virtual String8 getConsumerName() const override; - virtual uint64_t getNextFrameNumber() const override; virtual status_t setSharedBufferMode(bool sharedBufferMode) override; virtual status_t setAutoRefresh(bool autoRefresh) override; virtual status_t setDequeueTimeout(nsecs_t timeout) override; diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index fd33d5cd3e..36cfa3718a 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -127,10 +127,6 @@ String8 MonitoredProducer::getConsumerName() const { return mProducer->getConsumerName(); } -uint64_t MonitoredProducer::getNextFrameNumber() const { - return mProducer->getNextFrameNumber(); -} - status_t MonitoredProducer::setSharedBufferMode(bool sharedBufferMode) { return mProducer->setSharedBufferMode(sharedBufferMode); } diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index 71b6b5915d..f64fe51ef5 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -57,7 +57,6 @@ public: virtual status_t allowAllocation(bool allow); virtual status_t setGenerationNumber(uint32_t generationNumber); virtual String8 getConsumerName() const override; - virtual uint64_t getNextFrameNumber() const override; virtual status_t setDequeueTimeout(nsecs_t timeout) override; virtual status_t getLastQueuedBuffer(sp* outBuffer, sp* outFence, float outTransformMatrix[16]) override; -- cgit v1.2.3-59-g8ed1b From 70ccba596c586b7effde1ff99d36c911873b4ed4 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Fri, 1 Jul 2016 14:00:40 -0700 Subject: Surface: Add LAST_[DE]QUEUE_DURATION queries Adds support for the NATIVE_WINDOW_LAST_DEQUEUE_DURATION and NATIVE_WINDOW_LAST_QUEUE_DURATION queries. Bug: 29413700 Change-Id: Iea4efa208e8390fb2de52d5ad9f083ae91bf50b0 --- include/gui/Surface.h | 6 +++++- libs/gui/Surface.cpp | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'libs/gui/Surface.cpp') diff --git a/include/gui/Surface.h b/include/gui/Surface.h index af9dd50099..b9ffc49690 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -198,7 +198,6 @@ protected: virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); virtual int perform(int operation, va_list args); - virtual int query(int what, int* value) const; virtual int setSwapInterval(int interval); virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); @@ -224,6 +223,7 @@ public: virtual int setAutoRefresh(bool autoRefresh); virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); virtual int unlockAndPost(); + virtual int query(int what, int* value) const; virtual int connect(int api, const sp& listener); virtual int detachNextBuffer(sp* outBuffer, @@ -370,6 +370,10 @@ private: // used to prevent a mismatch between the number of queue/dequeue calls. bool mSharedBufferHasBeenQueued; + // These are used to satisfy the NATIVE_WINDOW_LAST_*_DURATION queries + nsecs_t mLastDequeueDuration = 0; + nsecs_t mLastQueueDuration = 0; + Condition mQueueBufferCondition; }; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9760a0e87c..af559133a9 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -292,8 +292,10 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { int buf = -1; sp fence; + nsecs_t now = systemTime(); status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight, reqFormat, reqUsage); + mLastDequeueDuration = systemTime() - now; if (result < 0) { ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer" @@ -496,7 +498,9 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { input.setSurfaceDamage(flippedRegion); } + nsecs_t now = systemTime(); status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); + mLastQueueDuration = systemTime() - now; if (err != OK) { ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); } @@ -575,6 +579,20 @@ int Surface::query(int what, int* value) const { } return err; } + case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: { + int64_t durationUs = mLastDequeueDuration / 1000; + *value = durationUs > std::numeric_limits::max() ? + std::numeric_limits::max() : + static_cast(durationUs); + return NO_ERROR; + } + case NATIVE_WINDOW_LAST_QUEUE_DURATION: { + int64_t durationUs = mLastQueueDuration / 1000; + *value = durationUs > std::numeric_limits::max() ? + std::numeric_limits::max() : + static_cast(durationUs); + return NO_ERROR; + } } } return mGraphicBufferProducer->query(what, value); -- cgit v1.2.3-59-g8ed1b From 529a103fde484a6512aaffd9ae063decb93765eb Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 29 Aug 2016 17:33:08 -0700 Subject: Surface: Add parcel/unparceling for missing field. Read/write new isSingleBuffered field in native code as well. Currently just write 'no' unconditionally and discard on read. Bug: 31162160 Change-Id: Icfb7a37fb37a41f6437fe08bcfad271474ba6983 --- libs/gui/Surface.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index dbf811462d..ab223ffd4b 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1364,12 +1364,18 @@ status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const { status_t res = OK; - if (!nameAlreadyWritten) res = parcel->writeString16(name); + if (!nameAlreadyWritten) { + res = parcel->writeString16(name); + if (res != OK) return res; - if (res == OK) { - res = parcel->writeStrongBinder( - IGraphicBufferProducer::asBinder(graphicBufferProducer)); + /* isSingleBuffered defaults to no */ + res = parcel->writeInt32(0); + if (res != OK) return res; } + + res = parcel->writeStrongBinder( + IGraphicBufferProducer::asBinder(graphicBufferProducer)); + return res; } @@ -1380,13 +1386,20 @@ status_t Surface::readFromParcel(const Parcel* parcel) { status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) { if (parcel == nullptr) return BAD_VALUE; + status_t res = OK; if (!nameAlreadyRead) { name = readMaybeEmptyString16(parcel); + // Discard this for now + int isSingleBuffered; + res = parcel->readInt32(&isSingleBuffered); + if (res != OK) { + return res; + } } sp binder; - status_t res = parcel->readStrongBinder(&binder); + res = parcel->readStrongBinder(&binder); if (res != OK) return res; graphicBufferProducer = interface_cast(binder); -- cgit v1.2.3-59-g8ed1b From 97b9c86338e2d364d47ea7522c2d81a8014f0e07 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 8 Sep 2016 13:54:35 -0700 Subject: Surface: Add force disconnection method. Add a new method forceScopedDisconnect to Surface. This will be used by the framework to force disconnection at times where the underlying GraphicBufferProducer may be about to be reused. This is scoped by PID to avoid conflicting with remote producers. Bug: 30236166 Change-Id: I857216483c0b550f240b3baea41977cbc58a67ed --- include/gui/BufferQueueCore.h | 2 ++ include/gui/BufferQueueProducer.h | 11 ++--------- include/gui/IGraphicBufferProducer.h | 15 +++++++++++---- include/gui/Surface.h | 5 ++++- libs/gui/BufferQueueProducer.cpp | 14 ++++++++++++-- libs/gui/IGraphicBufferProducer.cpp | 6 ++++-- libs/gui/Surface.cpp | 4 ++-- .../DisplayHardware/VirtualDisplaySurface.cpp | 4 ++-- .../DisplayHardware/VirtualDisplaySurface.h | 2 +- services/surfaceflinger/MonitoredProducer.cpp | 4 ++-- services/surfaceflinger/MonitoredProducer.h | 2 +- 11 files changed, 43 insertions(+), 26 deletions(-) (limited to 'libs/gui/Surface.cpp') diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h index 82bc121af3..cc5c536d13 100644 --- a/include/gui/BufferQueueCore.h +++ b/include/gui/BufferQueueCore.h @@ -182,6 +182,8 @@ private: // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated // by the connect and disconnect methods. int mConnectedApi; + // PID of the process which last successfully called connect(...) + pid_t mConnectedPid; // mConnectedProducerToken is used to set a binder death notification on // the producer. diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h index 838632c26d..8f613ee17d 100644 --- a/include/gui/BufferQueueProducer.h +++ b/include/gui/BufferQueueProducer.h @@ -135,15 +135,8 @@ public: virtual status_t connect(const sp& listener, int api, bool producerControlledByApp, QueueBufferOutput* output); - // disconnect attempts to disconnect a producer API from the BufferQueue. - // Calling this method will cause any subsequent calls to other - // IGraphicBufferProducer methods to fail except for getAllocator and connect. - // Successfully calling connect after this will allow the other methods to - // succeed again. - // - // This method will fail if the the BufferQueue is not currently - // connected to the specified producer API. - virtual status_t disconnect(int api); + // See IGraphicBufferProducer::disconnect + virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api); // Attaches a sideband buffer stream to the IGraphicBufferProducer. // diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index c62bc5899c..bf427fe4b9 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -458,17 +458,24 @@ public: virtual status_t connect(const sp& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; + enum class DisconnectMode { + // Disconnect only the specified API. + Api, + // Disconnect any API originally connected from the process calling disconnect. + AllLocal + }; + // disconnect attempts to disconnect a client API from the // IGraphicBufferProducer. Calling this method will cause any subsequent // calls to other IGraphicBufferProducer methods to fail except for // getAllocator and connect. Successfully calling connect after this will // allow the other methods to succeed again. // - // This method will fail if the the IGraphicBufferProducer is not currently - // connected to the specified client API. - // // The api should be one of the NATIVE_WINDOW_API_* values in // + // Alternatively if mode is AllLocal, then the API value is ignored, and any API + // connected from the same PID calling disconnect will be disconnected. + // // Disconnecting from an abandoned IGraphicBufferProducer is legal and // is considered a no-op. // @@ -477,7 +484,7 @@ public: // * the api specified does not match the one that was connected // * api was out of range (see above). // * DEAD_OBJECT - the token is hosted by an already-dead process - virtual status_t disconnect(int api) = 0; + virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) = 0; // Attaches a sideband buffer stream to the IGraphicBufferProducer. // diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 8177ec66af..f4a22cb733 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -203,7 +203,6 @@ protected: virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); virtual int connect(int api); - virtual int disconnect(int api); virtual int setBufferCount(int bufferCount); virtual int setBuffersDimensions(uint32_t width, uint32_t height); virtual int setBuffersUserDimensions(uint32_t width, uint32_t height); @@ -217,6 +216,10 @@ protected: virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects); public: + virtual int disconnect(int api, + IGraphicBufferProducer::DisconnectMode mode = + IGraphicBufferProducer::DisconnectMode::Api); + virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers); virtual int setAsyncMode(bool async); virtual int setSharedBufferMode(bool sharedBufferMode); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 47ab6f2fab..48b1db8f59 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -28,6 +28,7 @@ #define EGL_EGLEXT_PROTOTYPES +#include #include #include #include @@ -1130,7 +1131,7 @@ status_t BufferQueueProducer::connect(const sp& listener, status = BAD_VALUE; break; } - + mCore->mConnectedPid = IPCThreadState::self()->getCallingPid(); mCore->mBufferHasBeenQueued = false; mCore->mDequeueBufferCannotBlock = false; if (mDequeueTimeout < 0) { @@ -1143,7 +1144,7 @@ status_t BufferQueueProducer::connect(const sp& listener, return status; } -status_t BufferQueueProducer::disconnect(int api) { +status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { ATRACE_CALL(); BQ_LOGV("disconnect: api %d", api); @@ -1151,6 +1152,14 @@ status_t BufferQueueProducer::disconnect(int api) { sp listener; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); + + if (mode == DisconnectMode::AllLocal) { + if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) { + return NO_ERROR; + } + api = BufferQueueCore::CURRENTLY_CONNECTED_API; + } + mCore->waitWhileAllocatingLocked(); if (mCore->mIsAbandoned) { @@ -1189,6 +1198,7 @@ status_t BufferQueueProducer::disconnect(int api) { BufferQueueCore::INVALID_BUFFER_SLOT; mCore->mConnectedProducerListener = NULL; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; + mCore->mConnectedPid = -1; mCore->mSidebandStream.clear(); mCore->mDequeueCondition.broadcast(); listener = mCore->mConsumerListener; diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index fbd704d03d..f4ba3bf15f 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -270,10 +270,11 @@ public: return result; } - virtual status_t disconnect(int api) { + virtual status_t disconnect(int api, DisconnectMode mode) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInt32(api); + data.writeInt32(static_cast(mode)); status_t result =remote()->transact(DISCONNECT, data, &reply); if (result != NO_ERROR) { return result; @@ -621,7 +622,8 @@ status_t BnGraphicBufferProducer::onTransact( case DISCONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int api = data.readInt32(); - status_t res = disconnect(api); + DisconnectMode mode = static_cast(data.readInt32()); + status_t res = disconnect(api, mode); reply->writeInt32(res); return NO_ERROR; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index ab223ffd4b..08382908ba 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -844,14 +844,14 @@ int Surface::connect(int api, const sp& listener) { } -int Surface::disconnect(int api) { +int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { ATRACE_CALL(); ALOGV("Surface::disconnect"); Mutex::Autolock lock(mMutex); mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; mSharedBufferHasBeenQueued = false; freeAllBuffers(); - int err = mGraphicBufferProducer->disconnect(api); + int err = mGraphicBufferProducer->disconnect(api, mode); if (!err) { mReqFormat = 0; mReqWidth = 0; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 61bb0bd8d9..2190466ad9 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -563,8 +563,8 @@ status_t VirtualDisplaySurface::connect(const sp& listener, return result; } -status_t VirtualDisplaySurface::disconnect(int api) { - return mSource[SOURCE_SINK]->disconnect(api); +status_t VirtualDisplaySurface::disconnect(int api, DisconnectMode mode) { + return mSource[SOURCE_SINK]->disconnect(api, mode); } status_t VirtualDisplaySurface::setSidebandStream(const sp& /*stream*/) { diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index bf9b39c50d..70f717f8c2 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -115,7 +115,7 @@ private: virtual int query(int what, int* value); virtual status_t connect(const sp& listener, int api, bool producerControlledByApp, QueueBufferOutput* output); - virtual status_t disconnect(int api); + virtual status_t disconnect(int api, DisconnectMode mode); virtual status_t setSidebandStream(const sp& stream); virtual void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, uint32_t usage); diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp index 36cfa3718a..ffaee7a107 100644 --- a/services/surfaceflinger/MonitoredProducer.cpp +++ b/services/surfaceflinger/MonitoredProducer.cpp @@ -102,8 +102,8 @@ status_t MonitoredProducer::connect(const sp& listener, return mProducer->connect(listener, api, producerControlledByApp, output); } -status_t MonitoredProducer::disconnect(int api) { - return mProducer->disconnect(api); +status_t MonitoredProducer::disconnect(int api, DisconnectMode mode) { + return mProducer->disconnect(api, mode); } status_t MonitoredProducer::setSidebandStream(const sp& stream) { diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h index f64fe51ef5..66f6cf0bdb 100644 --- a/services/surfaceflinger/MonitoredProducer.h +++ b/services/surfaceflinger/MonitoredProducer.h @@ -50,7 +50,7 @@ public: virtual int query(int what, int* value); virtual status_t connect(const sp& token, int api, bool producerControlledByApp, QueueBufferOutput* output); - virtual status_t disconnect(int api); + virtual status_t disconnect(int api, DisconnectMode mode); virtual status_t setSidebandStream(const sp& stream); virtual void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, uint32_t usage); -- cgit v1.2.3-59-g8ed1b