Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <inttypes.h>
     18 
     19 #define LOG_TAG "BufferQueueProducer"
     20 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     21 //#define LOG_NDEBUG 0
     22 
     23 #if DEBUG_ONLY_CODE
     24 #define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
     25 #else
     26 #define VALIDATE_CONSISTENCY()
     27 #endif
     28 
     29 #define EGL_EGLEXT_PROTOTYPES
     30 
     31 #include <binder/IPCThreadState.h>
     32 #include <gui/BufferItem.h>
     33 #include <gui/BufferQueueCore.h>
     34 #include <gui/BufferQueueProducer.h>
     35 #include <gui/GLConsumer.h>
     36 #include <gui/IConsumerListener.h>
     37 #include <gui/IGraphicBufferAlloc.h>
     38 #include <gui/IProducerListener.h>
     39 
     40 #include <utils/Log.h>
     41 #include <utils/Trace.h>
     42 
     43 namespace android {
     44 
     45 BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
     46     mCore(core),
     47     mSlots(core->mSlots),
     48     mConsumerName(),
     49     mStickyTransform(0),
     50     mLastQueueBufferFence(Fence::NO_FENCE),
     51     mCallbackMutex(),
     52     mNextCallbackTicket(0),
     53     mCurrentCallbackTicket(0),
     54     mCallbackCondition(),
     55     mDequeueTimeout(-1) {}
     56 
     57 BufferQueueProducer::~BufferQueueProducer() {}
     58 
     59 status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
     60     ATRACE_CALL();
     61     BQ_LOGV("requestBuffer: slot %d", slot);
     62     Mutex::Autolock lock(mCore->mMutex);
     63 
     64     if (mCore->mIsAbandoned) {
     65         BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
     66         return NO_INIT;
     67     }
     68 
     69     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
     70         BQ_LOGE("requestBuffer: BufferQueue has no connected producer");
     71         return NO_INIT;
     72     }
     73 
     74     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
     75         BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
     76                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
     77         return BAD_VALUE;
     78     } else if (!mSlots[slot].mBufferState.isDequeued()) {
     79         BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
     80                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
     81         return BAD_VALUE;
     82     }
     83 
     84     mSlots[slot].mRequestBufferCalled = true;
     85     *buf = mSlots[slot].mGraphicBuffer;
     86     return NO_ERROR;
     87 }
     88 
     89 status_t BufferQueueProducer::setMaxDequeuedBufferCount(
     90         int maxDequeuedBuffers) {
     91     ATRACE_CALL();
     92     BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
     93             maxDequeuedBuffers);
     94 
     95     sp<IConsumerListener> listener;
     96     { // Autolock scope
     97         Mutex::Autolock lock(mCore->mMutex);
     98         mCore->waitWhileAllocatingLocked();
     99 
    100         if (mCore->mIsAbandoned) {
    101             BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
    102                     "abandoned");
    103             return NO_INIT;
    104         }
    105 
    106         if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
    107             return NO_ERROR;
    108         }
    109 
    110         // The new maxDequeuedBuffer count should not be violated by the number
    111         // of currently dequeued buffers
    112         int dequeuedCount = 0;
    113         for (int s : mCore->mActiveBuffers) {
    114             if (mSlots[s].mBufferState.isDequeued()) {
    115                 dequeuedCount++;
    116             }
    117         }
    118         if (dequeuedCount > maxDequeuedBuffers) {
    119             BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer"
    120                     "count (%d) exceeds the current dequeued buffer count (%d)",
    121                     maxDequeuedBuffers, dequeuedCount);
    122             return BAD_VALUE;
    123         }
    124 
    125         int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
    126         bufferCount += maxDequeuedBuffers;
    127 
    128         if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
    129             BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
    130                     "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
    131             return BAD_VALUE;
    132         }
    133 
    134         const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
    135         if (bufferCount < minBufferSlots) {
    136             BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is "
    137                     "less than minimum %d", bufferCount, minBufferSlots);
    138             return BAD_VALUE;
    139         }
    140 
    141         if (bufferCount > mCore->mMaxBufferCount) {
    142             BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would "
    143                     "exceed the maxBufferCount (%d) (maxAcquired %d async %d "
    144                     "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers,
    145                     mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
    146                     mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock);
    147             return BAD_VALUE;
    148         }
    149 
    150         int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
    151         if (!mCore->adjustAvailableSlotsLocked(delta)) {
    152             return BAD_VALUE;
    153         }
    154         mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
    155         VALIDATE_CONSISTENCY();
    156         if (delta < 0) {
    157             listener = mCore->mConsumerListener;
    158         }
    159         mCore->mDequeueCondition.broadcast();
    160     } // Autolock scope
    161 
    162     // Call back without lock held
    163     if (listener != NULL) {
    164         listener->onBuffersReleased();
    165     }
    166 
    167     return NO_ERROR;
    168 }
    169 
    170 status_t BufferQueueProducer::setAsyncMode(bool async) {
    171     ATRACE_CALL();
    172     BQ_LOGV("setAsyncMode: async = %d", async);
    173 
    174     sp<IConsumerListener> listener;
    175     { // Autolock scope
    176         Mutex::Autolock lock(mCore->mMutex);
    177         mCore->waitWhileAllocatingLocked();
    178 
    179         if (mCore->mIsAbandoned) {
    180             BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
    181             return NO_INIT;
    182         }
    183 
    184         if (async == mCore->mAsyncMode) {
    185             return NO_ERROR;
    186         }
    187 
    188         if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount +
    189                 (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) >
    190                 mCore->mMaxBufferCount) {
    191             BQ_LOGE("setAsyncMode(%d): this call would cause the "
    192                     "maxBufferCount (%d) to be exceeded (maxAcquired %d "
    193                     "maxDequeued %d mDequeueBufferCannotBlock %d)", async,
    194                     mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
    195                     mCore->mMaxDequeuedBufferCount,
    196                     mCore->mDequeueBufferCannotBlock);
    197             return BAD_VALUE;
    198         }
    199 
    200         int delta = mCore->getMaxBufferCountLocked(async,
    201                 mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount)
    202                 - mCore->getMaxBufferCountLocked();
    203 
    204         if (!mCore->adjustAvailableSlotsLocked(delta)) {
    205             BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of "
    206                     "available slots. Delta = %d", delta);
    207             return BAD_VALUE;
    208         }
    209         mCore->mAsyncMode = async;
    210         VALIDATE_CONSISTENCY();
    211         mCore->mDequeueCondition.broadcast();
    212         if (delta < 0) {
    213             listener = mCore->mConsumerListener;
    214         }
    215     } // Autolock scope
    216 
    217     // Call back without lock held
    218     if (listener != NULL) {
    219         listener->onBuffersReleased();
    220     }
    221     return NO_ERROR;
    222 }
    223 
    224 int BufferQueueProducer::getFreeBufferLocked() const {
    225     if (mCore->mFreeBuffers.empty()) {
    226         return BufferQueueCore::INVALID_BUFFER_SLOT;
    227     }
    228     int slot = mCore->mFreeBuffers.front();
    229     mCore->mFreeBuffers.pop_front();
    230     return slot;
    231 }
    232 
    233 int BufferQueueProducer::getFreeSlotLocked() const {
    234     if (mCore->mFreeSlots.empty()) {
    235         return BufferQueueCore::INVALID_BUFFER_SLOT;
    236     }
    237     int slot = *(mCore->mFreeSlots.begin());
    238     mCore->mFreeSlots.erase(slot);
    239     return slot;
    240 }
    241 
    242 status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
    243         int* found) const {
    244     auto callerString = (caller == FreeSlotCaller::Dequeue) ?
    245             "dequeueBuffer" : "attachBuffer";
    246     bool tryAgain = true;
    247     while (tryAgain) {
    248         if (mCore->mIsAbandoned) {
    249             BQ_LOGE("%s: BufferQueue has been abandoned", callerString);
    250             return NO_INIT;
    251         }
    252 
    253         int dequeuedCount = 0;
    254         int acquiredCount = 0;
    255         for (int s : mCore->mActiveBuffers) {
    256             if (mSlots[s].mBufferState.isDequeued()) {
    257                 ++dequeuedCount;
    258             }
    259             if (mSlots[s].mBufferState.isAcquired()) {
    260                 ++acquiredCount;
    261             }
    262         }
    263 
    264         // Producers are not allowed to dequeue more than
    265         // mMaxDequeuedBufferCount buffers.
    266         // This check is only done if a buffer has already been queued
    267         if (mCore->mBufferHasBeenQueued &&
    268                 dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
    269             BQ_LOGE("%s: attempting to exceed the max dequeued buffer count "
    270                     "(%d)", callerString, mCore->mMaxDequeuedBufferCount);
    271             return INVALID_OPERATION;
    272         }
    273 
    274         *found = BufferQueueCore::INVALID_BUFFER_SLOT;
    275 
    276         // If we disconnect and reconnect quickly, we can be in a state where
    277         // our slots are empty but we have many buffers in the queue. This can
    278         // cause us to run out of memory if we outrun the consumer. Wait here if
    279         // it looks like we have too many buffers queued up.
    280         const int maxBufferCount = mCore->getMaxBufferCountLocked();
    281         bool tooManyBuffers = mCore->mQueue.size()
    282                             > static_cast<size_t>(maxBufferCount);
    283         if (tooManyBuffers) {
    284             BQ_LOGV("%s: queue size is %zu, waiting", callerString,
    285                     mCore->mQueue.size());
    286         } else {
    287             // If in shared buffer mode and a shared buffer exists, always
    288             // return it.
    289             if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot !=
    290                     BufferQueueCore::INVALID_BUFFER_SLOT) {
    291                 *found = mCore->mSharedBufferSlot;
    292             } else {
    293                 if (caller == FreeSlotCaller::Dequeue) {
    294                     // If we're calling this from dequeue, prefer free buffers
    295                     int slot = getFreeBufferLocked();
    296                     if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
    297                         *found = slot;
    298                     } else if (mCore->mAllowAllocation) {
    299                         *found = getFreeSlotLocked();
    300                     }
    301                 } else {
    302                     // If we're calling this from attach, prefer free slots
    303                     int slot = getFreeSlotLocked();
    304                     if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
    305                         *found = slot;
    306                     } else {
    307                         *found = getFreeBufferLocked();
    308                     }
    309                 }
    310             }
    311         }
    312 
    313         // If no buffer is found, or if the queue has too many buffers
    314         // outstanding, wait for a buffer to be acquired or released, or for the
    315         // max buffer count to change.
    316         tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
    317                    tooManyBuffers;
    318         if (tryAgain) {
    319             // Return an error if we're in non-blocking mode (producer and
    320             // consumer are controlled by the application).
    321             // However, the consumer is allowed to briefly acquire an extra
    322             // buffer (which could cause us to have to wait here), which is
    323             // okay, since it is only used to implement an atomic acquire +
    324             // release (e.g., in GLConsumer::updateTexImage())
    325             if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) &&
    326                     (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
    327                 return WOULD_BLOCK;
    328             }
    329             if (mDequeueTimeout >= 0) {
    330                 status_t result = mCore->mDequeueCondition.waitRelative(
    331                         mCore->mMutex, mDequeueTimeout);
    332                 if (result == TIMED_OUT) {
    333                     return result;
    334                 }
    335             } else {
    336                 mCore->mDequeueCondition.wait(mCore->mMutex);
    337             }
    338         }
    339     } // while (tryAgain)
    340 
    341     return NO_ERROR;
    342 }
    343 
    344 status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
    345         sp<android::Fence> *outFence, uint32_t width, uint32_t height,
    346         PixelFormat format, uint32_t usage) {
    347     ATRACE_CALL();
    348     { // Autolock scope
    349         Mutex::Autolock lock(mCore->mMutex);
    350         mConsumerName = mCore->mConsumerName;
    351 
    352         if (mCore->mIsAbandoned) {
    353             BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
    354             return NO_INIT;
    355         }
    356 
    357         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    358             BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
    359             return NO_INIT;
    360         }
    361     } // Autolock scope
    362 
    363     BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height,
    364             format, usage);
    365 
    366     if ((width && !height) || (!width && height)) {
    367         BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
    368         return BAD_VALUE;
    369     }
    370 
    371     status_t returnFlags = NO_ERROR;
    372     EGLDisplay eglDisplay = EGL_NO_DISPLAY;
    373     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    374     bool attachedByConsumer = false;
    375 
    376     { // Autolock scope
    377         Mutex::Autolock lock(mCore->mMutex);
    378         mCore->waitWhileAllocatingLocked();
    379 
    380         if (format == 0) {
    381             format = mCore->mDefaultBufferFormat;
    382         }
    383 
    384         // Enable the usage bits the consumer requested
    385         usage |= mCore->mConsumerUsageBits;
    386 
    387         const bool useDefaultSize = !width && !height;
    388         if (useDefaultSize) {
    389             width = mCore->mDefaultWidth;
    390             height = mCore->mDefaultHeight;
    391         }
    392 
    393         int found = BufferItem::INVALID_BUFFER_SLOT;
    394         while (found == BufferItem::INVALID_BUFFER_SLOT) {
    395             status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
    396                     &found);
    397             if (status != NO_ERROR) {
    398                 return status;
    399             }
    400 
    401             // This should not happen
    402             if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    403                 BQ_LOGE("dequeueBuffer: no available buffer slots");
    404                 return -EBUSY;
    405             }
    406 
    407             const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
    408 
    409             // If we are not allowed to allocate new buffers,
    410             // waitForFreeSlotThenRelock must have returned a slot containing a
    411             // buffer. If this buffer would require reallocation to meet the
    412             // requested attributes, we free it and attempt to get another one.
    413             if (!mCore->mAllowAllocation) {
    414                 if (buffer->needsReallocation(width, height, format, usage)) {
    415                     if (mCore->mSharedBufferSlot == found) {
    416                         BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
    417                                 "buffer");
    418                         return BAD_VALUE;
    419                     }
    420                     mCore->mFreeSlots.insert(found);
    421                     mCore->clearBufferSlotLocked(found);
    422                     found = BufferItem::INVALID_BUFFER_SLOT;
    423                     continue;
    424                 }
    425             }
    426         }
    427 
    428         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
    429         if (mCore->mSharedBufferSlot == found &&
    430                 buffer->needsReallocation(width,  height, format, usage)) {
    431             BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
    432                     "buffer");
    433 
    434             return BAD_VALUE;
    435         }
    436 
    437         if (mCore->mSharedBufferSlot != found) {
    438             mCore->mActiveBuffers.insert(found);
    439         }
    440         *outSlot = found;
    441         ATRACE_BUFFER_INDEX(found);
    442 
    443         attachedByConsumer = mSlots[found].mNeedsReallocation;
    444         mSlots[found].mNeedsReallocation = false;
    445 
    446         mSlots[found].mBufferState.dequeue();
    447 
    448         if ((buffer == NULL) ||
    449                 buffer->needsReallocation(width, height, format, usage))
    450         {
    451             mSlots[found].mAcquireCalled = false;
    452             mSlots[found].mGraphicBuffer = NULL;
    453             mSlots[found].mRequestBufferCalled = false;
    454             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
    455             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
    456             mSlots[found].mFence = Fence::NO_FENCE;
    457             mCore->mBufferAge = 0;
    458             mCore->mIsAllocating = true;
    459 
    460             returnFlags |= BUFFER_NEEDS_REALLOCATION;
    461         } else {
    462             // We add 1 because that will be the frame number when this buffer
    463             // is queued
    464             mCore->mBufferAge =
    465                     mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
    466         }
    467 
    468         BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
    469                 mCore->mBufferAge);
    470 
    471         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
    472             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
    473                     "slot=%d w=%d h=%d format=%u",
    474                     found, buffer->width, buffer->height, buffer->format);
    475         }
    476 
    477         eglDisplay = mSlots[found].mEglDisplay;
    478         eglFence = mSlots[found].mEglFence;
    479         // Don't return a fence in shared buffer mode, except for the first
    480         // frame.
    481         *outFence = (mCore->mSharedBufferMode &&
    482                 mCore->mSharedBufferSlot == found) ?
    483                 Fence::NO_FENCE : mSlots[found].mFence;
    484         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
    485         mSlots[found].mFence = Fence::NO_FENCE;
    486 
    487         // If shared buffer mode has just been enabled, cache the slot of the
    488         // first buffer that is dequeued and mark it as the shared buffer.
    489         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
    490                 BufferQueueCore::INVALID_BUFFER_SLOT) {
    491             mCore->mSharedBufferSlot = found;
    492             mSlots[found].mBufferState.mShared = true;
    493         }
    494     } // Autolock scope
    495 
    496     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
    497         status_t error;
    498         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
    499         sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
    500                 width, height, format, usage,
    501                 {mConsumerName.string(), mConsumerName.size()}, &error));
    502         { // Autolock scope
    503             Mutex::Autolock lock(mCore->mMutex);
    504 
    505             if (graphicBuffer != NULL && !mCore->mIsAbandoned) {
    506                 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
    507                 mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
    508             }
    509 
    510             mCore->mIsAllocating = false;
    511             mCore->mIsAllocatingCondition.broadcast();
    512 
    513             if (graphicBuffer == NULL) {
    514                 mCore->mFreeSlots.insert(*outSlot);
    515                 mCore->clearBufferSlotLocked(*outSlot);
    516                 BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
    517                 return error;
    518             }
    519 
    520             if (mCore->mIsAbandoned) {
    521                 mCore->mFreeSlots.insert(*outSlot);
    522                 mCore->clearBufferSlotLocked(*outSlot);
    523                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
    524                 return NO_INIT;
    525             }
    526 
    527             VALIDATE_CONSISTENCY();
    528         } // Autolock scope
    529     }
    530 
    531     if (attachedByConsumer) {
    532         returnFlags |= BUFFER_NEEDS_REALLOCATION;
    533     }
    534 
    535     if (eglFence != EGL_NO_SYNC_KHR) {
    536         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
    537                 1000000000);
    538         // If something goes wrong, log the error, but return the buffer without
    539         // synchronizing access to it. It's too late at this point to abort the
    540         // dequeue operation.
    541         if (result == EGL_FALSE) {
    542             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
    543                     eglGetError());
    544         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
    545             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
    546         }
    547         eglDestroySyncKHR(eglDisplay, eglFence);
    548     }
    549 
    550     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
    551             *outSlot,
    552             mSlots[*outSlot].mFrameNumber,
    553             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
    554 
    555     return returnFlags;
    556 }
    557 
    558 status_t BufferQueueProducer::detachBuffer(int slot) {
    559     ATRACE_CALL();
    560     ATRACE_BUFFER_INDEX(slot);
    561     BQ_LOGV("detachBuffer: slot %d", slot);
    562 
    563     sp<IConsumerListener> listener;
    564     {
    565         Mutex::Autolock lock(mCore->mMutex);
    566 
    567         if (mCore->mIsAbandoned) {
    568             BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
    569             return NO_INIT;
    570         }
    571 
    572         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    573             BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
    574             return NO_INIT;
    575         }
    576 
    577         if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) {
    578             BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode");
    579             return BAD_VALUE;
    580         }
    581 
    582         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    583             BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
    584                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    585             return BAD_VALUE;
    586         } else if (!mSlots[slot].mBufferState.isDequeued()) {
    587             BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
    588                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
    589             return BAD_VALUE;
    590         } else if (!mSlots[slot].mRequestBufferCalled) {
    591             BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
    592                     slot);
    593             return BAD_VALUE;
    594         }
    595 
    596         mSlots[slot].mBufferState.detachProducer();
    597         mCore->mActiveBuffers.erase(slot);
    598         mCore->mFreeSlots.insert(slot);
    599         mCore->clearBufferSlotLocked(slot);
    600         mCore->mDequeueCondition.broadcast();
    601         VALIDATE_CONSISTENCY();
    602         listener = mCore->mConsumerListener;
    603     }
    604 
    605     if (listener != NULL) {
    606         listener->onBuffersReleased();
    607     }
    608 
    609     return NO_ERROR;
    610 }
    611 
    612 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
    613         sp<Fence>* outFence) {
    614     ATRACE_CALL();
    615 
    616     if (outBuffer == NULL) {
    617         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
    618         return BAD_VALUE;
    619     } else if (outFence == NULL) {
    620         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
    621         return BAD_VALUE;
    622     }
    623 
    624     Mutex::Autolock lock(mCore->mMutex);
    625 
    626     if (mCore->mIsAbandoned) {
    627         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
    628         return NO_INIT;
    629     }
    630 
    631     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    632         BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
    633         return NO_INIT;
    634     }
    635 
    636     if (mCore->mSharedBufferMode) {
    637         BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
    638             "mode");
    639         return BAD_VALUE;
    640     }
    641 
    642     mCore->waitWhileAllocatingLocked();
    643 
    644     if (mCore->mFreeBuffers.empty()) {
    645         return NO_MEMORY;
    646     }
    647 
    648     int found = mCore->mFreeBuffers.front();
    649     mCore->mFreeBuffers.remove(found);
    650     mCore->mFreeSlots.insert(found);
    651 
    652     BQ_LOGV("detachNextBuffer detached slot %d", found);
    653 
    654     *outBuffer = mSlots[found].mGraphicBuffer;
    655     *outFence = mSlots[found].mFence;
    656     mCore->clearBufferSlotLocked(found);
    657     VALIDATE_CONSISTENCY();
    658 
    659     return NO_ERROR;
    660 }
    661 
    662 status_t BufferQueueProducer::attachBuffer(int* outSlot,
    663         const sp<android::GraphicBuffer>& buffer) {
    664     ATRACE_CALL();
    665 
    666     if (outSlot == NULL) {
    667         BQ_LOGE("attachBuffer: outSlot must not be NULL");
    668         return BAD_VALUE;
    669     } else if (buffer == NULL) {
    670         BQ_LOGE("attachBuffer: cannot attach NULL buffer");
    671         return BAD_VALUE;
    672     }
    673 
    674     Mutex::Autolock lock(mCore->mMutex);
    675 
    676     if (mCore->mIsAbandoned) {
    677         BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
    678         return NO_INIT;
    679     }
    680 
    681     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    682         BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
    683         return NO_INIT;
    684     }
    685 
    686     if (mCore->mSharedBufferMode) {
    687         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
    688         return BAD_VALUE;
    689     }
    690 
    691     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
    692         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
    693                 "[queue %u]", buffer->getGenerationNumber(),
    694                 mCore->mGenerationNumber);
    695         return BAD_VALUE;
    696     }
    697 
    698     mCore->waitWhileAllocatingLocked();
    699 
    700     status_t returnFlags = NO_ERROR;
    701     int found;
    702     status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
    703     if (status != NO_ERROR) {
    704         return status;
    705     }
    706 
    707     // This should not happen
    708     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    709         BQ_LOGE("attachBuffer: no available buffer slots");
    710         return -EBUSY;
    711     }
    712 
    713     *outSlot = found;
    714     ATRACE_BUFFER_INDEX(*outSlot);
    715     BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
    716             *outSlot, returnFlags);
    717 
    718     mSlots[*outSlot].mGraphicBuffer = buffer;
    719     mSlots[*outSlot].mBufferState.attachProducer();
    720     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
    721     mSlots[*outSlot].mFence = Fence::NO_FENCE;
    722     mSlots[*outSlot].mRequestBufferCalled = true;
    723     mSlots[*outSlot].mAcquireCalled = false;
    724     mCore->mActiveBuffers.insert(found);
    725     VALIDATE_CONSISTENCY();
    726 
    727     return returnFlags;
    728 }
    729 
    730 status_t BufferQueueProducer::queueBuffer(int slot,
    731         const QueueBufferInput &input, QueueBufferOutput *output) {
    732     ATRACE_CALL();
    733     ATRACE_BUFFER_INDEX(slot);
    734 
    735     int64_t timestamp;
    736     bool isAutoTimestamp;
    737     android_dataspace dataSpace;
    738     Rect crop(Rect::EMPTY_RECT);
    739     int scalingMode;
    740     uint32_t transform;
    741     uint32_t stickyTransform;
    742     sp<Fence> fence;
    743     input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
    744             &transform, &fence, &stickyTransform);
    745     Region surfaceDamage = input.getSurfaceDamage();
    746 
    747     if (fence == NULL) {
    748         BQ_LOGE("queueBuffer: fence is NULL");
    749         return BAD_VALUE;
    750     }
    751 
    752     switch (scalingMode) {
    753         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
    754         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
    755         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
    756         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
    757             break;
    758         default:
    759             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
    760             return BAD_VALUE;
    761     }
    762 
    763     sp<IConsumerListener> frameAvailableListener;
    764     sp<IConsumerListener> frameReplacedListener;
    765     int callbackTicket = 0;
    766     BufferItem item;
    767     { // Autolock scope
    768         Mutex::Autolock lock(mCore->mMutex);
    769 
    770         if (mCore->mIsAbandoned) {
    771             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
    772             return NO_INIT;
    773         }
    774 
    775         if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    776             BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
    777             return NO_INIT;
    778         }
    779 
    780         if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    781             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
    782                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    783             return BAD_VALUE;
    784         } else if (!mSlots[slot].mBufferState.isDequeued()) {
    785             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
    786                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
    787             return BAD_VALUE;
    788         } else if (!mSlots[slot].mRequestBufferCalled) {
    789             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
    790                     "a buffer", slot);
    791             return BAD_VALUE;
    792         }
    793 
    794         // If shared buffer mode has just been enabled, cache the slot of the
    795         // first buffer that is queued and mark it as the shared buffer.
    796         if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
    797                 BufferQueueCore::INVALID_BUFFER_SLOT) {
    798             mCore->mSharedBufferSlot = slot;
    799             mSlots[slot].mBufferState.mShared = true;
    800         }
    801 
    802         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
    803                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
    804                 slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
    805                 crop.left, crop.top, crop.right, crop.bottom, transform,
    806                 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
    807 
    808         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
    809         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
    810         Rect croppedRect(Rect::EMPTY_RECT);
    811         crop.intersect(bufferRect, &croppedRect);
    812         if (croppedRect != crop) {
    813             BQ_LOGE("queueBuffer: crop rect is not contained within the "
    814                     "buffer in slot %d", slot);
    815             return BAD_VALUE;
    816         }
    817 
    818         // Override UNKNOWN dataspace with consumer default
    819         if (dataSpace == HAL_DATASPACE_UNKNOWN) {
    820             dataSpace = mCore->mDefaultBufferDataSpace;
    821         }
    822 
    823         mSlots[slot].mFence = fence;
    824         mSlots[slot].mBufferState.queue();
    825 
    826         ++mCore->mFrameCounter;
    827         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
    828 
    829         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
    830         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
    831         item.mCrop = crop;
    832         item.mTransform = transform &
    833                 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
    834         item.mTransformToDisplayInverse =
    835                 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
    836         item.mScalingMode = static_cast<uint32_t>(scalingMode);
    837         item.mTimestamp = timestamp;
    838         item.mIsAutoTimestamp = isAutoTimestamp;
    839         item.mDataSpace = dataSpace;
    840         item.mFrameNumber = mCore->mFrameCounter;
    841         item.mSlot = slot;
    842         item.mFence = fence;
    843         item.mIsDroppable = mCore->mAsyncMode ||
    844                 mCore->mDequeueBufferCannotBlock ||
    845                 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
    846         item.mSurfaceDamage = surfaceDamage;
    847         item.mQueuedBuffer = true;
    848         item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
    849 
    850         mStickyTransform = stickyTransform;
    851 
    852         // Cache the shared buffer data so that the BufferItem can be recreated.
    853         if (mCore->mSharedBufferMode) {
    854             mCore->mSharedBufferCache.crop = crop;
    855             mCore->mSharedBufferCache.transform = transform;
    856             mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
    857                     scalingMode);
    858             mCore->mSharedBufferCache.dataspace = dataSpace;
    859         }
    860 
    861         if (mCore->mQueue.empty()) {
    862             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
    863             // and simply queue this buffer
    864             mCore->mQueue.push_back(item);
    865             frameAvailableListener = mCore->mConsumerListener;
    866         } else {
    867             // When the queue is not empty, we need to look at the last buffer
    868             // in the queue to see if we need to replace it
    869             const BufferItem& last = mCore->mQueue.itemAt(
    870                     mCore->mQueue.size() - 1);
    871             if (last.mIsDroppable) {
    872 
    873                 if (!last.mIsStale) {
    874                     mSlots[last.mSlot].mBufferState.freeQueued();
    875 
    876                     // After leaving shared buffer mode, the shared buffer will
    877                     // still be around. Mark it as no longer shared if this
    878                     // operation causes it to be free.
    879                     if (!mCore->mSharedBufferMode &&
    880                             mSlots[last.mSlot].mBufferState.isFree()) {
    881                         mSlots[last.mSlot].mBufferState.mShared = false;
    882                     }
    883                     // Don't put the shared buffer on the free list.
    884                     if (!mSlots[last.mSlot].mBufferState.isShared()) {
    885                         mCore->mActiveBuffers.erase(last.mSlot);
    886                         mCore->mFreeBuffers.push_back(last.mSlot);
    887                     }
    888                 }
    889 
    890                 // Overwrite the droppable buffer with the incoming one
    891                 mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
    892                 frameReplacedListener = mCore->mConsumerListener;
    893             } else {
    894                 mCore->mQueue.push_back(item);
    895                 frameAvailableListener = mCore->mConsumerListener;
    896             }
    897         }
    898 
    899         mCore->mBufferHasBeenQueued = true;
    900         mCore->mDequeueCondition.broadcast();
    901         mCore->mLastQueuedSlot = slot;
    902 
    903         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
    904                 mCore->mTransformHint,
    905                 static_cast<uint32_t>(mCore->mQueue.size()),
    906                 mCore->mFrameCounter + 1);
    907 
    908         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
    909         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
    910 
    911         // Take a ticket for the callback functions
    912         callbackTicket = mNextCallbackTicket++;
    913 
    914         VALIDATE_CONSISTENCY();
    915     } // Autolock scope
    916 
    917     // Don't send the GraphicBuffer through the callback, and don't send
    918     // the slot number, since the consumer shouldn't need it
    919     item.mGraphicBuffer.clear();
    920     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
    921 
    922     // Call back without the main BufferQueue lock held, but with the callback
    923     // lock held so we can ensure that callbacks occur in order
    924     {
    925         Mutex::Autolock lock(mCallbackMutex);
    926         while (callbackTicket != mCurrentCallbackTicket) {
    927             mCallbackCondition.wait(mCallbackMutex);
    928         }
    929 
    930         if (frameAvailableListener != NULL) {
    931             frameAvailableListener->onFrameAvailable(item);
    932         } else if (frameReplacedListener != NULL) {
    933             frameReplacedListener->onFrameReplaced(item);
    934         }
    935 
    936         ++mCurrentCallbackTicket;
    937         mCallbackCondition.broadcast();
    938     }
    939 
    940     // Wait without lock held
    941     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
    942         // Waiting here allows for two full buffers to be queued but not a
    943         // third. In the event that frames take varying time, this makes a
    944         // small trade-off in favor of latency rather than throughput.
    945         mLastQueueBufferFence->waitForever("Throttling EGL Production");
    946     }
    947     mLastQueueBufferFence = fence;
    948     mLastQueuedCrop = item.mCrop;
    949     mLastQueuedTransform = item.mTransform;
    950 
    951     return NO_ERROR;
    952 }
    953 
    954 status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
    955     ATRACE_CALL();
    956     BQ_LOGV("cancelBuffer: slot %d", slot);
    957     Mutex::Autolock lock(mCore->mMutex);
    958 
    959     if (mCore->mIsAbandoned) {
    960         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
    961         return NO_INIT;
    962     }
    963 
    964     if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
    965         BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
    966         return NO_INIT;
    967     }
    968 
    969     if (mCore->mSharedBufferMode) {
    970         BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
    971         return BAD_VALUE;
    972     }
    973 
    974     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    975         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
    976                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    977         return BAD_VALUE;
    978     } else if (!mSlots[slot].mBufferState.isDequeued()) {
    979         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
    980                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
    981         return BAD_VALUE;
    982     } else if (fence == NULL) {
    983         BQ_LOGE("cancelBuffer: fence is NULL");
    984         return BAD_VALUE;
    985     }
    986 
    987     mSlots[slot].mBufferState.cancel();
    988 
    989     // After leaving shared buffer mode, the shared buffer will still be around.
    990     // Mark it as no longer shared if this operation causes it to be free.
    991     if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
    992         mSlots[slot].mBufferState.mShared = false;
    993     }
    994 
    995     // Don't put the shared buffer on the free list.
    996     if (!mSlots[slot].mBufferState.isShared()) {
    997         mCore->mActiveBuffers.erase(slot);
    998         mCore->mFreeBuffers.push_back(slot);
    999     }
   1000 
   1001     mSlots[slot].mFence = fence;
   1002     mCore->mDequeueCondition.broadcast();
   1003     VALIDATE_CONSISTENCY();
   1004 
   1005     return NO_ERROR;
   1006 }
   1007 
   1008 int BufferQueueProducer::query(int what, int *outValue) {
   1009     ATRACE_CALL();
   1010     Mutex::Autolock lock(mCore->mMutex);
   1011 
   1012     if (outValue == NULL) {
   1013         BQ_LOGE("query: outValue was NULL");
   1014         return BAD_VALUE;
   1015     }
   1016 
   1017     if (mCore->mIsAbandoned) {
   1018         BQ_LOGE("query: BufferQueue has been abandoned");
   1019         return NO_INIT;
   1020     }
   1021 
   1022     int value;
   1023     switch (what) {
   1024         case NATIVE_WINDOW_WIDTH:
   1025             value = static_cast<int32_t>(mCore->mDefaultWidth);
   1026             break;
   1027         case NATIVE_WINDOW_HEIGHT:
   1028             value = static_cast<int32_t>(mCore->mDefaultHeight);
   1029             break;
   1030         case NATIVE_WINDOW_FORMAT:
   1031             value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
   1032             break;
   1033         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
   1034             value = mCore->getMinUndequeuedBufferCountLocked();
   1035             break;
   1036         case NATIVE_WINDOW_STICKY_TRANSFORM:
   1037             value = static_cast<int32_t>(mStickyTransform);
   1038             break;
   1039         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
   1040             value = (mCore->mQueue.size() > 1);
   1041             break;
   1042         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
   1043             value = static_cast<int32_t>(mCore->mConsumerUsageBits);
   1044             break;
   1045         case NATIVE_WINDOW_DEFAULT_DATASPACE:
   1046             value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
   1047             break;
   1048         case NATIVE_WINDOW_BUFFER_AGE:
   1049             if (mCore->mBufferAge > INT32_MAX) {
   1050                 value = 0;
   1051             } else {
   1052                 value = static_cast<int32_t>(mCore->mBufferAge);
   1053             }
   1054             break;
   1055         default:
   1056             return BAD_VALUE;
   1057     }
   1058 
   1059     BQ_LOGV("query: %d? %d", what, value);
   1060     *outValue = value;
   1061     return NO_ERROR;
   1062 }
   1063 
   1064 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
   1065         int api, bool producerControlledByApp, QueueBufferOutput *output) {
   1066     ATRACE_CALL();
   1067     Mutex::Autolock lock(mCore->mMutex);
   1068     mConsumerName = mCore->mConsumerName;
   1069     BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
   1070             producerControlledByApp ? "true" : "false");
   1071 
   1072     if (mCore->mIsAbandoned) {
   1073         BQ_LOGE("connect: BufferQueue has been abandoned");
   1074         return NO_INIT;
   1075     }
   1076 
   1077     if (mCore->mConsumerListener == NULL) {
   1078         BQ_LOGE("connect: BufferQueue has no consumer");
   1079         return NO_INIT;
   1080     }
   1081 
   1082     if (output == NULL) {
   1083         BQ_LOGE("connect: output was NULL");
   1084         return BAD_VALUE;
   1085     }
   1086 
   1087     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
   1088         BQ_LOGE("connect: already connected (cur=%d req=%d)",
   1089                 mCore->mConnectedApi, api);
   1090         return BAD_VALUE;
   1091     }
   1092 
   1093     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
   1094             mDequeueTimeout < 0 ?
   1095             mCore->mConsumerControlledByApp && producerControlledByApp : false,
   1096             mCore->mMaxBufferCount) -
   1097             mCore->getMaxBufferCountLocked();
   1098     if (!mCore->adjustAvailableSlotsLocked(delta)) {
   1099         BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
   1100                 "slots. Delta = %d", delta);
   1101         return BAD_VALUE;
   1102     }
   1103 
   1104     int status = NO_ERROR;
   1105     switch (api) {
   1106         case NATIVE_WINDOW_API_EGL:
   1107         case NATIVE_WINDOW_API_CPU:
   1108         case NATIVE_WINDOW_API_MEDIA:
   1109         case NATIVE_WINDOW_API_CAMERA:
   1110             mCore->mConnectedApi = api;
   1111             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
   1112                     mCore->mTransformHint,
   1113                     static_cast<uint32_t>(mCore->mQueue.size()),
   1114                     mCore->mFrameCounter + 1);
   1115 
   1116             // Set up a death notification so that we can disconnect
   1117             // automatically if the remote producer dies
   1118             if (listener != NULL &&
   1119                     IInterface::asBinder(listener)->remoteBinder() != NULL) {
   1120                 status = IInterface::asBinder(listener)->linkToDeath(
   1121                         static_cast<IBinder::DeathRecipient*>(this));
   1122                 if (status != NO_ERROR) {
   1123                     BQ_LOGE("connect: linkToDeath failed: %s (%d)",
   1124                             strerror(-status), status);
   1125                 }
   1126             }
   1127             mCore->mConnectedProducerListener = listener;
   1128             break;
   1129         default:
   1130             BQ_LOGE("connect: unknown API %d", api);
   1131             status = BAD_VALUE;
   1132             break;
   1133     }
   1134     mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
   1135     mCore->mBufferHasBeenQueued = false;
   1136     mCore->mDequeueBufferCannotBlock = false;
   1137     if (mDequeueTimeout < 0) {
   1138         mCore->mDequeueBufferCannotBlock =
   1139                 mCore->mConsumerControlledByApp && producerControlledByApp;
   1140     }
   1141 
   1142     mCore->mAllowAllocation = true;
   1143     VALIDATE_CONSISTENCY();
   1144     return status;
   1145 }
   1146 
   1147 status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
   1148     ATRACE_CALL();
   1149     BQ_LOGV("disconnect: api %d", api);
   1150 
   1151     int status = NO_ERROR;
   1152     sp<IConsumerListener> listener;
   1153     { // Autolock scope
   1154         Mutex::Autolock lock(mCore->mMutex);
   1155 
   1156         if (mode == DisconnectMode::AllLocal) {
   1157             if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) {
   1158                 return NO_ERROR;
   1159             }
   1160             api = BufferQueueCore::CURRENTLY_CONNECTED_API;
   1161         }
   1162 
   1163         mCore->waitWhileAllocatingLocked();
   1164 
   1165         if (mCore->mIsAbandoned) {
   1166             // It's not really an error to disconnect after the surface has
   1167             // been abandoned; it should just be a no-op.
   1168             return NO_ERROR;
   1169         }
   1170 
   1171         if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
   1172             api = mCore->mConnectedApi;
   1173             // If we're asked to disconnect the currently connected api but
   1174             // nobody is connected, it's not really an error.
   1175             if (api == BufferQueueCore::NO_CONNECTED_API) {
   1176                 return NO_ERROR;
   1177             }
   1178         }
   1179 
   1180         switch (api) {
   1181             case NATIVE_WINDOW_API_EGL:
   1182             case NATIVE_WINDOW_API_CPU:
   1183             case NATIVE_WINDOW_API_MEDIA:
   1184             case NATIVE_WINDOW_API_CAMERA:
   1185                 if (mCore->mConnectedApi == api) {
   1186                     mCore->freeAllBuffersLocked();
   1187 
   1188                     // Remove our death notification callback if we have one
   1189                     if (mCore->mConnectedProducerListener != NULL) {
   1190                         sp<IBinder> token =
   1191                                 IInterface::asBinder(mCore->mConnectedProducerListener);
   1192                         // This can fail if we're here because of the death
   1193                         // notification, but we just ignore it
   1194                         token->unlinkToDeath(
   1195                                 static_cast<IBinder::DeathRecipient*>(this));
   1196                     }
   1197                     mCore->mSharedBufferSlot =
   1198                             BufferQueueCore::INVALID_BUFFER_SLOT;
   1199                     mCore->mConnectedProducerListener = NULL;
   1200                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
   1201                     mCore->mConnectedPid = -1;
   1202                     mCore->mSidebandStream.clear();
   1203                     mCore->mDequeueCondition.broadcast();
   1204                     listener = mCore->mConsumerListener;
   1205                 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
   1206                     BQ_LOGE("disconnect: still connected to another API "
   1207                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
   1208                     status = BAD_VALUE;
   1209                 }
   1210                 break;
   1211             default:
   1212                 BQ_LOGE("disconnect: unknown API %d", api);
   1213                 status = BAD_VALUE;
   1214                 break;
   1215         }
   1216     } // Autolock scope
   1217 
   1218     // Call back without lock held
   1219     if (listener != NULL) {
   1220         listener->onBuffersReleased();
   1221     }
   1222 
   1223     return status;
   1224 }
   1225 
   1226 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
   1227     sp<IConsumerListener> listener;
   1228     { // Autolock scope
   1229         Mutex::Autolock _l(mCore->mMutex);
   1230         mCore->mSidebandStream = stream;
   1231         listener = mCore->mConsumerListener;
   1232     } // Autolock scope
   1233 
   1234     if (listener != NULL) {
   1235         listener->onSidebandStreamChanged();
   1236     }
   1237     return NO_ERROR;
   1238 }
   1239 
   1240 void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
   1241         PixelFormat format, uint32_t usage) {
   1242     ATRACE_CALL();
   1243     while (true) {
   1244         size_t newBufferCount = 0;
   1245         uint32_t allocWidth = 0;
   1246         uint32_t allocHeight = 0;
   1247         PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
   1248         uint32_t allocUsage = 0;
   1249         { // Autolock scope
   1250             Mutex::Autolock lock(mCore->mMutex);
   1251             mCore->waitWhileAllocatingLocked();
   1252 
   1253             if (!mCore->mAllowAllocation) {
   1254                 BQ_LOGE("allocateBuffers: allocation is not allowed for this "
   1255                         "BufferQueue");
   1256                 return;
   1257             }
   1258 
   1259             newBufferCount = mCore->mFreeSlots.size();
   1260             if (newBufferCount == 0) {
   1261                 return;
   1262             }
   1263 
   1264             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
   1265             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
   1266             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
   1267             allocUsage = usage | mCore->mConsumerUsageBits;
   1268 
   1269             mCore->mIsAllocating = true;
   1270         } // Autolock scope
   1271 
   1272         Vector<sp<GraphicBuffer>> buffers;
   1273         for (size_t i = 0; i <  newBufferCount; ++i) {
   1274             status_t result = NO_ERROR;
   1275             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
   1276                     allocWidth, allocHeight, allocFormat, allocUsage,
   1277                     {mConsumerName.string(), mConsumerName.size()}, &result));
   1278             if (result != NO_ERROR) {
   1279                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
   1280                         " %u, usage %u)", width, height, format, usage);
   1281                 Mutex::Autolock lock(mCore->mMutex);
   1282                 mCore->mIsAllocating = false;
   1283                 mCore->mIsAllocatingCondition.broadcast();
   1284                 return;
   1285             }
   1286             buffers.push_back(graphicBuffer);
   1287         }
   1288 
   1289         { // Autolock scope
   1290             Mutex::Autolock lock(mCore->mMutex);
   1291             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
   1292             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
   1293             PixelFormat checkFormat = format != 0 ?
   1294                     format : mCore->mDefaultBufferFormat;
   1295             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
   1296             if (checkWidth != allocWidth || checkHeight != allocHeight ||
   1297                 checkFormat != allocFormat || checkUsage != allocUsage) {
   1298                 // Something changed while we released the lock. Retry.
   1299                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
   1300                 mCore->mIsAllocating = false;
   1301                 mCore->mIsAllocatingCondition.broadcast();
   1302                 continue;
   1303             }
   1304 
   1305             for (size_t i = 0; i < newBufferCount; ++i) {
   1306                 if (mCore->mFreeSlots.empty()) {
   1307                     BQ_LOGV("allocateBuffers: a slot was occupied while "
   1308                             "allocating. Dropping allocated buffer.");
   1309                     continue;
   1310                 }
   1311                 auto slot = mCore->mFreeSlots.begin();
   1312                 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
   1313                 mSlots[*slot].mGraphicBuffer = buffers[i];
   1314                 mSlots[*slot].mFence = Fence::NO_FENCE;
   1315 
   1316                 // freeBufferLocked puts this slot on the free slots list. Since
   1317                 // we then attached a buffer, move the slot to free buffer list.
   1318                 mCore->mFreeBuffers.push_front(*slot);
   1319 
   1320                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
   1321                         *slot);
   1322 
   1323                 // Make sure the erase is done after all uses of the slot
   1324                 // iterator since it will be invalid after this point.
   1325                 mCore->mFreeSlots.erase(slot);
   1326             }
   1327 
   1328             mCore->mIsAllocating = false;
   1329             mCore->mIsAllocatingCondition.broadcast();
   1330             VALIDATE_CONSISTENCY();
   1331         } // Autolock scope
   1332     }
   1333 }
   1334 
   1335 status_t BufferQueueProducer::allowAllocation(bool allow) {
   1336     ATRACE_CALL();
   1337     BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
   1338 
   1339     Mutex::Autolock lock(mCore->mMutex);
   1340     mCore->mAllowAllocation = allow;
   1341     return NO_ERROR;
   1342 }
   1343 
   1344 status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
   1345     ATRACE_CALL();
   1346     BQ_LOGV("setGenerationNumber: %u", generationNumber);
   1347 
   1348     Mutex::Autolock lock(mCore->mMutex);
   1349     mCore->mGenerationNumber = generationNumber;
   1350     return NO_ERROR;
   1351 }
   1352 
   1353 String8 BufferQueueProducer::getConsumerName() const {
   1354     ATRACE_CALL();
   1355     BQ_LOGV("getConsumerName: %s", mConsumerName.string());
   1356     return mConsumerName;
   1357 }
   1358 
   1359 status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
   1360     ATRACE_CALL();
   1361     BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
   1362 
   1363     Mutex::Autolock lock(mCore->mMutex);
   1364     if (!sharedBufferMode) {
   1365         mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
   1366     }
   1367     mCore->mSharedBufferMode = sharedBufferMode;
   1368     return NO_ERROR;
   1369 }
   1370 
   1371 status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
   1372     ATRACE_CALL();
   1373     BQ_LOGV("setAutoRefresh: %d", autoRefresh);
   1374 
   1375     Mutex::Autolock lock(mCore->mMutex);
   1376 
   1377     mCore->mAutoRefresh = autoRefresh;
   1378     return NO_ERROR;
   1379 }
   1380 
   1381 status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
   1382     ATRACE_CALL();
   1383     BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
   1384 
   1385     Mutex::Autolock lock(mCore->mMutex);
   1386     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
   1387             mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
   1388     if (!mCore->adjustAvailableSlotsLocked(delta)) {
   1389         BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
   1390                 "available slots. Delta = %d", delta);
   1391         return BAD_VALUE;
   1392     }
   1393 
   1394     mDequeueTimeout = timeout;
   1395     mCore->mDequeueBufferCannotBlock = false;
   1396 
   1397     VALIDATE_CONSISTENCY();
   1398     return NO_ERROR;
   1399 }
   1400 
   1401 status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
   1402         sp<Fence>* outFence, float outTransformMatrix[16]) {
   1403     ATRACE_CALL();
   1404     BQ_LOGV("getLastQueuedBuffer");
   1405 
   1406     Mutex::Autolock lock(mCore->mMutex);
   1407     if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
   1408         *outBuffer = nullptr;
   1409         *outFence = Fence::NO_FENCE;
   1410         return NO_ERROR;
   1411     }
   1412 
   1413     *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
   1414     *outFence = mLastQueueBufferFence;
   1415 
   1416     // Currently only SurfaceFlinger internally ever changes
   1417     // GLConsumer's filtering mode, so we just use 'true' here as
   1418     // this is slightly specialized for the current client of this API,
   1419     // which does want filtering.
   1420     GLConsumer::computeTransformMatrix(outTransformMatrix,
   1421             mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
   1422             mLastQueuedTransform, true /* filter */);
   1423 
   1424     return NO_ERROR;
   1425 }
   1426 
   1427 bool BufferQueueProducer::getFrameTimestamps(uint64_t frameNumber,
   1428         FrameTimestamps* outTimestamps) const {
   1429     ATRACE_CALL();
   1430     BQ_LOGV("getFrameTimestamps, %" PRIu64, frameNumber);
   1431     sp<IConsumerListener> listener;
   1432 
   1433     {
   1434         Mutex::Autolock lock(mCore->mMutex);
   1435         listener = mCore->mConsumerListener;
   1436     }
   1437     if (listener != NULL) {
   1438         return listener->getFrameTimestamps(frameNumber, outTimestamps);
   1439     }
   1440     return false;
   1441 }
   1442 
   1443 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
   1444     // If we're here, it means that a producer we were connected to died.
   1445     // We're guaranteed that we are still connected to it because we remove
   1446     // this callback upon disconnect. It's therefore safe to read mConnectedApi
   1447     // without synchronization here.
   1448     int api = mCore->mConnectedApi;
   1449     disconnect(api);
   1450 }
   1451 
   1452 status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
   1453     BQ_LOGV("getUniqueId");
   1454 
   1455     *outId = mCore->mUniqueId;
   1456     return NO_ERROR;
   1457 }
   1458 
   1459 } // namespace android
   1460