diff options
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 139 | 
1 files changed, 87 insertions, 52 deletions
| diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index b7a7aa0ccb..8e23eb8766 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -137,6 +137,7 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati          mSize(1, 1),          mRequestedSize(mSize),          mFormat(PIXEL_FORMAT_RGBA_8888), +        mTransactionReadyCallback(nullptr),          mSyncTransaction(nullptr),          mUpdateDestinationFrame(updateDestinationFrame) {      createBufferQueue(&mProducer, &mConsumer); @@ -608,60 +609,69 @@ void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& l  }  void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { -    BBQ_TRACE(); -    std::unique_lock _lock{mMutex}; +    std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr; +    SurfaceComposerClient::Transaction* prevTransaction = nullptr; +    { +        BBQ_TRACE(); +        std::unique_lock _lock{mMutex}; +        const bool syncTransactionSet = mTransactionReadyCallback != nullptr; +        BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet)); + +        if (syncTransactionSet) { +            bool mayNeedToWaitForBuffer = true; +            // If we are going to re-use the same mSyncTransaction, release the buffer that may +            // already be set in the Transaction. This is to allow us a free slot early to continue +            // processing a new buffer. +            if (!mAcquireSingleBuffer) { +                auto bufferData = mSyncTransaction->getAndClearBuffer(mSurfaceControl); +                if (bufferData) { +                    BQA_LOGD("Releasing previous buffer when syncing: framenumber=%" PRIu64, +                             bufferData->frameNumber); +                    releaseBuffer(bufferData->generateReleaseCallbackId(), +                                  bufferData->acquireFence); +                    // Because we just released a buffer, we know there's no need to wait for a free +                    // buffer. +                    mayNeedToWaitForBuffer = false; +                } +            } -    const bool syncTransactionSet = mSyncTransaction != nullptr; -    BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet)); - -    if (syncTransactionSet) { -        bool mayNeedToWaitForBuffer = true; -        // If we are going to re-use the same mSyncTransaction, release the buffer that may already -        // be set in the Transaction. This is to allow us a free slot early to continue processing -        // a new buffer. -        if (!mAcquireSingleBuffer) { -            auto bufferData = mSyncTransaction->getAndClearBuffer(mSurfaceControl); -            if (bufferData) { -                BQA_LOGD("Releasing previous buffer when syncing: framenumber=%" PRIu64, -                         bufferData->frameNumber); -                releaseBuffer(bufferData->generateReleaseCallbackId(), bufferData->acquireFence); -                // Because we just released a buffer, we know there's no need to wait for a free -                // buffer. -                mayNeedToWaitForBuffer = false; +            if (mayNeedToWaitForBuffer) { +                flushAndWaitForFreeBuffer(_lock);              }          } -        if (mayNeedToWaitForBuffer) { -            flushAndWaitForFreeBuffer(_lock); +        // add to shadow queue +        mNumFrameAvailable++; +        if (mWaitForTransactionCallback && mNumFrameAvailable >= 2) { +            acquireAndReleaseBuffer();          } -    } - -    // add to shadow queue -    mNumFrameAvailable++; -    if (mWaitForTransactionCallback && mNumFrameAvailable >= 2) { -        acquireAndReleaseBuffer(); -    } -    ATRACE_INT(mQueuedBufferTrace.c_str(), -               mNumFrameAvailable + mNumAcquired - mPendingRelease.size()); - -    BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " syncTransactionSet=%s", item.mFrameNumber, -             boolToString(syncTransactionSet)); - -    if (syncTransactionSet) { -        acquireNextBufferLocked(mSyncTransaction); - -        // Only need a commit callback when syncing to ensure the buffer that's synced has been sent -        // to SF -        incStrong((void*)transactionCommittedCallbackThunk); -        mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk, -                                                          static_cast<void*>(this)); - -        if (mAcquireSingleBuffer) { -            mSyncTransaction = nullptr; +        ATRACE_INT(mQueuedBufferTrace.c_str(), +                   mNumFrameAvailable + mNumAcquired - mPendingRelease.size()); + +        BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " syncTransactionSet=%s", +                 item.mFrameNumber, boolToString(syncTransactionSet)); + +        if (syncTransactionSet) { +            acquireNextBufferLocked(mSyncTransaction); + +            // Only need a commit callback when syncing to ensure the buffer that's synced has been +            // sent to SF +            incStrong((void*)transactionCommittedCallbackThunk); +            mSyncTransaction->addTransactionCommittedCallback(transactionCommittedCallbackThunk, +                                                              static_cast<void*>(this)); +            mWaitForTransactionCallback = true; +            if (mAcquireSingleBuffer) { +                prevCallback = mTransactionReadyCallback; +                prevTransaction = mSyncTransaction; +                mTransactionReadyCallback = nullptr; +                mSyncTransaction = nullptr; +            } +        } else if (!mWaitForTransactionCallback) { +            acquireNextBufferLocked(std::nullopt);          } -        mWaitForTransactionCallback = true; -    } else if (!mWaitForTransactionCallback) { -        acquireNextBufferLocked(std::nullopt); +    } +    if (prevCallback) { +        prevCallback(prevTransaction);      }  } @@ -680,12 +690,37 @@ void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {      mDequeueTimestamps.erase(bufferId);  }; -void BLASTBufferQueue::setSyncTransaction(SurfaceComposerClient::Transaction* t, -                                          bool acquireSingleBuffer) { +void BLASTBufferQueue::syncNextTransaction( +        std::function<void(SurfaceComposerClient::Transaction*)> callback, +        bool acquireSingleBuffer) {      BBQ_TRACE();      std::lock_guard _lock{mMutex}; -    mSyncTransaction = t; -    mAcquireSingleBuffer = mSyncTransaction ? acquireSingleBuffer : true; +    mTransactionReadyCallback = callback; +    if (callback) { +        mSyncTransaction = new SurfaceComposerClient::Transaction(); +    } else { +        mSyncTransaction = nullptr; +    } +    mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true; +} + +void BLASTBufferQueue::stopContinuousSyncTransaction() { +    std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr; +    SurfaceComposerClient::Transaction* prevTransaction = nullptr; +    { +        std::lock_guard _lock{mMutex}; +        bool invokeCallback = mTransactionReadyCallback && !mAcquireSingleBuffer; +        if (invokeCallback) { +            prevCallback = mTransactionReadyCallback; +            prevTransaction = mSyncTransaction; +        } +        mTransactionReadyCallback = nullptr; +        mSyncTransaction = nullptr; +        mAcquireSingleBuffer = true; +    } +    if (prevCallback) { +        prevCallback(prevTransaction); +    }  }  bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { |