Loading libs/gui/BLASTBufferQueue.cpp +153 −20 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ #include <private/gui/ComposerServiceAIDL.h> #include <android-base/thread_annotations.h> #include <chrono> #include <com_android_graphics_libgui_flags.h> Loading Loading @@ -179,8 +178,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati // explicitly so that dequeueBuffer will block mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max()); // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE, Loading Loading @@ -236,6 +233,11 @@ BLASTBufferQueue::~BLASTBufferQueue() { } } void BLASTBufferQueue::onFirstRef() { // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format) { LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL"); Loading Loading @@ -499,7 +501,13 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId, callbackId.to_string().c_str()); return; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) if (!it->second.mIsStale) { mNumAcquired--; } #else mNumAcquired--; #endif BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber); BQA_LOGV("released %s", callbackId.to_string().c_str()); mBufferItemConsumer->releaseBuffer(it->second, releaseFence); Loading Loading @@ -761,6 +769,9 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { } // add to shadow queue #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) mNumDequeued--; #endif mNumFrameAvailable++; if (waitForTransactionCallback && mNumFrameAvailable >= 2) { acquireAndReleaseBuffer(); Loading Loading @@ -815,9 +826,18 @@ void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) { }; void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) { { std::lock_guard _lock{mTimestampMutex}; mDequeueTimestamps.erase(bufferId); }; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) { std::lock_guard lock{mMutex}; mNumDequeued--; } #endif } bool BLASTBufferQueue::syncNextTransaction( std::function<void(SurfaceComposerClient::Transaction*)> callback, Loading Loading @@ -1116,30 +1136,143 @@ public: producerControlledByApp, output); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) status_t disconnect(int api, DisconnectMode mode) override { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return BufferQueueProducer::disconnect(api, mode); } std::lock_guard lock{bbq->mMutex}; if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) { return status; } bbq->mNumDequeued = 0; bbq->mNumAcquired = 0; for (auto& [releaseId, bufferItem] : bbq->mSubmitted) { bufferItem.mIsStale = true; } return OK; } status_t setAsyncMode(bool asyncMode) override { if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mAsyncMode = asyncMode; } return OK; } status_t setSharedBufferMode(bool sharedBufferMode) override { if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mSharedBufferMode = sharedBufferMode; } return OK; } status_t detachBuffer(int slot) override { if (status_t status = BufferQueueProducer::detachBuffer(slot); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued--; } return OK; } status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height, PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) override { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage, outBufferAge, outTimestamps); } { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued++; } status_t status = BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage, outBufferAge, outTimestamps); if (status < 0) { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued--; } return status; } #endif // We want to resize the frame history when changing the size of the buffer queue status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override { int maxBufferCount; status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount, if (status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount, &maxBufferCount); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } // if we can't determine the max buffer count, then just skip growing the history size if (status == OK) { size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering // optimize away resizing the frame history unless it will grow if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (bbq != nullptr) { ALOGV("increasing frame history size to %zu", newFrameHistorySize); bbq->resizeFrameEventHistory(newFrameHistorySize); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) { std::lock_guard lock{bbq->mMutex}; bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount; } } return status; #endif return OK; } int query(int what, int* value) override { if (what == NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER) { *value = 1; return NO_ERROR; return OK; } return BufferQueueProducer::query(what, value); } Loading libs/gui/include/gui/BLASTBufferQueue.h +11 −2 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ #include <utils/RefBase.h> #include <system/window.h> #include <thread> #include <queue> #include <com_android_graphics_libgui_flags.h> Loading Loading @@ -131,6 +130,8 @@ public: virtual ~BLASTBufferQueue(); void onFirstRef() override; private: friend class BLASTBufferQueueHelper; friend class BBQBufferQueueProducer; Loading Loading @@ -170,8 +171,16 @@ private: // BufferQueue internally allows 1 more than // the max to be acquired int32_t mMaxAcquiredBuffers = 1; int32_t mMaxAcquiredBuffers GUARDED_BY(mMutex) = 1; #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) int32_t mMaxDequeuedBuffers GUARDED_BY(mMutex) = 1; static constexpr int32_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS; bool mAsyncMode GUARDED_BY(mMutex) = false; bool mSharedBufferMode GUARDED_BY(mMutex) = false; int32_t mNumDequeued GUARDED_BY(mMutex) = 0; #endif int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0; int32_t mNumAcquired GUARDED_BY(mMutex) = 0; Loading Loading
libs/gui/BLASTBufferQueue.cpp +153 −20 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ #include <private/gui/ComposerServiceAIDL.h> #include <android-base/thread_annotations.h> #include <chrono> #include <com_android_graphics_libgui_flags.h> Loading Loading @@ -179,8 +178,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati // explicitly so that dequeueBuffer will block mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max()); // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE, Loading Loading @@ -236,6 +233,11 @@ BLASTBufferQueue::~BLASTBufferQueue() { } } void BLASTBufferQueue::onFirstRef() { // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format) { LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL"); Loading Loading @@ -499,7 +501,13 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId, callbackId.to_string().c_str()); return; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) if (!it->second.mIsStale) { mNumAcquired--; } #else mNumAcquired--; #endif BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber); BQA_LOGV("released %s", callbackId.to_string().c_str()); mBufferItemConsumer->releaseBuffer(it->second, releaseFence); Loading Loading @@ -761,6 +769,9 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { } // add to shadow queue #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) mNumDequeued--; #endif mNumFrameAvailable++; if (waitForTransactionCallback && mNumFrameAvailable >= 2) { acquireAndReleaseBuffer(); Loading Loading @@ -815,9 +826,18 @@ void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) { }; void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) { { std::lock_guard _lock{mTimestampMutex}; mDequeueTimestamps.erase(bufferId); }; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) { std::lock_guard lock{mMutex}; mNumDequeued--; } #endif } bool BLASTBufferQueue::syncNextTransaction( std::function<void(SurfaceComposerClient::Transaction*)> callback, Loading Loading @@ -1116,30 +1136,143 @@ public: producerControlledByApp, output); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) status_t disconnect(int api, DisconnectMode mode) override { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return BufferQueueProducer::disconnect(api, mode); } std::lock_guard lock{bbq->mMutex}; if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) { return status; } bbq->mNumDequeued = 0; bbq->mNumAcquired = 0; for (auto& [releaseId, bufferItem] : bbq->mSubmitted) { bufferItem.mIsStale = true; } return OK; } status_t setAsyncMode(bool asyncMode) override { if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mAsyncMode = asyncMode; } return OK; } status_t setSharedBufferMode(bool sharedBufferMode) override { if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mSharedBufferMode = sharedBufferMode; } return OK; } status_t detachBuffer(int slot) override { if (status_t status = BufferQueueProducer::detachBuffer(slot); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued--; } return OK; } status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height, PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) override { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage, outBufferAge, outTimestamps); } { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued++; } status_t status = BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage, outBufferAge, outTimestamps); if (status < 0) { std::lock_guard lock{bbq->mMutex}; bbq->mNumDequeued--; } return status; } #endif // We want to resize the frame history when changing the size of the buffer queue status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override { int maxBufferCount; status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount, if (status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount, &maxBufferCount); status != OK) { return status; } sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } // if we can't determine the max buffer count, then just skip growing the history size if (status == OK) { size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering // optimize away resizing the frame history unless it will grow if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) { sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (bbq != nullptr) { ALOGV("increasing frame history size to %zu", newFrameHistorySize); bbq->resizeFrameEventHistory(newFrameHistorySize); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) { std::lock_guard lock{bbq->mMutex}; bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount; } } return status; #endif return OK; } int query(int what, int* value) override { if (what == NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER) { *value = 1; return NO_ERROR; return OK; } return BufferQueueProducer::query(what, value); } Loading
libs/gui/include/gui/BLASTBufferQueue.h +11 −2 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ #include <utils/RefBase.h> #include <system/window.h> #include <thread> #include <queue> #include <com_android_graphics_libgui_flags.h> Loading Loading @@ -131,6 +130,8 @@ public: virtual ~BLASTBufferQueue(); void onFirstRef() override; private: friend class BLASTBufferQueueHelper; friend class BBQBufferQueueProducer; Loading Loading @@ -170,8 +171,16 @@ private: // BufferQueue internally allows 1 more than // the max to be acquired int32_t mMaxAcquiredBuffers = 1; int32_t mMaxAcquiredBuffers GUARDED_BY(mMutex) = 1; #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) int32_t mMaxDequeuedBuffers GUARDED_BY(mMutex) = 1; static constexpr int32_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS; bool mAsyncMode GUARDED_BY(mMutex) = false; bool mSharedBufferMode GUARDED_BY(mMutex) = false; int32_t mNumDequeued GUARDED_BY(mMutex) = 0; #endif int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0; int32_t mNumAcquired GUARDED_BY(mMutex) = 0; Loading