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