Loading libs/gui/BLASTBufferQueue.cpp +42 −14 Original line number Diff line number Diff line Loading @@ -29,9 +29,10 @@ #include <gui/IProducerListener.h> #include <gui/Surface.h> #include <utils/Singleton.h> #include <utils/Trace.h> #include <private/gui/ComposerService.h> #include <chrono> using namespace std::chrono_literals; Loading Loading @@ -158,6 +159,9 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format)); mBufferItemConsumer->setBlastBufferQueue(this); ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers); mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers); mTransformHint = mSurfaceControl->getTransformHint(); mBufferItemConsumer->setTransformHint(mTransformHint); SurfaceComposerClient::Transaction() Loading Loading @@ -302,18 +306,20 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence // So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer. // Otherwise, this is a no-op. static void releaseBufferCallbackThunk(wp<BLASTBufferQueue> context, uint64_t graphicBufferId, const sp<Fence>& releaseFence, uint32_t transformHint) { const sp<Fence>& releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { sp<BLASTBufferQueue> blastBufferQueue = context.promote(); ALOGV("releaseBufferCallbackThunk graphicBufferId=%" PRIu64 " blastBufferQueue=%s", graphicBufferId, blastBufferQueue ? "alive" : "dead"); if (blastBufferQueue) { blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint); blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } } void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId, const sp<Fence>& releaseFence, uint32_t transformHint) { const sp<Fence>& releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { ATRACE_CALL(); std::unique_lock _lock{mMutex}; BQA_LOGV("releaseBufferCallback graphicBufferId=%" PRIu64, graphicBufferId); Loading @@ -324,15 +330,36 @@ void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId, mBufferItemConsumer->setTransformHint(mTransformHint); } auto it = mSubmitted.find(graphicBufferId); // 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(graphicBufferId); return it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL; }(); const auto numPendingBuffersToHold = isEGL ? std::max(0u, mMaxAcquiredBuffers - currentMaxAcquiredBufferCount) : 0; mPendingRelease.emplace_back(ReleasedBuffer{graphicBufferId, releaseFence}); // 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.bufferId); if (it == mSubmitted.end()) { BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %" PRIu64, graphicBufferId); return; } mBufferItemConsumer->releaseBuffer(it->second, releaseFence); mBufferItemConsumer->releaseBuffer(it->second, releaseBuffer.releaseFence); mSubmitted.erase(it); } ATRACE_INT("PendingRelease", mPendingRelease.size()); mNumAcquired--; processNextBufferLocked(false /* useNextTransaction */); mCallbackCV.notify_all(); Loading Loading @@ -414,7 +441,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this) /* callbackContext */, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); t->setBuffer(mSurfaceControl, buffer, releaseBufferCallback); t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace)); t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata); Loading Loading @@ -567,7 +595,7 @@ void BLASTBufferQueue::setTransactionCompleteCallback( // includeExtraAcquire is true to include this buffer to the count. Since this depends on the state // of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE. bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const { int maxAcquiredBuffers = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1); int maxAcquiredBuffers = mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1); return mNumAcquired == maxAcquiredBuffers; } Loading libs/gui/ISurfaceComposer.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -1215,16 +1215,17 @@ public: return reply.readInt32(); } status_t getExtraBufferCount(int* extraBuffers) const override { status_t getMaxAcquiredBufferCount(int* buffers) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t err = remote()->transact(BnSurfaceComposer::GET_EXTRA_BUFFER_COUNT, data, &reply); status_t err = remote()->transact(BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); if (err != NO_ERROR) { ALOGE("getExtraBufferCount failed to read data: %s (%d)", strerror(-err), err); ALOGE("getMaxAcquiredBufferCount failed to read data: %s (%d)", strerror(-err), err); return err; } return reply.readInt32(extraBuffers); return reply.readInt32(buffers); } }; Loading Loading @@ -2069,14 +2070,14 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(reply->writeInt32, priority); return NO_ERROR; } case GET_EXTRA_BUFFER_COUNT: { case GET_MAX_ACQUIRED_BUFFER_COUNT: { CHECK_INTERFACE(ISurfaceComposer, data, reply); int extraBuffers = 0; int err = getExtraBufferCount(&extraBuffers); int buffers = 0; int err = getMaxAcquiredBufferCount(&buffers); if (err != NO_ERROR) { return err; } SAFE_PARCEL(reply->writeInt32, extraBuffers); SAFE_PARCEL(reply->writeInt32, buffers); return NO_ERROR; } case OVERRIDE_HDR_TYPES: { Loading libs/gui/ITransactionCompletedListener.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ status_t SurfaceStats::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeBool, false); } SAFE_PARCEL(output->writeUint32, transformHint); SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount); SAFE_PARCEL(output->writeParcelable, eventStats); SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size())); for (const auto& data : jankData) { Loading @@ -138,6 +139,7 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->read, *previousReleaseFence); } SAFE_PARCEL(input->readUint32, &transformHint); SAFE_PARCEL(input->readUint32, ¤tMaxAcquiredBufferCount); SAFE_PARCEL(input->readParcelable, &eventStats); int32_t jankData_size = 0; Loading Loading @@ -251,11 +253,13 @@ public: stats); } void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint) override { void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) override { callRemoteAsync<decltype( &ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, graphicBufferId, releaseFence, transformHint); graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } }; Loading libs/gui/Surface.cpp +0 −15 Original line number Diff line number Diff line Loading @@ -1501,9 +1501,6 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO: res = dispatchSetFrameTimelineInfo(args); break; case NATIVE_WINDOW_GET_EXTRA_BUFFER_COUNT: res = dispatchGetExtraBufferCount(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1853,14 +1850,6 @@ int Surface::dispatchSetFrameTimelineInfo(va_list args) { return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId}); } int Surface::dispatchGetExtraBufferCount(va_list args) { ATRACE_CALL(); auto extraBuffers = static_cast<int*>(va_arg(args, int*)); ALOGV("Surface::dispatchGetExtraBufferCount"); return getExtraBufferCount(extraBuffers); } bool Surface::transformToDisplayInverse() const { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading Loading @@ -2632,8 +2621,4 @@ status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInf return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo); } status_t Surface::getExtraBufferCount(int* extraBuffers) const { return composerService()->getExtraBufferCount(extraBuffers); } }; // namespace android libs/gui/SurfaceComposerClient.cpp +6 −5 Original line number Diff line number Diff line Loading @@ -328,7 +328,8 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceStats.previousReleaseFence ? surfaceStats.previousReleaseFence : Fence::NO_FENCE, surfaceStats.transformHint); surfaceStats.transformHint, surfaceStats.currentMaxAcquiredBufferCount); } } } Loading Loading @@ -364,9 +365,9 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint) { void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { ReleaseBufferCallback callback; { std::scoped_lock<std::mutex> lock(mMutex); Loading @@ -376,7 +377,7 @@ void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, ALOGE("Could not call release buffer callback, buffer not found %" PRIu64, graphicBufferId); return; } callback(graphicBufferId, releaseFence, transformHint); callback(graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked( Loading Loading
libs/gui/BLASTBufferQueue.cpp +42 −14 Original line number Diff line number Diff line Loading @@ -29,9 +29,10 @@ #include <gui/IProducerListener.h> #include <gui/Surface.h> #include <utils/Singleton.h> #include <utils/Trace.h> #include <private/gui/ComposerService.h> #include <chrono> using namespace std::chrono_literals; Loading Loading @@ -158,6 +159,9 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format)); mBufferItemConsumer->setBlastBufferQueue(this); ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers); mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers); mTransformHint = mSurfaceControl->getTransformHint(); mBufferItemConsumer->setTransformHint(mTransformHint); SurfaceComposerClient::Transaction() Loading Loading @@ -302,18 +306,20 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence // So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer. // Otherwise, this is a no-op. static void releaseBufferCallbackThunk(wp<BLASTBufferQueue> context, uint64_t graphicBufferId, const sp<Fence>& releaseFence, uint32_t transformHint) { const sp<Fence>& releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { sp<BLASTBufferQueue> blastBufferQueue = context.promote(); ALOGV("releaseBufferCallbackThunk graphicBufferId=%" PRIu64 " blastBufferQueue=%s", graphicBufferId, blastBufferQueue ? "alive" : "dead"); if (blastBufferQueue) { blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint); blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } } void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId, const sp<Fence>& releaseFence, uint32_t transformHint) { const sp<Fence>& releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { ATRACE_CALL(); std::unique_lock _lock{mMutex}; BQA_LOGV("releaseBufferCallback graphicBufferId=%" PRIu64, graphicBufferId); Loading @@ -324,15 +330,36 @@ void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId, mBufferItemConsumer->setTransformHint(mTransformHint); } auto it = mSubmitted.find(graphicBufferId); // 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(graphicBufferId); return it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL; }(); const auto numPendingBuffersToHold = isEGL ? std::max(0u, mMaxAcquiredBuffers - currentMaxAcquiredBufferCount) : 0; mPendingRelease.emplace_back(ReleasedBuffer{graphicBufferId, releaseFence}); // 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.bufferId); if (it == mSubmitted.end()) { BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %" PRIu64, graphicBufferId); return; } mBufferItemConsumer->releaseBuffer(it->second, releaseFence); mBufferItemConsumer->releaseBuffer(it->second, releaseBuffer.releaseFence); mSubmitted.erase(it); } ATRACE_INT("PendingRelease", mPendingRelease.size()); mNumAcquired--; processNextBufferLocked(false /* useNextTransaction */); mCallbackCV.notify_all(); Loading Loading @@ -414,7 +441,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this) /* callbackContext */, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); t->setBuffer(mSurfaceControl, buffer, releaseBufferCallback); t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace)); t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata); Loading Loading @@ -567,7 +595,7 @@ void BLASTBufferQueue::setTransactionCompleteCallback( // includeExtraAcquire is true to include this buffer to the count. Since this depends on the state // of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE. bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const { int maxAcquiredBuffers = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1); int maxAcquiredBuffers = mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1); return mNumAcquired == maxAcquiredBuffers; } Loading
libs/gui/ISurfaceComposer.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -1215,16 +1215,17 @@ public: return reply.readInt32(); } status_t getExtraBufferCount(int* extraBuffers) const override { status_t getMaxAcquiredBufferCount(int* buffers) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t err = remote()->transact(BnSurfaceComposer::GET_EXTRA_BUFFER_COUNT, data, &reply); status_t err = remote()->transact(BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); if (err != NO_ERROR) { ALOGE("getExtraBufferCount failed to read data: %s (%d)", strerror(-err), err); ALOGE("getMaxAcquiredBufferCount failed to read data: %s (%d)", strerror(-err), err); return err; } return reply.readInt32(extraBuffers); return reply.readInt32(buffers); } }; Loading Loading @@ -2069,14 +2070,14 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(reply->writeInt32, priority); return NO_ERROR; } case GET_EXTRA_BUFFER_COUNT: { case GET_MAX_ACQUIRED_BUFFER_COUNT: { CHECK_INTERFACE(ISurfaceComposer, data, reply); int extraBuffers = 0; int err = getExtraBufferCount(&extraBuffers); int buffers = 0; int err = getMaxAcquiredBufferCount(&buffers); if (err != NO_ERROR) { return err; } SAFE_PARCEL(reply->writeInt32, extraBuffers); SAFE_PARCEL(reply->writeInt32, buffers); return NO_ERROR; } case OVERRIDE_HDR_TYPES: { Loading
libs/gui/ITransactionCompletedListener.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ status_t SurfaceStats::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeBool, false); } SAFE_PARCEL(output->writeUint32, transformHint); SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount); SAFE_PARCEL(output->writeParcelable, eventStats); SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size())); for (const auto& data : jankData) { Loading @@ -138,6 +139,7 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->read, *previousReleaseFence); } SAFE_PARCEL(input->readUint32, &transformHint); SAFE_PARCEL(input->readUint32, ¤tMaxAcquiredBufferCount); SAFE_PARCEL(input->readParcelable, &eventStats); int32_t jankData_size = 0; Loading Loading @@ -251,11 +253,13 @@ public: stats); } void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint) override { void onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) override { callRemoteAsync<decltype( &ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, graphicBufferId, releaseFence, transformHint); graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } }; Loading
libs/gui/Surface.cpp +0 −15 Original line number Diff line number Diff line Loading @@ -1501,9 +1501,6 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO: res = dispatchSetFrameTimelineInfo(args); break; case NATIVE_WINDOW_GET_EXTRA_BUFFER_COUNT: res = dispatchGetExtraBufferCount(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1853,14 +1850,6 @@ int Surface::dispatchSetFrameTimelineInfo(va_list args) { return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId}); } int Surface::dispatchGetExtraBufferCount(va_list args) { ATRACE_CALL(); auto extraBuffers = static_cast<int*>(va_arg(args, int*)); ALOGV("Surface::dispatchGetExtraBufferCount"); return getExtraBufferCount(extraBuffers); } bool Surface::transformToDisplayInverse() const { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading Loading @@ -2632,8 +2621,4 @@ status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInf return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo); } status_t Surface::getExtraBufferCount(int* extraBuffers) const { return composerService()->getExtraBufferCount(extraBuffers); } }; // namespace android
libs/gui/SurfaceComposerClient.cpp +6 −5 Original line number Diff line number Diff line Loading @@ -328,7 +328,8 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceStats.previousReleaseFence ? surfaceStats.previousReleaseFence : Fence::NO_FENCE, surfaceStats.transformHint); surfaceStats.transformHint, surfaceStats.currentMaxAcquiredBufferCount); } } } Loading Loading @@ -364,9 +365,9 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint) { void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, sp<Fence> releaseFence, uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) { ReleaseBufferCallback callback; { std::scoped_lock<std::mutex> lock(mMutex); Loading @@ -376,7 +377,7 @@ void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, ALOGE("Could not call release buffer callback, buffer not found %" PRIu64, graphicBufferId); return; } callback(graphicBufferId, releaseFence, transformHint); callback(graphicBufferId, releaseFence, transformHint, currentMaxAcquiredBufferCount); } ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked( Loading