SurfaceFlinger: Fix PTS on stale buffers

SurfaceFlinger's (Layer's) shadow copy of the BufferQueue queue was
getting out of sync for a few reasons. This change fixes these by
doing the following:

- Adds a check to re-synchronize the shadow copy every time we
  successfully acquire a buffer by first dropping stale buffers before
  removing the current buffer.
- Avoids trying to perform updates for buffers which have been rejected
  (for incorrect dimensions) by SurfaceFlinger.
- Adds IGraphicBufferConsumer::setShadowQueueSize, which allows the
  consumer to notify the BufferQueue that it is maintaining a shadow
  copy of the queue and prevents it from dropping so many buffers
  during acquireBuffer that it ends up returning a buffer for which the
  consumer has not yet received an onFrameAvailable call.

Bug: 20096136
Change-Id: I78d0738428005fc19b3be85cc8f1db498043612f
(cherry picked from commit 2e36f2283f48ab764b496490c73a132acf21df3a)
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2944c63..9fb94dd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -127,6 +127,10 @@
     mSurfaceFlingerConsumer->setContentsChangedListener(this);
     mSurfaceFlingerConsumer->setName(mName);
 
+    // Set the shadow queue size to 0 to notify the BufferQueue that we are
+    // shadowing it
+    mSurfaceFlingerConsumer->setShadowQueueSize(0);
+
 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
 #warning "disabling triple buffering"
     mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
@@ -164,9 +168,10 @@
     { // Autolock scope
         Mutex::Autolock lock(mQueueItemLock);
         mQueueItems.push_back(item);
+        mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+        android_atomic_inc(&mQueuedFrames);
     }
 
-    android_atomic_inc(&mQueuedFrames);
     mFlinger->signalLayerUpdate();
 }
 
@@ -1259,14 +1264,39 @@
             // layer update so we check again at the next opportunity.
             mFlinger->signalLayerUpdate();
             return outDirtyRegion;
+        } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
+            // If the buffer has been rejected, remove it from the shadow queue
+            // and return early
+            Mutex::Autolock lock(mQueueItemLock);
+
+            // Update the BufferQueue with the new shadow queue size after
+            // dropping this item
+            mQueueItems.removeAt(0);
+            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+
+            android_atomic_dec(&mQueuedFrames);
+            return outDirtyRegion;
         }
 
-        // Remove this buffer from our internal queue tracker
         { // Autolock scope
+            auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
+
             Mutex::Autolock lock(mQueueItemLock);
+
+            // Remove any stale buffers that have been dropped during
+            // updateTexImage
+            while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
+                mQueueItems.removeAt(0);
+                android_atomic_dec(&mQueuedFrames);
+            }
+
+            // Update the BufferQueue with our new shadow queue size, since we
+            // have removed at least one item
             mQueueItems.removeAt(0);
+            mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
         }
 
+
         // Decrement the queued-frames count.  Signal another event if we
         // have more frames pending.
         if (android_atomic_dec(&mQueuedFrames) > 1) {