// 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)
NO_BUFFER_AVAILABLE
。否则返回到 outBuffer
。mGraphicBuffer
指向空,因为假定了消费者会缓存 mGraphicBuffer
引用。exptectedPresent
是非零,它表示 buffer 将显示到屏幕上的时间,它的单位是纳秒。如果 buffer 的时间戳在更远的未来,则返回 PRESENT_LATER
。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_OPERATION
。mMaxAcquiredBufferCount
默认值是 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
:
mIsAutoTimestamp
是 true
表示 mTimestamp
是调用 BufferQueueProducer::dequeueBuffer() 的时间戳。它同时表示生产者不希望丢弃 buffer。