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