frameworks/native/libs/gui/BufferQueueProducer.cpp
831 status_t BufferQueueProducer::queueBuffer(int slot,
832 const QueueBufferInput &input, QueueBufferOutput *output) {
1061 addAndGetFrameTimestamps(&newFrameEventsEntry,
1062 getFrameTimestamps ? &output->frameTimestamps : nullptr);
1075
1076 if (frameAvailableListener != nullptr) {
1077 frameAvailableListener->onFrameAvailable(item);
1078 } else if (frameReplacedListener != nullptr) {
1079 frameReplacedListener->onFrameReplaced(item);
1080 }
android::BufferQueueConsumer::acquireBuffer BufferQueueConsumer.cpp:85
android::ConsumerBase::acquireBufferLocked ConsumerBase.cpp:392
android::BufferItemConsumer::acquireBuffer BufferItemConsumer.cpp:66
android::BLASTBufferQueue::acquireNextBufferLocked BLASTBufferQueue.cpp:474
android::BLASTBufferQueue::onFrameAvailable BLASTBufferQueue.cpp:694
android::ConsumerBase::onFrameAvailable ConsumerBase.cpp:157
android::BufferQueue::ProxyConsumerListener::onFrameAvailable BufferQueue.cpp:71
android::BufferQueueProducer::queueBuffer BufferQueueProducer.cpp:1054
android::Surface::queueBuffer Surface.cpp:1190
/frameworks/native/libs/gui/BufferQueue.cpp
62 void BufferQueue::ProxyConsumerListener::onFrameAvailable(
63 const BufferItem& item) {
64 sp listener(mConsumerListener.promote());
65 if (listener != nullptr) {
66 listener->onFrameAvailable(item);
67 }
68 }
/frameworks/native/libs/gui/ConsumerBase.cpp
146 void ConsumerBase::onFrameAvailable(const BufferItem& item) {
147 CB_LOGV("onFrameAvailable");
148
149 sp listener;
150 { // scope for the lock
151 Mutex::Autolock lock(mFrameAvailableMutex);
152 listener = mFrameAvailableListener.promote();
153 }
154
155 if (listener != nullptr) {
156 CB_LOGV("actually calling onFrameAvailable");
157 listener->onFrameAvailable(item);
158 }
159 }
追溯下此listen的历史
/frameworks/native/libs/gui/ConsumerBase.cpp
237 void ConsumerBase::setFrameAvailableListener(
238 const wp& listener) {
239 CB_LOGV("setFrameAvailableListener");
240 Mutex::Autolock lock(mFrameAvailableMutex);
241 mFrameAvailableListener = listener;
242 }
147 BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
148 : mSurfaceControl(nullptr),
149 mSize(1, 1),
150 mRequestedSize(mSize),
151 mFormat(PIXEL_FORMAT_RGBA_8888),
152 mTransactionReadyCallback(nullptr),
153 mSyncTransaction(nullptr),
154 mUpdateDestinationFrame(updateDestinationFrame) {
172 mBufferItemConsumer->setFrameAvailableListener(this);
173
/frameworks/native/libs/gui/BLASTBufferQueue.cpp
696 void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
697 std::function prevCallback = nullptr;
698 SurfaceComposerClient::Transaction* prevTransaction = nullptr;
699
700 {
701 UNIQUE_LOCK_WITH_ASSERTION(mMutex);
702 BBQ_TRACE();
703 bool waitForTransactionCallback = !mSyncedFrameNumbers.empty();
704
705 const bool syncTransactionSet = mTransactionReadyCallback != nullptr;
706 BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));
707
708 if (syncTransactionSet) {
709 // If we are going to re-use the same mSyncTransaction, release the buffer that may
710 // already be set in the Transaction. This is to allow us a free slot early to continue
711 // processing a new buffer.
712 if (!mAcquireSingleBuffer) {
713 auto bufferData = mSyncTransaction->getAndClearBuffer(mSurfaceControl);
714 if (bufferData) {
715 BQA_LOGD("Releasing previous buffer when syncing: framenumber=%" PRIu64,
716 bufferData->frameNumber);
717 releaseBuffer(bufferData->generateReleaseCallbackId(),
718 bufferData->acquireFence);
719 }
720 }
721
722 if (waitForTransactionCallback) {
723 // We are waiting on a previous sync's transaction callback so allow another sync
724 // transaction to proceed.
725 //
726 // We need to first flush out the transactions that were in between the two syncs.
727 // We do this by merging them into mSyncTransaction so any buffer merging will get
728 // a release callback invoked.
729 while (mNumFrameAvailable > 0) {
730 // flush out the shadow queue
731 acquireAndReleaseBuffer();
732 }
733 } else {
734 // Make sure the frame available count is 0 before proceeding with a sync to ensure
735 // the correct frame is used for the sync. The only way mNumFrameAvailable would be
736 // greater than 0 is if we already ran out of buffers previously. This means we
737 // need to flush the buffers before proceeding with the sync.
738 while (mNumFrameAvailable > 0) {
739 BQA_LOGD("waiting until no queued buffers");
740 mCallbackCV.wait(_lock);
741 }
742 }
743 }
744
745 // add to shadow queue
746 mNumFrameAvailable++;
747 if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
748 acquireAndReleaseBuffer();
749 }
750 ATRACE_INT(mQueuedBufferTrace.c_str(),
751 mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
752
753 BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " syncTransactionSet=%s",
754 item.mFrameNumber, boolToString(syncTransactionSet));
755
756 if (syncTransactionSet) {
757 // Add to mSyncedFrameNumbers before waiting in case any buffers are released
758 // while waiting for a free buffer. The release and commit callback will try to
759 // acquire buffers if there are any available, but we don't want it to acquire
760 // in the case where a sync transaction wants the buffer.
761 mSyncedFrameNumbers.emplace(item.mFrameNumber);
762 // If there's no available buffer and we're in a sync transaction, we need to wait
763 // instead of returning since we guarantee a buffer will be acquired for the sync.
764 while (acquireNextBufferLocked(mSyncTransaction) == BufferQueue::NO_BUFFER_AVAILABLE) {
765 BQA_LOGD("waiting for available buffer");
766 mCallbackCV.wait(_lock);
767 }
768
769 // Only need a commit callback when syncing to ensure the buffer that's synced has been
770 // sent to SF
771 incStrong((void*)transactionCommittedCallbackThunk);
772 mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk,
773 static_cast(this));
774 if (mAcquireSingleBuffer) {
775 prevCallback = mTransactionReadyCallback;
776 prevTransaction = mSyncTransaction;
777 mTransactionReadyCallback = nullptr;
778 mSyncTransaction = nullptr;
779 }
780 } else if (!waitForTransactionCallback) {
781 acquireNextBufferLocked(std::nullopt);
782 }
783 }
784 if (prevCallback) {
785 prevCallback(prevTransaction);
786 }
787 }
505 status_t BLASTBufferQueue::acquireNextBufferLocked(
506 const std::optional transaction) {
507 // Check if we have frames available and we have not acquired the maximum number of buffers.
508 // Even with this check, the consumer can fail to acquire an additional buffer if the consumer
509 // has already acquired (mMaxAcquiredBuffers + 1) and the new buffer is not droppable. In this
510 // case mBufferItemConsumer->acquireBuffer will return with NO_BUFFER_AVAILABLE.
511 if (mNumFrameAvailable == 0) {
512 BQA_LOGV("Can't acquire next buffer. No available frames");
513 return BufferQueue::NO_BUFFER_AVAILABLE;
514 }
515
516 if (mNumAcquired >= (mMaxAcquiredBuffers + 2)) {
517 BQA_LOGV("Can't acquire next buffer. Already acquired max frames %d max:%d + 2",
518 mNumAcquired, mMaxAcquiredBuffers);
519 return BufferQueue::NO_BUFFER_AVAILABLE;
520 }
521
522 if (mSurfaceControl == nullptr) {
523 BQA_LOGE("ERROR : surface control is null");
524 return NAME_NOT_FOUND;
525 }
526
527 SurfaceComposerClient::Transaction localTransaction;
528 bool applyTransaction = true;
529 SurfaceComposerClient::Transaction* t = &localTransaction;
530 if (transaction) {
531 t = *transaction;
532 applyTransaction = false;
533 }
534
535 BufferItem bufferItem;
536
537 status_t status =
538 mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
539 if (status == BufferQueue::NO_BUFFER_AVAILABLE) {
540 BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE");
541 return status;
542 } else if (status != OK) {
543 BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str());
544 return status;
545 }
546
547 auto buffer = bufferItem.mGraphicBuffer;
548 mNumFrameAvailable--;
549 BBQ_TRACE("frame=%" PRIu64, bufferItem.mFrameNumber);
550
551 if (buffer == nullptr) {
552 mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
553 BQA_LOGE("Buffer was empty");
554 return BAD_VALUE;
555 }
556
557 if (rejectBuffer(bufferItem)) {
558 BQA_LOGE("rejecting buffer:active_size=%dx%d, requested_size=%dx%d "
559 "buffer{size=%dx%d transform=%d}",
560 mSize.width, mSize.height, mRequestedSize.width, mRequestedSize.height,
561 buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform);
562 mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
563 return acquireNextBufferLocked(transaction);
564 }
565
566 mNumAcquired++;
567 mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
568 ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
569 mSubmitted[releaseCallbackId] = bufferItem;
570
571 bool needsDisconnect = false;
572 mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect);
573
574 // if producer disconnected before, notify SurfaceFlinger
575 if (needsDisconnect) {
576 t->notifyProducerDisconnect(mSurfaceControl);
577 }
578
579 // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback.
580 incStrong((void*)transactionCallbackThunk);
581
582 // Only update mSize for destination bounds if the incoming buffer matches the requested size.
583 // Otherwise, it could cause stretching since the destination bounds will update before the
584 // buffer with the new size is acquired.
585 if (mRequestedSize == getBufferSize(bufferItem) ||
586 bufferItem.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
587 mSize = mRequestedSize;
588 }
589 Rect crop = computeCrop(bufferItem);
590 mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(),
591 bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform,
592 bufferItem.mScalingMode, crop);
593
594 auto releaseBufferCallback =
595 std::bind(releaseBufferCallbackThunk, wp(this) /* callbackContext */,
596 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
597 sp fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE;
598 t->setBuffer(mSurfaceControl, buffer, fence, bufferItem.mFrameNumber, mProducerId,
599 releaseBufferCallback);
600 t->setDataspace(mSurfaceControl, static_cast(bufferItem.mDataSpace));
601 t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
602 t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage);
603 t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast(this));
604
605 mSurfaceControlsWithPendingCallback.push(mSurfaceControl);
606
607 if (mUpdateDestinationFrame) {
608 t->setDestinationFrame(mSurfaceControl, Rect(mSize));
609 } else {
610 const bool ignoreDestinationFrame =
611 bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE;
612 t->setFlags(mSurfaceControl,
613 ignoreDestinationFrame ? layer_state_t::eIgnoreDestinationFrame : 0,
614 layer_state_t::eIgnoreDestinationFrame);
615 }
616 t->setBufferCrop(mSurfaceControl, crop);
617 t->setTransform(mSurfaceControl, bufferItem.mTransform);
618 t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
619 t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
620 if (!bufferItem.mIsAutoTimestamp) {
621 t->setDesiredPresentTime(bufferItem.mTimestamp);
622 }
623
624 // Drop stale frame timeline infos
625 while (!mPendingFrameTimelines.empty() &&
626 mPendingFrameTimelines.front().first < bufferItem.mFrameNumber) {
627 ATRACE_FORMAT_INSTANT("dropping stale frameNumber: %" PRIu64 " vsyncId: %" PRId64,
628 mPendingFrameTimelines.front().first,
629 mPendingFrameTimelines.front().second.vsyncId);
630 mPendingFrameTimelines.pop();
631 }
632
633 if (!mPendingFrameTimelines.empty() &&
634 mPendingFrameTimelines.front().first == bufferItem.mFrameNumber) {
635 ATRACE_FORMAT_INSTANT("Transaction::setFrameTimelineInfo frameNumber: %" PRIu64
636 " vsyncId: %" PRId64,
637 bufferItem.mFrameNumber,
638 mPendingFrameTimelines.front().second.vsyncId);
639 t->setFrameTimelineInfo(mPendingFrameTimelines.front().second);
640 mPendingFrameTimelines.pop();
641 }
642
643 {
644 std::lock_guard _lock{mTimestampMutex};
645 auto dequeueTime = mDequeueTimestamps.find(buffer->getId());
646 if (dequeueTime != mDequeueTimestamps.end()) {
647 Parcel p;
648 p.writeInt64(dequeueTime->second);
649 t->setMetadata(mSurfaceControl, gui::METADATA_DEQUEUE_TIME, p);
650 mDequeueTimestamps.erase(dequeueTime);
651 }
652 }
653
654 mergePendingTransactions(t, bufferItem.mFrameNumber);
655 if (applyTransaction) {
656 // All transactions on our apply token are one-way. See comment on mAppliedLastTransaction
657 t->setApplyToken(mApplyToken).apply(false, true);
658 mAppliedLastTransaction = true;
659 mLastAppliedFrameNumber = bufferItem.mFrameNumber;
660 } else {
661 t->setBufferHasBarrier(mSurfaceControl, mLastAppliedFrameNumber);
662 mAppliedLastTransaction = false;
663 }
664
665 BQA_LOGV("acquireNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
666 " applyTransaction=%s mTimestamp=%" PRId64 "%s mPendingTransactions.size=%d"
667 " graphicBufferId=%" PRIu64 "%s transform=%d",
668 mSize.width, mSize.height, bufferItem.mFrameNumber, boolToString(applyTransaction),
669 bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "",
670 static_cast(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(),
671 bufferItem.mAutoRefresh ? " mAutoRefresh" : "", bufferItem.mTransform);
672 return OK;
673 }
frameworks/native/libs/gui/BufferItemConsumer.cpp
58 status_t BufferItemConsumer::acquireBuffer(BufferItem *item,
59 nsecs_t presentWhen, bool waitForFence) {
60 status_t err;
61
62 if (!item) return BAD_VALUE;
63
64 Mutex::Autolock _l(mMutex);
65
66 err = acquireBufferLocked(item, presentWhen);
67 if (err != OK) {
68 if (err != NO_BUFFER_AVAILABLE) {
69 BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
70 }
71 return err;
72 }
73
74 if (waitForFence) {
75 err = item->mFence->waitForever("BufferItemConsumer::acquireBuffer");
76 if (err != OK) {
77 BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
78 strerror(-err), err);
79 return err;
80 }
81 }
82
83 item->mGraphicBuffer = mSlots[item->mSlot].mGraphicBuffer;
84
85
/frameworks/native/libs/gui/ConsumerBase.cpp
385 status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
386 nsecs_t presentWhen, uint64_t maxFrameNumber) {
387 if (mAbandoned) {
388 CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");
389 return NO_INIT;
390 }
391
392 status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
393 if (err != NO_ERROR) {
394 return err;
395 }
396
397 if (item->mGraphicBuffer != nullptr) {
398 if (mSlots[item->mSlot].mGraphicBuffer != nullptr) {
399 freeBufferLocked(item->mSlot);
400 }
401 mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
402 }
403
404 mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
405 mSlots[item->mSlot].mFence = item->mFence;
406
407 CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
408 item->mSlot, item->mFrameNumber);
409
410 return OK;
411 }
frameworks/native/libs/gui/BufferQueueConsumer.cpp
79 status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
80 nsecs_t expectedPresent, uint64_t maxFrameNumber) {
BLASTBufferQueue::queueBuffer 成功后,通过 listener->addAndGetFrameTimestamps 通知Queue成功时间
/frameworks/native/libs/gui/BufferQueueProducer.cpp
1675 void BufferQueueProducer::addAndGetFrameTimestamps(
1676 const NewFrameEventsEntry* newTimestamps,
1677 FrameEventHistoryDelta* outDelta) {
1678 if (newTimestamps == nullptr && outDelta == nullptr) {
1679 return;
1680 }
1681
1682 ATRACE_CALL();
1683 BQ_LOGV("addAndGetFrameTimestamps");
1684 sp listener;
1685 {
1686 std::lock_guard lock(mCore->mMutex);
1687 listener = mCore->mConsumerListener;
1688 }
1689 if (listener != nullptr) {
1690 listener->addAndGetFrameTimestamps(newTimestamps, outDelta);
1691 }
1692 }