diff options
author | 2016-09-30 14:01:24 -0700 | |
---|---|---|
committer | 2017-01-12 10:40:55 -0800 | |
commit | 50143b3780ad2aaa544c8d2d47619214b79c3c56 (patch) | |
tree | a12029b8f201a15bbc82f76b3a6f8802d8ee703e /libs/gui/Surface.cpp | |
parent | ba4d92cc90b5d2a902e898211f04311a0ae2493b (diff) |
Avoid sync calls for unsupported/non-existant times
* Make sure not to do sync calls for present or retire
if they aren't supported.
* Don't do sync calls for retire or release if they
can not possibly exist.
Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*
Change-Id: I580409f01cbf07e9a6e00fbb05d914654f12a4a2
Diffstat (limited to 'libs/gui/Surface.cpp')
-rw-r--r-- | libs/gui/Surface.cpp | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 1e79e06d8b..a172c32522 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -49,7 +49,6 @@ Surface::Surface( mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false), - mNextFrameNumber(1), mQueriedSupportedTimestamps(false), mFrameTimestampsSupportsPresent(false), mFrameTimestampsSupportsRetire(false), @@ -144,6 +143,31 @@ void Surface::enableFrameTimestamps(bool enable) { mEnableFrameTimestamps = enable; } +static bool checkConsumerForUpdates( + const FrameEvents* e, const uint64_t lastFrameNumber, + const nsecs_t* outRefreshStartTime, + const nsecs_t* outGlCompositionDoneTime, + const nsecs_t* outDisplayPresentTime, + const nsecs_t* outDisplayRetireTime, + const nsecs_t* outReleaseTime) { + bool checkForRefreshStart = (outRefreshStartTime != nullptr) && + !e->hasFirstRefreshStartInfo(); + bool checkForGlCompositionDone = (outGlCompositionDoneTime != nullptr) && + !e->hasGpuCompositionDoneInfo(); + bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && + !e->hasDisplayPresentInfo(); + + // DisplayRetire and Release are never available for the last frame. + bool checkForDisplayRetire = (outDisplayRetireTime != nullptr) && + !e->hasDisplayRetireInfo() && (e->frameNumber != lastFrameNumber); + bool checkForRelease = (outReleaseTime != nullptr) && + !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber); + + // RequestedPresent and Acquire info are always available producer-side. + return checkForRefreshStart || checkForGlCompositionDone || + checkForDisplayPresent || checkForDisplayRetire || checkForRelease; +} + static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { if (dst != nullptr) { *dst = Fence::isValidTimestamp(src) ? src : 0; @@ -180,24 +204,25 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, } FrameEvents* events = mFrameEventHistory.getFrame(frameNumber); + if (events == nullptr) { + // If the entry isn't available in the producer, it's definitely not + // available in the consumer. + return NAME_NOT_FOUND; + } // Update our cache of events if the requested events are not available. - if (events == nullptr || - (outRequestedPresentTime && !events->hasRequestedPresentInfo()) || - (outAcquireTime && !events->hasAcquireInfo()) || - (outRefreshStartTime && !events->hasFirstRefreshStartInfo()) || - (outGlCompositionDoneTime && !events->hasGpuCompositionDoneInfo()) || - (outDisplayPresentTime && !events->hasDisplayPresentInfo()) || - (outDisplayRetireTime && !events->hasDisplayRetireInfo()) || - (outReleaseTime && !events->hasReleaseInfo())) { - FrameEventHistoryDelta delta; - mGraphicBufferProducer->getFrameTimestamps(&delta); - mFrameEventHistory.applyDelta(delta); - events = mFrameEventHistory.getFrame(frameNumber); - } - - // A record for the requested frame does not exist. + if (checkConsumerForUpdates(events, mLastFrameNumber, + outRefreshStartTime, outGlCompositionDoneTime, + outDisplayPresentTime, outDisplayRetireTime, outReleaseTime)) { + FrameEventHistoryDelta delta; + mGraphicBufferProducer->getFrameTimestamps(&delta); + mFrameEventHistory.applyDelta(delta); + events = mFrameEventHistory.getFrame(frameNumber); + } + if (events == nullptr) { + // The entry was available before the update, but was overwritten + // after the update. Make sure not to send the wrong frame's data. return NAME_NOT_FOUND; } @@ -347,11 +372,9 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { nsecs_t now = systemTime(); FrameEventHistoryDelta frameTimestamps; - FrameEventHistoryDelta* frameTimestampsOrNull = - enableFrameTimestamps ? &frameTimestamps : nullptr; - status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, - reqWidth, reqHeight, reqFormat, reqUsage, frameTimestampsOrNull); + reqWidth, reqHeight, reqFormat, reqUsage, + enableFrameTimestamps ? &frameTimestamps : nullptr); mLastDequeueDuration = systemTime() - now; if (result < 0) { @@ -579,6 +602,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mFrameEventHistory.updateSignalTimes(); } + mLastFrameNumber = mNextFrameNumber; + mDefaultWidth = output.width; mDefaultHeight = output.height; mNextFrameNumber = output.nextFrameNumber; |