From 9f31e299b3ec93b7bac969846105e7e926e3efcd Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 11 Apr 2016 11:15:32 -0700 Subject: [PATCH] Add Surface::waitForNextFrame We can use this for cases like SurfaceView where one thread (e.g. the framework code) wants to wait for an unknown client thread to render a frame in to the surface before we report it as shown to the window manager. Bug: 22207948 Change-Id: I9d3344aa1c0ab0f0efd9df24e90ce0410d5f2e22 --- include/gui/Surface.h | 9 +++++++++ libs/gui/Surface.cpp | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 5d1d7bff86..f76a9beefe 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -122,6 +122,13 @@ public: // See IGraphicBufferProducer::setDequeueTimeout status_t setDequeueTimeout(nsecs_t timeout); + /* + * Wait for frame number to increase past lastFrame for at most + * timeoutNs. Useful for one thread to wait for another unknown + * thread to queue a buffer. + */ + bool waitForNextFrame(uint64_t lastFrame, nsecs_t timeout); + protected: virtual ~Surface(); @@ -348,6 +355,8 @@ private: // This is true if the shared buffer has already been queued/canceled. It's // used to prevent a mismatch between the number of queue/dequeue calls. bool mSharedBufferHasBeenQueued; + + Condition mQueueBufferCondition; }; namespace view { diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 76b62f1c40..5efc3331bb 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -480,6 +480,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mSharedBufferHasBeenQueued = true; } + mQueueBufferCondition.broadcast(); + return err; } @@ -1259,6 +1261,15 @@ status_t Surface::unlockAndPost() return err; } +bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { + Mutex::Autolock lock(mMutex); + uint64_t currentFrame = mGraphicBufferProducer->getNextFrameNumber(); + if (currentFrame > lastFrame) { + return true; + } + return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; +} + namespace view { status_t Surface::writeToParcel(Parcel* parcel) const { -- 2.11.0