void BLASTBufferQueue::releaseBufferCallbackLocked(const ReleaseCallbackId& id,
const sp<Fence>& releaseFence, uint32_t transformHint,
uint32_t currentMaxAcquiredBufferCount) {
...
// Calculate how many buffers we need to hold before we release them back
// to the buffer queue. This will prevent higher latency when we are running
// on a lower refresh rate than the max supported. We only do that for EGL
// clients as others don't care about latency
const bool isEGL = [&] {
const auto it = mSubmitted.find(id);
return it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL;
}();
const auto numPendingBuffersToHold =
isEGL ? std::max(0u, mMaxAcquiredBuffers - currentMaxAcquiredBufferCount) : 0;
auto rb = ReleasedBuffer{id, releaseFence};
if (std::find(mPendingRelease.begin(), mPendingRelease.end(), rb) == mPendingRelease.end()) {
mPendingRelease.emplace_back(rb);
}
mApi
判断生产者是否是 EGL。mSubmitted
是在 BLASTBufferQueue::acquireNextBufferLocked() 中更新的。
- 如果是 EGL,则
numPendingBuffersToHold
是最大 acquired 数减去当前 currentMaxAcquiredBufferCount
。在 SurfaceFlinger 模块中 currentMaxAcquiredBufferCount
是 0。
- 创建一个 ReleaseBuffer 加入
mPendingRelease
。
// Release all buffers that are beyond the ones that we need to hold
while (mPendingRelease.size() > numPendingBuffersToHold) {
const auto releaseBuffer = mPendingRelease.front();
mPendingRelease.pop_front();
auto it = mSubmitted.find(releaseBuffer.callbackId);
if (it == mSubmitted.end()) {
BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %s",
releaseBuffer.callbackId.to_string().c_str());
return;
}
mNumAcquired--;
BQA_LOGV("released %s", id.to_string().c_str());
mBufferItemConsumer->releaseBuffer(it->second, releaseBuffer.releaseFence);
mSubmitted.erase(it);
// Don't process the transactions here if mWaitForTransactionCallback is set. Instead, let
// onFrameAvailable handle processing them since it will merge with the nextTransaction.
if (!mWaitForTransactionCallback) {
acquireNextBufferLocked(std::nullopt);
}
}
ATRACE_INT("PendingRelease", mPendingRelease.size());
ATRACE_INT(mQueuedBufferTrace.c_str(),
mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
mCallbackCV.notify_all();
}