diff options
author | 2016-12-06 15:07:48 -0800 | |
---|---|---|
committer | 2016-12-06 15:07:48 -0800 | |
commit | ecea1bfeae1211f9a363925c172c0f23062107fb (patch) | |
tree | 99d7fc7c78f261a3ffde997e8354f8134c60bfbe /libs/gui/Surface.cpp | |
parent | f5c3b20f062ca646572ee6c07713eba691971c95 (diff) | |
parent | 6079aa6a8a845d8312435fe3e991bbe14588d018 (diff) |
Merge remote-tracking branch 'goog/stage-aosp-master' into HEAD
Diffstat (limited to 'libs/gui/Surface.cpp')
-rw-r--r-- | libs/gui/Surface.cpp | 113 |
1 files changed, 100 insertions, 13 deletions
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 1879f8a099..8e6ab1c73b 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 { @@ -133,6 +135,39 @@ status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* 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); @@ -259,8 +294,10 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { int buf = -1; sp<Fence> 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" @@ -463,7 +500,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); } @@ -471,7 +510,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) { @@ -542,6 +581,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<int>::max() ? + std::numeric_limits<int>::max() : + static_cast<int>(durationUs); + return NO_ERROR; + } + case NATIVE_WINDOW_LAST_QUEUE_DURATION: { + int64_t durationUs = mLastQueueDuration / 1000; + *value = durationUs > std::numeric_limits<int>::max() ? + std::numeric_limits<int>::max() : + static_cast<int>(durationUs); + return NO_ERROR; + } } } return mGraphicBufferProducer->query(what, value); @@ -617,6 +670,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; @@ -737,6 +793,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<IProducerListener> listener = new DummyProducerListener(); return connect(api, listener); @@ -752,7 +822,7 @@ int Surface::connect(int api, const sp<IProducerListener>& 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) { @@ -774,14 +844,14 @@ int Surface::connect(int api, const sp<IProducerListener>& 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; @@ -1272,13 +1342,17 @@ 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; } +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 { @@ -1290,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; } @@ -1306,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<IBinder> binder; - status_t res = parcel->readStrongBinder(&binder); + res = parcel->readStrongBinder(&binder); if (res != OK) return res; graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder); |