Enable backpressure for BufferStateLayer

The default behaviour of buffer state layer is to drop older
buffers if there are newer buffers that are ready to be presented.

When emulating BufferQueue behavior via the adapter, we want
to queue up buffers without any present timestamps. To solve this,
we introduce a layer state flag to keep the buffer in the transaction
queue if there is already a buffer that is ready to be applied.

Test: atest SurfaceViewBufferTests:BufferPresentationTests
Bug: 176967609
Change-Id: I33f6347bd1c7a2d80dc4214e596bb864abe8c6bf
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 0a3d44d..4904955 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -146,6 +146,10 @@
 
     mTransformHint = mSurfaceControl->getTransformHint();
     mBufferItemConsumer->setTransformHint(mTransformHint);
+    SurfaceComposerClient::Transaction()
+            .setFlags(surface, layer_state_t::eEnableBackpressure,
+                      layer_state_t::eEnableBackpressure)
+            .apply();
 
     mNumAcquired = 0;
     mNumFrameAvailable = 0;
@@ -169,13 +173,20 @@
 void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
                               int32_t format) {
     std::unique_lock _lock{mMutex};
-    mSurfaceControl = surface;
-
     if (mFormat != format) {
         mFormat = format;
         mBufferItemConsumer->setDefaultBufferFormat(format);
     }
 
+    SurfaceComposerClient::Transaction t;
+    bool applyTransaction = false;
+    if (!SurfaceControl::isSameSurface(mSurfaceControl, surface)) {
+        mSurfaceControl = surface;
+        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
+                   layer_state_t::eEnableBackpressure);
+        applyTransaction = true;
+    }
+
     ui::Size newSize(width, height);
     if (mRequestedSize != newSize) {
         mRequestedSize.set(newSize);
@@ -184,13 +195,15 @@
             // If the buffer supports scaling, update the frame immediately since the client may
             // want to scale the existing buffer to the new size.
             mSize = mRequestedSize;
-            SurfaceComposerClient::Transaction t;
             t.setFrame(mSurfaceControl,
                        {0, 0, static_cast<int32_t>(mSize.width),
                         static_cast<int32_t>(mSize.height)});
-            t.apply();
+            applyTransaction = true;
         }
     }
+    if (applyTransaction) {
+        t.apply();
+    }
 }
 
 static void transactionCallbackThunk(void* context, nsecs_t latchTime,