// acquireBuffer attempts to acquire ownership of the next pending buffer in
// the BufferQueue. If no buffer is pending then it returns
// NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the
// information about the buffer is returned in BufferItem.  If the buffer
// returned had previously been acquired then the BufferItem::mGraphicBuffer
// field of buffer is set to NULL and it is assumed that the consumer still
// holds a reference to the buffer.
//
// If expectedPresent is nonzero, it indicates the time when the buffer
// will be displayed on screen. If the buffer's timestamp is farther in the
// future, the buffer won't be acquired, and PRESENT_LATER will be
// returned.  The presentation time is in nanoseconds, and the time base
// is CLOCK_MONOTONIC.
status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
        nsecs_t expectedPresent, uint64_t maxFrameNumber)
int numDroppedBuffers = 0;
sp<IProducerListener> listener;

numDroppedBuffers 表示获取过程中丢弃的 buffer 数量。在函数最后如果 listener 不空,则会回调 numDroppedBuffers 次 onBufferReleased()

{
    std::unique_lock<std::mutex> lock(mCore->mMutex);

    // Check that the consumer doesn't currently have the maximum number of
    // buffers acquired. We allow the max buffer count to be exceeded by one
    // buffer so that the consumer can successfully set up the newly acquired
    // buffer before releasing the old one.
    int numAcquiredBuffers = 0;
    for (int s : mCore->mActiveBuffers) {
        if (mSlots[s].mBufferState.isAcquired()) {
            ++numAcquiredBuffers;
        }
    }
    if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
        BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
                numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
        return INVALID_OPERATION;
    }

计算 ACQUIRED buffer 数 numAcquiredBuffers。如果 numAcquiredBuffers 超过了 mMaxAcquiredBufferCount,则返回 INVALID_OPERATIONmMaxAcquiredBufferCount 默认值是 1,通过 setMaxAcquiredBufferCount() 修改。

    bool sharedBufferAvailable = mCore->mSharedBufferMode &&
            mCore->mAutoRefresh && mCore->mSharedBufferSlot !=
            BufferQueueCore::INVALID_BUFFER_SLOT;
    // In asynchronous mode the list is guaranteed to be one buffer deep,
    // while in synchronous mode we use the oldest buffer.
    if (mCore->mQueue.empty() && !sharedBufferAvailable) {
        return NO_BUFFER_AVAILABLE;
    }

如果 mQueue 空,且共享 buffer 不可用,则返回 NO_BUFFER_AVAILABLE

    BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
    // If expectedPresent is specified, we may not want to return a buffer yet.
    // If it's specified and there's more than one buffer queued, we may want
    // to drop a buffer.
    // Skip this if we're in shared buffer mode and the queue is empty,
    // since in that case we'll just return the shared buffer.
    if (expectedPresent != 0 && !mCore->mQueue.empty()) {

当指定了 expectedPresent 时,即期望显示时间,可能会存在多个满足条件的 buffer,这时我们会丢弃一些 buffer。

        // The 'expectedPresent' argument indicates when the buffer is expected
        // to be presented on-screen. If the buffer's desired present time is
        // earlier (less) than expectedPresent -- meaning it will be displayed
        // on time or possibly late if we show it as soon as possible -- we
        // acquire and return it. If we don't want to display it until after the
        // expectedPresent time, we return PRESENT_LATER without acquiring it.
        //
        // To be safe, we don't defer acquisition if expectedPresent is more
        // than one second in the future beyond the desired present time
        // (i.e., we'd be holding the buffer for a long time).
        //
        // NOTE: Code assumes monotonic time values from the system clock
        // are positive.

        // Start by checking to see if we can drop frames. We skip this check if
        // the timestamps are being auto-generated by Surface. If the app isn't
        // generating timestamps explicitly, it probably doesn't want frames to
        // be discarded based on them.
        while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {

expectedPresent 是消费者期望的 buffer 显示时间。BufferItem 有成员 mTimestamp 和 mIsAutoTimestamp