BufferQueue: Add NATIVE_WINDOW_BUFFER_AGE query

Adds a NATIVE_WINDOW_BUFFER_AGE query, which returns the age of the
contents of the most recently dequeued buffer as the number of frames
that have elapsed since it was last queued.

Change-Id: Ib6fd62945cb62d1e60133a65beee510363218a23
(cherry picked from commit 49f810c72df8d1d64128e376757079825c8decd4)
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 86e45c8..b8df436 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -337,10 +337,18 @@
             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
             mSlots[found].mFence = Fence::NO_FENCE;
+            mCore->mBufferAge = 0;
 
             returnFlags |= BUFFER_NEEDS_REALLOCATION;
+        } else {
+            // We add 1 because that will be the frame number when this buffer
+            // is queued
+            mCore->mBufferAge =
+                    mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
         }
 
+        BQ_LOGV("dequeueBuffer: setting buffer age to %llu", mCore->mBufferAge);
+
         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
                     "slot=%d w=%d h=%d format=%u",
@@ -784,6 +792,13 @@
         case NATIVE_WINDOW_DEFAULT_DATASPACE:
             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
             break;
+        case NATIVE_WINDOW_BUFFER_AGE:
+            if (mCore->mBufferAge > INT32_MAX) {
+                value = 0;
+            } else {
+                value = static_cast<int32_t>(mCore->mBufferAge);
+            }
+            break;
         default:
             return BAD_VALUE;
     }