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 #include <pwd.h>
     19 #include <sys/types.h>
     20 
     21 #define LOG_TAG "BufferQueueConsumer"
     22 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     23 //#define LOG_NDEBUG 0
     24 
     25 #if DEBUG_ONLY_CODE
     26 #define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
     27 #else
     28 #define VALIDATE_CONSISTENCY()
     29 #endif
     30 
     31 #include <gui/BufferItem.h>
     32 #include <gui/BufferQueueConsumer.h>
     33 #include <gui/BufferQueueCore.h>
     34 #include <gui/IConsumerListener.h>
     35 #include <gui/IProducerListener.h>
     36 
     37 #include <binder/IPCThreadState.h>
     38 #ifndef __ANDROID_VNDK__
     39 #include <binder/PermissionCache.h>
     40 #endif
     41 
     42 #include <system/window.h>
     43 
     44 namespace android {
     45 
     46 BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
     47     mCore(core),
     48     mSlots(core->mSlots),
     49     mConsumerName() {}
     50 
     51 BufferQueueConsumer::~BufferQueueConsumer() {}
     52 
     53 status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
     54         nsecs_t expectedPresent, uint64_t maxFrameNumber) {
     55     ATRACE_CALL();
     56 
     57     int numDroppedBuffers = 0;
     58     sp<IProducerListener> listener;
     59     {
     60         Mutex::Autolock lock(mCore->mMutex);
     61 
     62         // Check that the consumer doesn't currently have the maximum number of
     63         // buffers acquired. We allow the max buffer count to be exceeded by one
     64         // buffer so that the consumer can successfully set up the newly acquired
     65         // buffer before releasing the old one.
     66         int numAcquiredBuffers = 0;
     67         for (int s : mCore->mActiveBuffers) {
     68             if (mSlots[s].mBufferState.isAcquired()) {
     69                 ++numAcquiredBuffers;
     70             }
     71         }
     72         if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
     73             BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
     74                     numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
     75             return INVALID_OPERATION;
     76         }
     77 
     78         bool sharedBufferAvailable = mCore->mSharedBufferMode &&
     79                 mCore->mAutoRefresh && mCore->mSharedBufferSlot !=
     80                 BufferQueueCore::INVALID_BUFFER_SLOT;
     81 
     82         // In asynchronous mode the list is guaranteed to be one buffer deep,
     83         // while in synchronous mode we use the oldest buffer.
     84         if (mCore->mQueue.empty() && !sharedBufferAvailable) {
     85             return NO_BUFFER_AVAILABLE;
     86         }
     87 
     88         BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
     89 
     90         // If expectedPresent is specified, we may not want to return a buffer yet.
     91         // If it's specified and there's more than one buffer queued, we may want
     92         // to drop a buffer.
     93         // Skip this if we're in shared buffer mode and the queue is empty,
     94         // since in that case we'll just return the shared buffer.
     95         if (expectedPresent != 0 && !mCore->mQueue.empty()) {
     96             const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
     97 
     98             // The 'expectedPresent' argument indicates when the buffer is expected
     99             // to be presented on-screen. If the buffer's desired present time is
    100             // earlier (less) than expectedPresent -- meaning it will be displayed
    101             // on time or possibly late if we show it as soon as possible -- we
    102             // acquire and return it. If we don't want to display it until after the
    103             // expectedPresent time, we return PRESENT_LATER without acquiring it.
    104             //
    105             // To be safe, we don't defer acquisition if expectedPresent is more
    106             // than one second in the future beyond the desired present time
    107             // (i.e., we'd be holding the buffer for a long time).
    108             //
    109             // NOTE: Code assumes monotonic time values from the system clock
    110             // are positive.
    111 
    112             // Start by checking to see if we can drop frames. We skip this check if
    113             // the timestamps are being auto-generated by Surface. If the app isn't
    114             // generating timestamps explicitly, it probably doesn't want frames to
    115             // be discarded based on them.
    116             while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
    117                 const BufferItem& bufferItem(mCore->mQueue[1]);
    118 
    119                 // If dropping entry[0] would leave us with a buffer that the
    120                 // consumer is not yet ready for, don't drop it.
    121                 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
    122                     break;
    123                 }
    124 
    125                 // If entry[1] is timely, drop entry[0] (and repeat). We apply an
    126                 // additional criterion here: we only drop the earlier buffer if our
    127                 // desiredPresent falls within +/- 1 second of the expected present.
    128                 // Otherwise, bogus desiredPresent times (e.g., 0 or a small
    129                 // relative timestamp), which normally mean "ignore the timestamp
    130                 // and acquire immediately", would cause us to drop frames.
    131                 //
    132                 // We may want to add an additional criterion: don't drop the
    133                 // earlier buffer if entry[1]'s fence hasn't signaled yet.
    134                 nsecs_t desiredPresent = bufferItem.mTimestamp;
    135                 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
    136                         desiredPresent > expectedPresent) {
    137                     // This buffer is set to display in the near future, or
    138                     // desiredPresent is garbage. Either way we don't want to drop
    139                     // the previous buffer just to get this on the screen sooner.
    140                     BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
    141                             PRId64 " (%" PRId64 ") now=%" PRId64,
    142                             desiredPresent, expectedPresent,
    143                             desiredPresent - expectedPresent,
    144                             systemTime(CLOCK_MONOTONIC));
    145                     break;
    146                 }
    147 
    148                 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
    149                         " size=%zu",
    150                         desiredPresent, expectedPresent, mCore->mQueue.size());
    151 
    152                 if (!front->mIsStale) {
    153                     // Front buffer is still in mSlots, so mark the slot as free
    154                     mSlots[front->mSlot].mBufferState.freeQueued();
    155 
    156                     // After leaving shared buffer mode, the shared buffer will
    157                     // still be around. Mark it as no longer shared if this
    158                     // operation causes it to be free.
    159                     if (!mCore->mSharedBufferMode &&
    160                             mSlots[front->mSlot].mBufferState.isFree()) {
    161                         mSlots[front->mSlot].mBufferState.mShared = false;
    162                     }
    163 
    164                     // Don't put the shared buffer on the free list
    165                     if (!mSlots[front->mSlot].mBufferState.isShared()) {
    166                         mCore->mActiveBuffers.erase(front->mSlot);
    167                         mCore->mFreeBuffers.push_back(front->mSlot);
    168                     }
    169 
    170                     listener = mCore->mConnectedProducerListener;
    171                     ++numDroppedBuffers;
    172                 }
    173 
    174                 mCore->mQueue.erase(front);
    175                 front = mCore->mQueue.begin();
    176             }
    177 
    178             // See if the front buffer is ready to be acquired
    179             nsecs_t desiredPresent = front->mTimestamp;
    180             bool bufferIsDue = desiredPresent <= expectedPresent ||
    181                     desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
    182             bool consumerIsReady = maxFrameNumber > 0 ?
    183                     front->mFrameNumber <= maxFrameNumber : true;
    184             if (!bufferIsDue || !consumerIsReady) {
    185                 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
    186                         " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
    187                         " consumer=%" PRIu64,
    188                         desiredPresent, expectedPresent,
    189                         desiredPresent - expectedPresent,
    190                         systemTime(CLOCK_MONOTONIC),
    191                         front->mFrameNumber, maxFrameNumber);
    192                 return PRESENT_LATER;
    193             }
    194 
    195             BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
    196                     "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
    197                     desiredPresent - expectedPresent,
    198                     systemTime(CLOCK_MONOTONIC));
    199         }
    200 
    201         int slot = BufferQueueCore::INVALID_BUFFER_SLOT;
    202 
    203         if (sharedBufferAvailable && mCore->mQueue.empty()) {
    204             // make sure the buffer has finished allocating before acquiring it
    205             mCore->waitWhileAllocatingLocked();
    206 
    207             slot = mCore->mSharedBufferSlot;
    208 
    209             // Recreate the BufferItem for the shared buffer from the data that
    210             // was cached when it was last queued.
    211             outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer;
    212             outBuffer->mFence = Fence::NO_FENCE;
    213             outBuffer->mFenceTime = FenceTime::NO_FENCE;
    214             outBuffer->mCrop = mCore->mSharedBufferCache.crop;
    215             outBuffer->mTransform = mCore->mSharedBufferCache.transform &
    216                     ~static_cast<uint32_t>(
    217                     NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
    218             outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode;
    219             outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace;
    220             outBuffer->mFrameNumber = mCore->mFrameCounter;
    221             outBuffer->mSlot = slot;
    222             outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled;
    223             outBuffer->mTransformToDisplayInverse =
    224                     (mCore->mSharedBufferCache.transform &
    225                     NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
    226             outBuffer->mSurfaceDamage = Region::INVALID_REGION;
    227             outBuffer->mQueuedBuffer = false;
    228             outBuffer->mIsStale = false;
    229             outBuffer->mAutoRefresh = mCore->mSharedBufferMode &&
    230                     mCore->mAutoRefresh;
    231         } else {
    232             slot = front->mSlot;
    233             *outBuffer = *front;
    234         }
    235 
    236         ATRACE_BUFFER_INDEX(slot);
    237 
    238         BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
    239                 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle);
    240 
    241         if (!outBuffer->mIsStale) {
    242             mSlots[slot].mAcquireCalled = true;
    243             // Don't decrease the queue count if the BufferItem wasn't
    244             // previously in the queue. This happens in shared buffer mode when
    245             // the queue is empty and the BufferItem is created above.
    246             if (mCore->mQueue.empty()) {
    247                 mSlots[slot].mBufferState.acquireNotInQueue();
    248             } else {
    249                 mSlots[slot].mBufferState.acquire();
    250             }
    251             mSlots[slot].mFence = Fence::NO_FENCE;
    252         }
    253 
    254         // If the buffer has previously been acquired by the consumer, set
    255         // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
    256         // on the consumer side
    257         if (outBuffer->mAcquireCalled) {
    258             outBuffer->mGraphicBuffer = NULL;
    259         }
    260 
    261         mCore->mQueue.erase(front);
    262 
    263         // We might have freed a slot while dropping old buffers, or the producer
    264         // may be blocked waiting for the number of buffers in the queue to
    265         // decrease.
    266         mCore->mDequeueCondition.broadcast();
    267 
    268         ATRACE_INT(mCore->mConsumerName.string(),
    269                 static_cast<int32_t>(mCore->mQueue.size()));
    270         mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
    271 
    272         VALIDATE_CONSISTENCY();
    273     }
    274 
    275     if (listener != NULL) {
    276         for (int i = 0; i < numDroppedBuffers; ++i) {
    277             listener->onBufferReleased();
    278         }
    279     }
    280 
    281     return NO_ERROR;
    282 }
    283 
    284 status_t BufferQueueConsumer::detachBuffer(int slot) {
    285     ATRACE_CALL();
    286     ATRACE_BUFFER_INDEX(slot);
    287     BQ_LOGV("detachBuffer: slot %d", slot);
    288     Mutex::Autolock lock(mCore->mMutex);
    289 
    290     if (mCore->mIsAbandoned) {
    291         BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
    292         return NO_INIT;
    293     }
    294 
    295     if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
    296         BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
    297         return BAD_VALUE;
    298     }
    299 
    300     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    301         BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
    302                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    303         return BAD_VALUE;
    304     } else if (!mSlots[slot].mBufferState.isAcquired()) {
    305         BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
    306                 "(state = %s)", slot, mSlots[slot].mBufferState.string());
    307         return BAD_VALUE;
    308     }
    309 
    310     mSlots[slot].mBufferState.detachConsumer();
    311     mCore->mActiveBuffers.erase(slot);
    312     mCore->mFreeSlots.insert(slot);
    313     mCore->clearBufferSlotLocked(slot);
    314     mCore->mDequeueCondition.broadcast();
    315     VALIDATE_CONSISTENCY();
    316 
    317     return NO_ERROR;
    318 }
    319 
    320 status_t BufferQueueConsumer::attachBuffer(int* outSlot,
    321         const sp<android::GraphicBuffer>& buffer) {
    322     ATRACE_CALL();
    323 
    324     if (outSlot == NULL) {
    325         BQ_LOGE("attachBuffer: outSlot must not be NULL");
    326         return BAD_VALUE;
    327     } else if (buffer == NULL) {
    328         BQ_LOGE("attachBuffer: cannot attach NULL buffer");
    329         return BAD_VALUE;
    330     }
    331 
    332     Mutex::Autolock lock(mCore->mMutex);
    333 
    334     if (mCore->mSharedBufferMode) {
    335         BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
    336         return BAD_VALUE;
    337     }
    338 
    339     // Make sure we don't have too many acquired buffers
    340     int numAcquiredBuffers = 0;
    341     for (int s : mCore->mActiveBuffers) {
    342         if (mSlots[s].mBufferState.isAcquired()) {
    343             ++numAcquiredBuffers;
    344         }
    345     }
    346 
    347     if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
    348         BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
    349                 "(max %d)", numAcquiredBuffers,
    350                 mCore->mMaxAcquiredBufferCount);
    351         return INVALID_OPERATION;
    352     }
    353 
    354     if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
    355         BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
    356                 "[queue %u]", buffer->getGenerationNumber(),
    357                 mCore->mGenerationNumber);
    358         return BAD_VALUE;
    359     }
    360 
    361     // Find a free slot to put the buffer into
    362     int found = BufferQueueCore::INVALID_BUFFER_SLOT;
    363     if (!mCore->mFreeSlots.empty()) {
    364         auto slot = mCore->mFreeSlots.begin();
    365         found = *slot;
    366         mCore->mFreeSlots.erase(slot);
    367     } else if (!mCore->mFreeBuffers.empty()) {
    368         found = mCore->mFreeBuffers.front();
    369         mCore->mFreeBuffers.remove(found);
    370     }
    371     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    372         BQ_LOGE("attachBuffer: could not find free buffer slot");
    373         return NO_MEMORY;
    374     }
    375 
    376     mCore->mActiveBuffers.insert(found);
    377     *outSlot = found;
    378     ATRACE_BUFFER_INDEX(*outSlot);
    379     BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
    380 
    381     mSlots[*outSlot].mGraphicBuffer = buffer;
    382     mSlots[*outSlot].mBufferState.attachConsumer();
    383     mSlots[*outSlot].mNeedsReallocation = true;
    384     mSlots[*outSlot].mFence = Fence::NO_FENCE;
    385     mSlots[*outSlot].mFrameNumber = 0;
    386 
    387     // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
    388     // GraphicBuffer pointer on the next acquireBuffer call, which decreases
    389     // Binder traffic by not un/flattening the GraphicBuffer. However, it
    390     // requires that the consumer maintain a cached copy of the slot <--> buffer
    391     // mappings, which is why the consumer doesn't need the valid pointer on
    392     // acquire.
    393     //
    394     // The StreamSplitter is one of the primary users of the attach/detach
    395     // logic, and while it is running, all buffers it acquires are immediately
    396     // detached, and all buffers it eventually releases are ones that were
    397     // attached (as opposed to having been obtained from acquireBuffer), so it
    398     // doesn't make sense to maintain the slot/buffer mappings, which would
    399     // become invalid for every buffer during detach/attach. By setting this to
    400     // false, the valid GraphicBuffer pointer will always be sent with acquire
    401     // for attached buffers.
    402     mSlots[*outSlot].mAcquireCalled = false;
    403 
    404     VALIDATE_CONSISTENCY();
    405 
    406     return NO_ERROR;
    407 }
    408 
    409 status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
    410         const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
    411         EGLSyncKHR eglFence) {
    412     ATRACE_CALL();
    413     ATRACE_BUFFER_INDEX(slot);
    414 
    415     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
    416             releaseFence == NULL) {
    417         BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
    418                 releaseFence.get());
    419         return BAD_VALUE;
    420     }
    421 
    422     sp<IProducerListener> listener;
    423     { // Autolock scope
    424         Mutex::Autolock lock(mCore->mMutex);
    425 
    426         // If the frame number has changed because the buffer has been reallocated,
    427         // we can ignore this releaseBuffer for the old buffer.
    428         // Ignore this for the shared buffer where the frame number can easily
    429         // get out of sync due to the buffer being queued and acquired at the
    430         // same time.
    431         if (frameNumber != mSlots[slot].mFrameNumber &&
    432                 !mSlots[slot].mBufferState.isShared()) {
    433             return STALE_BUFFER_SLOT;
    434         }
    435 
    436         if (!mSlots[slot].mBufferState.isAcquired()) {
    437             BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
    438                     "but its state was %s", slot,
    439                     mSlots[slot].mBufferState.string());
    440             return BAD_VALUE;
    441         }
    442 
    443         mSlots[slot].mEglDisplay = eglDisplay;
    444         mSlots[slot].mEglFence = eglFence;
    445         mSlots[slot].mFence = releaseFence;
    446         mSlots[slot].mBufferState.release();
    447 
    448         // After leaving shared buffer mode, the shared buffer will
    449         // still be around. Mark it as no longer shared if this
    450         // operation causes it to be free.
    451         if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
    452             mSlots[slot].mBufferState.mShared = false;
    453         }
    454         // Don't put the shared buffer on the free list.
    455         if (!mSlots[slot].mBufferState.isShared()) {
    456             mCore->mActiveBuffers.erase(slot);
    457             mCore->mFreeBuffers.push_back(slot);
    458         }
    459 
    460         listener = mCore->mConnectedProducerListener;
    461         BQ_LOGV("releaseBuffer: releasing slot %d", slot);
    462 
    463         mCore->mDequeueCondition.broadcast();
    464         VALIDATE_CONSISTENCY();
    465     } // Autolock scope
    466 
    467     // Call back without lock held
    468     if (listener != NULL) {
    469         listener->onBufferReleased();
    470     }
    471 
    472     return NO_ERROR;
    473 }
    474 
    475 status_t BufferQueueConsumer::connect(
    476         const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
    477     ATRACE_CALL();
    478 
    479     if (consumerListener == NULL) {
    480         BQ_LOGE("connect: consumerListener may not be NULL");
    481         return BAD_VALUE;
    482     }
    483 
    484     BQ_LOGV("connect: controlledByApp=%s",
    485             controlledByApp ? "true" : "false");
    486 
    487     Mutex::Autolock lock(mCore->mMutex);
    488 
    489     if (mCore->mIsAbandoned) {
    490         BQ_LOGE("connect: BufferQueue has been abandoned");
    491         return NO_INIT;
    492     }
    493 
    494     mCore->mConsumerListener = consumerListener;
    495     mCore->mConsumerControlledByApp = controlledByApp;
    496 
    497     return NO_ERROR;
    498 }
    499 
    500 status_t BufferQueueConsumer::disconnect() {
    501     ATRACE_CALL();
    502 
    503     BQ_LOGV("disconnect");
    504 
    505     Mutex::Autolock lock(mCore->mMutex);
    506 
    507     if (mCore->mConsumerListener == NULL) {
    508         BQ_LOGE("disconnect: no consumer is connected");
    509         return BAD_VALUE;
    510     }
    511 
    512     mCore->mIsAbandoned = true;
    513     mCore->mConsumerListener = NULL;
    514     mCore->mQueue.clear();
    515     mCore->freeAllBuffersLocked();
    516     mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
    517     mCore->mDequeueCondition.broadcast();
    518     return NO_ERROR;
    519 }
    520 
    521 status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
    522     ATRACE_CALL();
    523 
    524     if (outSlotMask == NULL) {
    525         BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
    526         return BAD_VALUE;
    527     }
    528 
    529     Mutex::Autolock lock(mCore->mMutex);
    530 
    531     if (mCore->mIsAbandoned) {
    532         BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
    533         return NO_INIT;
    534     }
    535 
    536     uint64_t mask = 0;
    537     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
    538         if (!mSlots[s].mAcquireCalled) {
    539             mask |= (1ULL << s);
    540         }
    541     }
    542 
    543     // Remove from the mask queued buffers for which acquire has been called,
    544     // since the consumer will not receive their buffer addresses and so must
    545     // retain their cached information
    546     BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
    547     while (current != mCore->mQueue.end()) {
    548         if (current->mAcquireCalled) {
    549             mask &= ~(1ULL << current->mSlot);
    550         }
    551         ++current;
    552     }
    553 
    554     BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
    555     *outSlotMask = mask;
    556     return NO_ERROR;
    557 }
    558 
    559 status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
    560         uint32_t height) {
    561     ATRACE_CALL();
    562 
    563     if (width == 0 || height == 0) {
    564         BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
    565                 "height=%u)", width, height);
    566         return BAD_VALUE;
    567     }
    568 
    569     BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
    570 
    571     Mutex::Autolock lock(mCore->mMutex);
    572     mCore->mDefaultWidth = width;
    573     mCore->mDefaultHeight = height;
    574     return NO_ERROR;
    575 }
    576 
    577 status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
    578     ATRACE_CALL();
    579 
    580     if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
    581         BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount);
    582         return BAD_VALUE;
    583     }
    584 
    585     Mutex::Autolock lock(mCore->mMutex);
    586 
    587     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
    588         BQ_LOGE("setMaxBufferCount: producer is already connected");
    589         return INVALID_OPERATION;
    590     }
    591 
    592     if (bufferCount < mCore->mMaxAcquiredBufferCount) {
    593         BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
    594                 "mMaxAcquiredBufferCount (%d)", bufferCount,
    595                 mCore->mMaxAcquiredBufferCount);
    596         return BAD_VALUE;
    597     }
    598 
    599     int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
    600             mCore->mDequeueBufferCannotBlock, bufferCount) -
    601             mCore->getMaxBufferCountLocked();
    602     if (!mCore->adjustAvailableSlotsLocked(delta)) {
    603         BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
    604                 "available slots. Delta = %d", delta);
    605         return BAD_VALUE;
    606     }
    607 
    608     mCore->mMaxBufferCount = bufferCount;
    609     return NO_ERROR;
    610 }
    611 
    612 status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
    613         int maxAcquiredBuffers) {
    614     ATRACE_CALL();
    615 
    616     if (maxAcquiredBuffers < 1 ||
    617             maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
    618         BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
    619                 maxAcquiredBuffers);
    620         return BAD_VALUE;
    621     }
    622 
    623     sp<IConsumerListener> listener;
    624     { // Autolock scope
    625         Mutex::Autolock lock(mCore->mMutex);
    626         mCore->waitWhileAllocatingLocked();
    627 
    628         if (mCore->mIsAbandoned) {
    629             BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
    630             return NO_INIT;
    631         }
    632 
    633         if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) {
    634             return NO_ERROR;
    635         }
    636 
    637         // The new maxAcquiredBuffers count should not be violated by the number
    638         // of currently acquired buffers
    639         int acquiredCount = 0;
    640         for (int slot : mCore->mActiveBuffers) {
    641             if (mSlots[slot].mBufferState.isAcquired()) {
    642                 acquiredCount++;
    643             }
    644         }
    645         if (acquiredCount > maxAcquiredBuffers) {
    646             BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer"
    647                     "count (%d) exceeds the current acquired buffer count (%d)",
    648                     maxAcquiredBuffers, acquiredCount);
    649             return BAD_VALUE;
    650         }
    651 
    652         if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount +
    653                 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0))
    654                 > mCore->mMaxBufferCount) {
    655             BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would "
    656                     "exceed the maxBufferCount (%d) (maxDequeued %d async %d)",
    657                     maxAcquiredBuffers, mCore->mMaxBufferCount,
    658                     mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode ||
    659                     mCore->mDequeueBufferCannotBlock);
    660             return BAD_VALUE;
    661         }
    662 
    663         int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
    664         if (!mCore->adjustAvailableSlotsLocked(delta)) {
    665             return BAD_VALUE;
    666         }
    667 
    668         BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
    669         mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
    670         VALIDATE_CONSISTENCY();
    671         if (delta < 0) {
    672             listener = mCore->mConsumerListener;
    673         }
    674     }
    675     // Call back without lock held
    676     if (listener != NULL) {
    677         listener->onBuffersReleased();
    678     }
    679 
    680     return NO_ERROR;
    681 }
    682 
    683 status_t BufferQueueConsumer::setConsumerName(const String8& name) {
    684     ATRACE_CALL();
    685     BQ_LOGV("setConsumerName: '%s'", name.string());
    686     Mutex::Autolock lock(mCore->mMutex);
    687     mCore->mConsumerName = name;
    688     mConsumerName = name;
    689     return NO_ERROR;
    690 }
    691 
    692 status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
    693     ATRACE_CALL();
    694     BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
    695     Mutex::Autolock lock(mCore->mMutex);
    696     mCore->mDefaultBufferFormat = defaultFormat;
    697     return NO_ERROR;
    698 }
    699 
    700 status_t BufferQueueConsumer::setDefaultBufferDataSpace(
    701         android_dataspace defaultDataSpace) {
    702     ATRACE_CALL();
    703     BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
    704     Mutex::Autolock lock(mCore->mMutex);
    705     mCore->mDefaultBufferDataSpace = defaultDataSpace;
    706     return NO_ERROR;
    707 }
    708 
    709 status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
    710     ATRACE_CALL();
    711     BQ_LOGV("setConsumerUsageBits: %#" PRIx64, usage);
    712     Mutex::Autolock lock(mCore->mMutex);
    713     mCore->mConsumerUsageBits = usage;
    714     return NO_ERROR;
    715 }
    716 
    717 status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
    718     ATRACE_CALL();
    719     BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
    720     Mutex::Autolock lock(mCore->mMutex);
    721     mCore->mConsumerIsProtected = isProtected;
    722     return NO_ERROR;
    723 }
    724 
    725 status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
    726     ATRACE_CALL();
    727     BQ_LOGV("setTransformHint: %#x", hint);
    728     Mutex::Autolock lock(mCore->mMutex);
    729     mCore->mTransformHint = hint;
    730     return NO_ERROR;
    731 }
    732 
    733 status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
    734     Mutex::Autolock lock(mCore->mMutex);
    735     *outStream = mCore->mSidebandStream;
    736     return NO_ERROR;
    737 }
    738 
    739 status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
    740         std::vector<OccupancyTracker::Segment>* outHistory) {
    741     Mutex::Autolock lock(mCore->mMutex);
    742     *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
    743     return NO_ERROR;
    744 }
    745 
    746 status_t BufferQueueConsumer::discardFreeBuffers() {
    747     Mutex::Autolock lock(mCore->mMutex);
    748     mCore->discardFreeBuffersLocked();
    749     return NO_ERROR;
    750 }
    751 
    752 status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const {
    753     struct passwd* pwd = getpwnam("shell");
    754     uid_t shellUid = pwd ? pwd->pw_uid : 0;
    755     if (!shellUid) {
    756         int savedErrno = errno;
    757         BQ_LOGE("Cannot get AID_SHELL");
    758         return savedErrno ? -savedErrno : UNKNOWN_ERROR;
    759     }
    760 
    761     const IPCThreadState* ipc = IPCThreadState::self();
    762     const uid_t uid = ipc->getCallingUid();
    763 #ifndef __ANDROID_VNDK__
    764     // permission check can't be done for vendors as vendors have no access to
    765     // the PermissionController
    766     const pid_t pid = ipc->getCallingPid();
    767     if ((uid != shellUid) &&
    768         !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
    769         outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
    770                 "from pid=%d, uid=%d\n", pid, uid);
    771 #else
    772     if (uid != shellUid) {
    773 #endif
    774         android_errorWriteWithInfoLog(0x534e4554, "27046057",
    775                 static_cast<int32_t>(uid), NULL, 0);
    776         return PERMISSION_DENIED;
    777     }
    778 
    779     mCore->dumpState(prefix, outResult);
    780     return NO_ERROR;
    781 }
    782 
    783 } // namespace android
    784