Revert "Partial revert of "Fix Surface slot caching""

This reverts commit 981066c3a5be3e4775b6537ef32268f7e108c912.
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 92285e5..b025280 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -274,35 +274,51 @@
     ATRACE_CALL();
     ATRACE_BUFFER_INDEX(slot);
     BQ_LOGV("detachBuffer: slot %d", slot);
-    Mutex::Autolock lock(mCore->mMutex);
 
-    if (mCore->mIsAbandoned) {
-        BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
-        return NO_INIT;
+    sp<IConsumerListener> consumerListener;
+    sp<IProducerListener> producerListener;
+    {
+        Mutex::Autolock lock(mCore->mMutex);
+
+        if (mCore->mIsAbandoned) {
+            BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
+            return NO_INIT;
+        }
+
+        if (mCore->mSingleBufferMode || slot == mCore->mSingleBufferSlot) {
+            BQ_LOGE("detachBuffer: detachBuffer not allowed in single buffer"
+                    "mode");
+            return BAD_VALUE;
+        }
+
+        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
+            BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
+                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
+            return BAD_VALUE;
+        } else if (!mSlots[slot].mBufferState.isAcquired()) {
+            BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
+                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
+            return BAD_VALUE;
+        }
+
+        mSlots[slot].mBufferState.detachConsumer();
+        mCore->mActiveBuffers.erase(slot);
+        mCore->mFreeSlots.insert(slot);
+        mCore->clearBufferSlotLocked(slot);
+        mCore->mDequeueCondition.broadcast();
+        VALIDATE_CONSISTENCY();
+        producerListener = mCore->mConnectedProducerListener;
+        consumerListener = mCore->mConsumerListener;
     }
 
-    if (mCore->mSingleBufferMode || slot == mCore->mSingleBufferSlot) {
-        BQ_LOGE("detachBuffer: detachBuffer not allowed in single buffer"
-                "mode");
-        return BAD_VALUE;
+    // Call back without lock held
+    if (producerListener != NULL) {
+        producerListener->onSlotFreed(slot);
+    }
+    if (consumerListener != NULL) {
+        consumerListener->onBuffersReleased();
     }
 
-    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
-        BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
-                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
-        return BAD_VALUE;
-    } else if (!mSlots[slot].mBufferState.isAcquired()) {
-        BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
-                "(state = %s)", slot, mSlots[slot].mBufferState.string());
-        return BAD_VALUE;
-    }
-
-    mSlots[slot].mBufferState.detachConsumer();
-    mCore->mActiveBuffers.erase(slot);
-    mCore->mFreeSlots.insert(slot);
-    mCore->clearBufferSlotLocked(slot);
-    mCore->mDequeueCondition.broadcast();
-    VALIDATE_CONSISTENCY();
 
     return NO_ERROR;
 }
@@ -573,30 +589,40 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mCore->mMutex);
+    sp<IConsumerListener> listener;
+    {
+        Mutex::Autolock lock(mCore->mMutex);
+        if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+            BQ_LOGE("setMaxBufferCount: producer is already connected");
+            return INVALID_OPERATION;
+        }
 
-    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
-        BQ_LOGE("setMaxBufferCount: producer is already connected");
-        return INVALID_OPERATION;
+        if (bufferCount < mCore->mMaxAcquiredBufferCount) {
+            BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
+                    "mMaxAcquiredBufferCount (%d)", bufferCount,
+                    mCore->mMaxAcquiredBufferCount);
+            return BAD_VALUE;
+        }
+
+        int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
+                mCore->mDequeueBufferCannotBlock, bufferCount) -
+                mCore->getMaxBufferCountLocked();
+        if (!mCore->adjustAvailableSlotsLocked(delta, nullptr)) {
+            BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number"
+                    " of available slots. Delta = %d", delta);
+            return BAD_VALUE;
+        }
+
+        mCore->mMaxBufferCount = bufferCount;
+        if (delta < 0) {
+            listener = mCore->mConsumerListener;
+        }
     }
 
-    if (bufferCount < mCore->mMaxAcquiredBufferCount) {
-        BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
-                "mMaxAcquiredBufferCount (%d)", bufferCount,
-                mCore->mMaxAcquiredBufferCount);
-        return BAD_VALUE;
+    // Call back without lock held
+    if (listener != NULL) {
+        listener->onBuffersReleased();
     }
-
-    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
-            mCore->mDequeueBufferCannotBlock, bufferCount) -
-            mCore->getMaxBufferCountLocked();
-    if (!mCore->adjustAvailableSlotsLocked(delta)) {
-        BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
-                "available slots. Delta = %d", delta);
-        return BAD_VALUE;
-    }
-
-    mCore->mMaxBufferCount = bufferCount;
     return NO_ERROR;
 }
 
@@ -611,7 +637,9 @@
         return BAD_VALUE;
     }
 
-    sp<IConsumerListener> listener;
+    sp<IConsumerListener> consumerListener;
+    sp<IProducerListener> producerListener;
+    std::vector<int> freedSlots;
     { // Autolock scope
         Mutex::Autolock lock(mCore->mMutex);
         mCore->waitWhileAllocatingLocked();
@@ -648,7 +676,7 @@
         }
 
         int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
-        if (!mCore->adjustAvailableSlotsLocked(delta)) {
+        if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
             return BAD_VALUE;
         }
 
@@ -656,12 +684,19 @@
         mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
         VALIDATE_CONSISTENCY();
         if (delta < 0) {
-            listener = mCore->mConsumerListener;
+            consumerListener = mCore->mConsumerListener;
+            producerListener = mCore->mConnectedProducerListener;
         }
     }
+
     // Call back without lock held
-    if (listener != NULL) {
-        listener->onBuffersReleased();
+    if (consumerListener != NULL) {
+        consumerListener->onBuffersReleased();
+    }
+    if (producerListener != NULL) {
+        for (int i : freedSlots) {
+            producerListener->onSlotFreed(i);
+        }
     }
 
     return NO_ERROR;