OSDN Git Service

Re-enable frame dropping for non-auto timestamps
authorAndy McFadden <fadden@android.com>
Fri, 16 Aug 2013 21:55:39 +0000 (14:55 -0700)
committerAndy McFadden <fadden@android.com>
Fri, 16 Aug 2013 22:15:16 +0000 (15:15 -0700)
This change adds an entire field to note whether the timestamp was
auto-generated by Surface or supplied by the application.

The value is used when deciding whether or not to drop frames based
on buffer presentation timestamps.  If a desired presentation time
was set explicitly, BufferQueue will use that value to decide if a
frame should be dropped.  If the timestamp was generated by Surface
at the time the buffer was queued, the timestamp is ignored.

Bug 10151804

Change-Id: Ibd571a7578351063b813cbdad2ddbeed70655ba5

include/gui/IGraphicBufferConsumer.h
include/gui/IGraphicBufferProducer.h
libs/gui/BufferQueue.cpp
libs/gui/IGraphicBufferConsumer.cpp
libs/gui/IGraphicBufferProducer.cpp
libs/gui/Surface.cpp
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp

index 2ad302f..3327b37 100644 (file)
@@ -72,6 +72,10 @@ public:
         // to set by queueBuffer each time this slot is queued.
         int64_t mTimestamp;
 
+        // mIsAutoTimestamp indicates whether mTimestamp was generated
+        // automatically when the buffer was queued.
+        bool mIsAutoTimestamp;
+
         // mFrameNumber is the number of the queued frame for this slot.
         uint64_t mFrameNumber;
 
index 033c727..c3ede5e 100644 (file)
@@ -108,15 +108,17 @@ public:
     struct QueueBufferInput : public Flattenable<QueueBufferInput> {
         friend class Flattenable<QueueBufferInput>;
         inline QueueBufferInput(const Parcel& parcel);
-        inline QueueBufferInput(int64_t timestamp,
+        inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,
                 const Rect& crop, int scalingMode, uint32_t transform, bool async,
                 const sp<Fence>& fence)
-        : timestamp(timestamp), crop(crop), scalingMode(scalingMode),
-          transform(transform), async(async), fence(fence) { }
-        inline void deflate(int64_t* outTimestamp, Rect* outCrop,
-                int* outScalingMode, uint32_t* outTransform, bool* outAsync,
-                sp<Fence>* outFence) const {
+        : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop),
+          scalingMode(scalingMode), transform(transform), async(async),
+          fence(fence) { }
+        inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,
+                Rect* outCrop, int* outScalingMode, uint32_t* outTransform,
+                bool* outAsync, sp<Fence>* outFence) const {
             *outTimestamp = timestamp;
+            *outIsAutoTimestamp = bool(isAutoTimestamp);
             *outCrop = crop;
             *outScalingMode = scalingMode;
             *outTransform = transform;
@@ -132,6 +134,7 @@ public:
 
     private:
         int64_t timestamp;
+        int isAutoTimestamp;
         Rect crop;
         int scalingMode;
         uint32_t transform;
index 033c2a6..65007fa 100644 (file)
@@ -475,10 +475,12 @@ status_t BufferQueue::queueBuffer(int buf,
     uint32_t transform;
     int scalingMode;
     int64_t timestamp;
+    bool isAutoTimestamp;
     bool async;
     sp<Fence> fence;
 
-    input.deflate(&timestamp, &crop, &scalingMode, &transform, &async, &fence);
+    input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
+            &async, &fence);
 
     if (fence == NULL) {
         ST_LOGE("queueBuffer: fence is NULL");
@@ -558,6 +560,7 @@ status_t BufferQueue::queueBuffer(int buf,
         item.mTransform = transform;
         item.mScalingMode = scalingMode;
         item.mTimestamp = timestamp;
+        item.mIsAutoTimestamp = isAutoTimestamp;
         item.mFrameNumber = mFrameCounter;
         item.mBuf = buf;
         item.mFence = fence;
@@ -860,7 +863,12 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent)
         //
         // NOTE: code assumes monotonic time values from the system clock are
         // positive.
-        while (false && mQueue.size() > 1) {
+
+        // Start by checking to see if we can drop frames.  We skip this check
+        // if the timestamps are being auto-generated by Surface -- if the
+        // app isn't generating timestamps explicitly, they probably don't
+        // want frames to be discarded based on them.
+        while (mQueue.size() > 1 && !mQueue[0].mIsAutoTimestamp) {
             // If entry[1] is timely, drop entry[0] (and repeat).  We apply
             // an additional criteria here: we only drop the earlier buffer if
             // our desiredPresent falls within +/- 1 second of the expected
index 6d65016..4db635c 100644 (file)
@@ -43,6 +43,7 @@ IGraphicBufferConsumer::BufferItem::BufferItem() :
     mTransform(0),
     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     mTimestamp(0),
+    mIsAutoTimestamp(false),
     mFrameNumber(0),
     mBuf(INVALID_BUFFER_SLOT),
     mIsDroppable(false),
@@ -55,6 +56,7 @@ size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
             sizeof(mTransform) +
             sizeof(mScalingMode) +
             sizeof(mTimestamp) +
+            sizeof(mIsAutoTimestamp) +
             sizeof(mFrameNumber) +
             sizeof(mBuf) +
             sizeof(mIsDroppable) +
@@ -123,6 +125,7 @@ status_t IGraphicBufferConsumer::BufferItem::flatten(
     FlattenableUtils::write(buffer, size, mTransform);
     FlattenableUtils::write(buffer, size, mScalingMode);
     FlattenableUtils::write(buffer, size, mTimestamp);
+    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
     FlattenableUtils::write(buffer, size, mFrameNumber);
     FlattenableUtils::write(buffer, size, mBuf);
     FlattenableUtils::write(buffer, size, mIsDroppable);
@@ -163,6 +166,7 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten(
     FlattenableUtils::read(buffer, size, mTransform);
     FlattenableUtils::read(buffer, size, mScalingMode);
     FlattenableUtils::read(buffer, size, mTimestamp);
+    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
     FlattenableUtils::read(buffer, size, mFrameNumber);
     FlattenableUtils::read(buffer, size, mBuf);
     FlattenableUtils::read(buffer, size, mIsDroppable);
index e3d2a20..3080220 100644 (file)
@@ -269,6 +269,7 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel)
 
 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
     return sizeof(timestamp)
+         + sizeof(isAutoTimestamp)
          + sizeof(crop)
          + sizeof(scalingMode)
          + sizeof(transform)
@@ -287,6 +288,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
         return NO_MEMORY;
     }
     FlattenableUtils::write(buffer, size, timestamp);
+    FlattenableUtils::write(buffer, size, isAutoTimestamp);
     FlattenableUtils::write(buffer, size, crop);
     FlattenableUtils::write(buffer, size, scalingMode);
     FlattenableUtils::write(buffer, size, transform);
@@ -299,6 +301,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
 {
     size_t minNeeded =
               sizeof(timestamp)
+            + sizeof(isAutoTimestamp)
             + sizeof(crop)
             + sizeof(scalingMode)
             + sizeof(transform)
@@ -309,6 +312,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
     }
 
     FlattenableUtils::read(buffer, size, timestamp);
+    FlattenableUtils::read(buffer, size, isAutoTimestamp);
     FlattenableUtils::read(buffer, size, crop);
     FlattenableUtils::read(buffer, size, scalingMode);
     FlattenableUtils::read(buffer, size, transform);
index f3a7e5e..b9a12ed 100644 (file)
@@ -262,8 +262,10 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
     ALOGV("Surface::queueBuffer");
     Mutex::Autolock lock(mMutex);
     int64_t timestamp;
+    bool isAutoTimestamp = false;
     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+        isAutoTimestamp = true;
         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
             timestamp / 1000000.f);
     } else {
@@ -281,8 +283,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
 
     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
     IGraphicBufferProducer::QueueBufferOutput output;
-    IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
-            mTransform, mSwapIntervalZero, fence);
+    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
+            crop, mScalingMode, mTransform, mSwapIntervalZero, fence);
     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
     if (err != OK)  {
         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
index 30b0084..89c87c7 100644 (file)
@@ -185,7 +185,7 @@ void VirtualDisplaySurface::onFrameCommitted() {
         sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
         VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
         status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
-                QueueBufferInput(systemTime(),
+                QueueBufferInput(systemTime(), false,
                     Rect(mSinkBufferWidth, mSinkBufferHeight),
                     NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, outFence),
                 &qbo);
@@ -309,12 +309,13 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot,
 
         // Extract the GLES release fence for HWC to acquire
         int64_t timestamp;
+        bool isAutoTimestamp;
         Rect crop;
         int scalingMode;
         uint32_t transform;
         bool async;
-        input.deflate(&timestamp, &crop, &scalingMode, &transform,
-                &async, &mFbFence);
+        input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode,
+                &transform, &async, &mFbFence);
 
         mFbProducerSlot = pslot;
     }