Merge cherrypicks of [2420306, 2420248, 2420158, 2420321, 2420159, 2420160, 2420266, 2420284, 2420308, 2420342, 2420177, 2420195, 2420344, 2420345, 2420179, 2420324, 2420251, 2420269, 2420271, 2420325, 2420310, 2420220, 2420348, 2420291, 2420328, 2420330, 2420383, 2420331, 2420255, 2420296, 2420278, 2420229, 2420335] into nyc-mr1-volantis-release

Change-Id: Id96a57cd611bbf4b646783c10c130830f82212a9
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 05923b5..ce47784 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -921,7 +921,11 @@
 
     // Call back without the main BufferQueue lock held, but with the callback
     // lock held so we can ensure that callbacks occur in order
-    {
+
+    int connectedApi;
+    sp<Fence> lastQueuedFence;
+
+    { // scope for the lock
         Mutex::Autolock lock(mCallbackMutex);
         while (callbackTicket != mCurrentCallbackTicket) {
             mCallbackCondition.wait(mCallbackMutex);
@@ -933,20 +937,24 @@
             frameReplacedListener->onFrameReplaced(item);
         }
 
+        connectedApi = mCore->mConnectedApi;
+        lastQueuedFence = std::move(mLastQueueBufferFence);
+
+        mLastQueueBufferFence = std::move(fence);
+        mLastQueuedCrop = item.mCrop;
+        mLastQueuedTransform = item.mTransform;
+
         ++mCurrentCallbackTicket;
         mCallbackCondition.broadcast();
     }
 
     // Wait without lock held
-    if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+    if (connectedApi == NATIVE_WINDOW_API_EGL) {
         // Waiting here allows for two full buffers to be queued but not a
         // third. In the event that frames take varying time, this makes a
         // small trade-off in favor of latency rather than throughput.
-        mLastQueueBufferFence->waitForever("Throttling EGL Production");
+        lastQueuedFence->waitForever("Throttling EGL Production");
     }
-    mLastQueueBufferFence = fence;
-    mLastQueuedCrop = item.mCrop;
-    mLastQueuedTransform = item.mTransform;
 
     return NO_ERROR;
 }