Have the Surface class track the buffer age.
Have the Surface class track the buffer age, so that Surface::query()
can return the buffer age without having to use a binder call to
BufferQueueProducer::query(). The idea is for
BufferQueueProducer::dequeueBuffer() to return the value, which the
Surface class will cache for later use by Surface::query().
Bug: b/27903668
Test: Use systrace to no ensure query binder call after dequeueBuffer.
Change-Id: I106a7bd27461d381f0bd84df70d804de56a128ab
(cherry picked from commit d11b044864be525a1646f93106ab496195bb8239)
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 409a3cb..78eb69d 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -44,21 +44,19 @@
namespace android {
-Surface::Surface(
- const sp<IGraphicBufferProducer>& bufferProducer,
- bool controlledByApp)
- : mGraphicBufferProducer(bufferProducer),
- mCrop(Rect::EMPTY_RECT),
- mGenerationNumber(0),
- mSharedBufferMode(false),
- mAutoRefresh(false),
- mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
- mSharedBufferHasBeenQueued(false),
- mQueriedSupportedTimestamps(false),
- mFrameTimestampsSupportsPresent(false),
- mEnableFrameTimestamps(false),
- mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>())
-{
+Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp)
+ : mGraphicBufferProducer(bufferProducer),
+ mCrop(Rect::EMPTY_RECT),
+ mBufferAge(0),
+ mGenerationNumber(0),
+ mSharedBufferMode(false),
+ mAutoRefresh(false),
+ mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
+ mSharedBufferHasBeenQueued(false),
+ mQueriedSupportedTimestamps(false),
+ mFrameTimestampsSupportsPresent(false),
+ mEnableFrameTimestamps(false),
+ mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
@@ -506,9 +504,10 @@
nsecs_t startTime = systemTime();
FrameEventHistoryDelta frameTimestamps;
- status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
- reqWidth, reqHeight, reqFormat, reqUsage,
- enableFrameTimestamps ? &frameTimestamps : nullptr);
+ status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
+ reqFormat, reqUsage, &mBufferAge,
+ enableFrameTimestamps ? &frameTimestamps
+ : nullptr);
mLastDequeueDuration = systemTime() - startTime;
if (result < 0) {
@@ -845,6 +844,14 @@
}
return err;
}
+ case NATIVE_WINDOW_BUFFER_AGE: {
+ if (mBufferAge > INT32_MAX) {
+ *value = 0;
+ } else {
+ *value = static_cast<int32_t>(mBufferAge);
+ }
+ return NO_ERROR;
+ }
case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
int64_t durationUs = mLastDequeueDuration / 1000;
*value = durationUs > std::numeric_limits<int>::max() ?