Loading libs/gui/BLASTBufferQueue.cpp +10 −151 Original line number Diff line number Diff line Loading @@ -22,14 +22,11 @@ #include <com_android_graphics_libgui_flags.h> #include <cutils/atomic.h> #include <ftl/fake_guard.h> #include <gui/BLASTBufferQueue.h> #include <gui/BufferItemConsumer.h> #include <gui/BufferQueueConsumer.h> #include <gui/BufferQueueCore.h> #include <gui/BufferQueueProducer.h> #include <sys/epoll.h> #include <sys/eventfd.h> #include <gui/FrameRateUtils.h> #include <gui/GLConsumer.h> Loading Loading @@ -77,12 +74,6 @@ namespace android { std::unique_lock _lock{mutex}; \ base::ScopedLockAssertion assumeLocked(mutex); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) static ReleaseBufferCallback EMPTY_RELEASE_CALLBACK = [](const ReleaseCallbackId&, const sp<Fence>& /*releaseFence*/, std::optional<uint32_t> /*currentMaxAcquiredBufferCount*/) {}; #endif void BLASTBufferItemConsumer::onDisconnect() { Mutex::Autolock lock(mMutex); mPreviouslyConnected = mCurrentlyConnected; Loading Loading @@ -224,12 +215,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati }, this); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> bufferReleaseConsumer; gui::BufferReleaseChannel::open(mName, bufferReleaseConsumer, mBufferReleaseProducer); mBufferReleaseReader = std::make_shared<BufferReleaseReader>(std::move(bufferReleaseConsumer)); #endif BQA_LOGV("BLASTBufferQueue created"); } Loading Loading @@ -259,9 +244,6 @@ BLASTBufferQueue::~BLASTBufferQueue() { void BLASTBufferQueue::onFirstRef() { // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) mBufferReleaseThread.start(sp<BLASTBufferQueue>::fromExisting(this)); #endif } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, Loading @@ -287,9 +269,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, if (surfaceControlChanged) { t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, layer_state_t::eEnableBackpressure); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) t.setBufferReleaseChannel(mSurfaceControl, mBufferReleaseProducer); #endif applyTransaction = true; } mTransformHint = mSurfaceControl->getTransformHint(); Loading Loading @@ -407,7 +386,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence stat.latchTime, stat.frameEventStats.dequeueReadyTime); } #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) auto currFrameNumber = stat.frameEventStats.frameNumber; std::vector<ReleaseCallbackId> staleReleases; for (const auto& [key, value]: mSubmitted) { Loading @@ -423,7 +401,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence stat.currentMaxAcquiredBufferCount, true /* fakeRelease */); } #endif } else { BQA_LOGE("Failed to find matching SurfaceControl in transactionCallback"); } Loading @@ -434,15 +411,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence } } void BLASTBufferQueue::flushShadowQueue() { BQA_LOGV("flushShadowQueue"); int numFramesToFlush = mNumFrameAvailable; while (numFramesToFlush > 0) { acquireNextBufferLocked(std::nullopt); numFramesToFlush--; } } // Unlike transactionCallbackThunk the release buffer callback does not extend the life of the // BBQ. This is because if the BBQ is destroyed, then the buffers will be released by the client. // So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer. Loading @@ -460,6 +428,15 @@ ReleaseBufferCallback BLASTBufferQueue::makeReleaseBufferCallbackThunk() { }; } void BLASTBufferQueue::flushShadowQueue() { BQA_LOGV("flushShadowQueue"); int numFramesToFlush = mNumFrameAvailable; while (numFramesToFlush > 0) { acquireNextBufferLocked(std::nullopt); numFramesToFlush--; } } void BLASTBufferQueue::releaseBufferCallback( const ReleaseCallbackId& id, const sp<Fence>& releaseFence, std::optional<uint32_t> currentMaxAcquiredBufferCount) { Loading Loading @@ -634,12 +611,7 @@ status_t BLASTBufferQueue::acquireNextBufferLocked( bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, bufferItem.mScalingMode, crop); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) ReleaseBufferCallback releaseBufferCallback = applyTransaction ? EMPTY_RELEASE_CALLBACK : makeReleaseBufferCallbackThunk(); #else auto releaseBufferCallback = makeReleaseBufferCallbackThunk(); #endif sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE; nsecs_t dequeueTime = -1; Loading Loading @@ -1252,120 +1224,7 @@ bool BLASTBufferQueue::isSameSurfaceControl(const sp<SurfaceControl>& surfaceCon void BLASTBufferQueue::setTransactionHangCallback( std::function<void(const std::string&)> callback) { std::lock_guard _lock{mMutex}; mTransactionHangCallback = std::move(callback); mTransactionHangCallback = callback; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader( std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> endpoint) : mEndpoint{std::move(endpoint)} { mEpollFd = android::base::unique_fd{epoll_create1(0)}; LOG_ALWAYS_FATAL_IF(!mEpollFd.ok(), "Failed to create buffer release epoll file descriptor. errno=%d " "message='%s'", errno, strerror(errno)); epoll_event registerEndpointFd{}; registerEndpointFd.events = EPOLLIN; registerEndpointFd.data.fd = mEndpoint->getFd(); status_t status = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEndpoint->getFd(), ®isterEndpointFd); LOG_ALWAYS_FATAL_IF(status == -1, "Failed to register buffer release consumer file descriptor with epoll. " "errno=%d message='%s'", errno, strerror(errno)); mEventFd = android::base::unique_fd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); LOG_ALWAYS_FATAL_IF(!mEventFd.ok(), "Failed to create buffer release event file descriptor. errno=%d " "message='%s'", errno, strerror(errno)); epoll_event registerEventFd{}; registerEventFd.events = EPOLLIN; registerEventFd.data.fd = mEventFd.get(); status = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEventFd.get(), ®isterEventFd); LOG_ALWAYS_FATAL_IF(status == -1, "Failed to register buffer release event file descriptor with epoll. " "errno=%d message='%s'", errno, strerror(errno)); } BLASTBufferQueue::BufferReleaseReader& BLASTBufferQueue::BufferReleaseReader::operator=( BufferReleaseReader&& other) { if (this != &other) { ftl::FakeGuard guard{mMutex}; ftl::FakeGuard otherGuard{other.mMutex}; mEndpoint = std::move(other.mEndpoint); mEpollFd = std::move(other.mEpollFd); mEventFd = std::move(other.mEventFd); } return *this; } status_t BLASTBufferQueue::BufferReleaseReader::readBlocking(ReleaseCallbackId& outId, sp<Fence>& outFence, uint32_t& outMaxAcquiredBufferCount) { epoll_event event{}; while (true) { int eventCount = epoll_wait(mEpollFd.get(), &event, 1 /* maxevents */, -1 /* timeout */); if (eventCount == 1) { break; } if (eventCount == -1 && errno != EINTR) { ALOGE("epoll_wait error while waiting for buffer release. errno=%d message='%s'", errno, strerror(errno)); } } if (event.data.fd == mEventFd.get()) { uint64_t value; if (read(mEventFd.get(), &value, sizeof(uint64_t)) == -1 && errno != EWOULDBLOCK) { ALOGE("error while reading from eventfd. errno=%d message='%s'", errno, strerror(errno)); } return WOULD_BLOCK; } std::lock_guard lock{mMutex}; return mEndpoint->readReleaseFence(outId, outFence, outMaxAcquiredBufferCount); } void BLASTBufferQueue::BufferReleaseReader::interruptBlockingRead() { uint64_t value = 1; if (write(mEventFd.get(), &value, sizeof(uint64_t)) == -1) { ALOGE("failed to notify dequeue event. errno=%d message='%s'", errno, strerror(errno)); } } void BLASTBufferQueue::BufferReleaseThread::start(const sp<BLASTBufferQueue>& bbq) { mRunning = std::make_shared<std::atomic_bool>(true); mReader = bbq->mBufferReleaseReader; std::thread([running = mRunning, reader = mReader, weakBbq = wp<BLASTBufferQueue>(bbq)]() { pthread_setname_np(pthread_self(), "BufferReleaseThread"); while (*running) { ReleaseCallbackId id; sp<Fence> fence; uint32_t maxAcquiredBufferCount; if (status_t status = reader->readBlocking(id, fence, maxAcquiredBufferCount); status != OK) { continue; } sp<BLASTBufferQueue> bbq = weakBbq.promote(); if (!bbq) { return; } bbq->releaseBufferCallback(id, fence, maxAcquiredBufferCount); } }).detach(); } BLASTBufferQueue::BufferReleaseThread::~BufferReleaseThread() { *mRunning = false; mReader->interruptBlockingRead(); } #endif } // namespace android libs/gui/include/gui/BLASTBufferQueue.h +0 −45 Original line number Diff line number Diff line Loading @@ -315,51 +315,6 @@ private: std::function<void(const std::string&)> mTransactionHangCallback; std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) class BufferReleaseReader { public: BufferReleaseReader() = default; BufferReleaseReader(std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint>); BufferReleaseReader& operator=(BufferReleaseReader&&); // Block until we can read a buffer release message. // // Returns: // * OK if a ReleaseCallbackId and Fence were successfully read. // * WOULD_BLOCK if the blocking read was interrupted by interruptBlockingRead. // * UNKNOWN_ERROR if something went wrong. status_t readBlocking(ReleaseCallbackId& outId, sp<Fence>& outReleaseFence, uint32_t& outMaxAcquiredBufferCount); // Signals the reader's eventfd to wake up any threads waiting on readBlocking. void interruptBlockingRead(); private: std::mutex mMutex; std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> mEndpoint GUARDED_BY(mMutex); android::base::unique_fd mEpollFd; android::base::unique_fd mEventFd; }; // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to // the client. See BBQBufferQueueProducer::dequeueBuffer for details. std::shared_ptr<BufferReleaseReader> mBufferReleaseReader; std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseProducer; class BufferReleaseThread { public: BufferReleaseThread() = default; ~BufferReleaseThread(); void start(const sp<BLASTBufferQueue>&); private: std::shared_ptr<std::atomic_bool> mRunning; std::shared_ptr<BufferReleaseReader> mReader; }; BufferReleaseThread mBufferReleaseThread; #endif }; } // namespace android Loading services/surfaceflinger/Layer.cpp +4 −19 Original line number Diff line number Diff line Loading @@ -1951,24 +1951,15 @@ bool Layer::setDropInputMode(gui::DropInputMode mode) { void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener, const sp<GraphicBuffer>& buffer, uint64_t framenumber, const sp<Fence>& releaseFence) { if (!listener && !mBufferReleaseChannel) { if (!listener) { return; } SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber); ReleaseCallbackId callbackId{buffer->getId(), framenumber}; const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE; uint32_t currentMaxAcquiredBufferCount = mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid); if (listener) { listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount); } if (mBufferReleaseChannel) { mBufferReleaseChannel->writeReleaseFence(callbackId, fence, currentMaxAcquiredBufferCount); } listener->onReleaseBuffer({buffer->getId(), framenumber}, releaseFence ? releaseFence : Fence::NO_FENCE, currentMaxAcquiredBufferCount); } sp<CallbackHandle> Layer::findCallbackHandle() { Loading Loading @@ -2086,7 +2077,6 @@ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult, void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) { for (const auto& handle : mDrawingState.callbackHandles) { handle->bufferReleaseChannel = mBufferReleaseChannel; handle->transformHint = mTransformHint; handle->dequeueReadyTime = dequeueReadyTime; handle->currentMaxAcquiredBufferCount = Loading Loading @@ -3518,11 +3508,6 @@ bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thre return haveTrustedPresentationListener; } void Layer::setBufferReleaseChannel( const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) { mBufferReleaseChannel = channel; } void Layer::updateLastLatchTime(nsecs_t latchTime) { mLastLatchTime = latchTime; } Loading services/surfaceflinger/Layer.h +0 −3 Original line number Diff line number Diff line Loading @@ -537,7 +537,6 @@ public: }; BufferInfo mBufferInfo; std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseChannel; // implements compositionengine::LayerFE const compositionengine::LayerFECompositionState* getCompositionState() const; Loading Loading @@ -725,8 +724,6 @@ public: bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds, TrustedPresentationListener const& listener); void setBufferReleaseChannel( const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel); // Creates a new handle each time, so we only expect // this to be called once. Loading services/surfaceflinger/SurfaceFlinger.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -5063,10 +5063,6 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } } if (what & layer_state_t::eBufferReleaseChannelChanged) { layer->setBufferReleaseChannel(s.bufferReleaseChannel); } const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence()); bool willPresentCurrentTransaction = requestedLayerState && (requestedLayerState->hasReadyFrame() || Loading Loading
libs/gui/BLASTBufferQueue.cpp +10 −151 Original line number Diff line number Diff line Loading @@ -22,14 +22,11 @@ #include <com_android_graphics_libgui_flags.h> #include <cutils/atomic.h> #include <ftl/fake_guard.h> #include <gui/BLASTBufferQueue.h> #include <gui/BufferItemConsumer.h> #include <gui/BufferQueueConsumer.h> #include <gui/BufferQueueCore.h> #include <gui/BufferQueueProducer.h> #include <sys/epoll.h> #include <sys/eventfd.h> #include <gui/FrameRateUtils.h> #include <gui/GLConsumer.h> Loading Loading @@ -77,12 +74,6 @@ namespace android { std::unique_lock _lock{mutex}; \ base::ScopedLockAssertion assumeLocked(mutex); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) static ReleaseBufferCallback EMPTY_RELEASE_CALLBACK = [](const ReleaseCallbackId&, const sp<Fence>& /*releaseFence*/, std::optional<uint32_t> /*currentMaxAcquiredBufferCount*/) {}; #endif void BLASTBufferItemConsumer::onDisconnect() { Mutex::Autolock lock(mMutex); mPreviouslyConnected = mCurrentlyConnected; Loading Loading @@ -224,12 +215,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati }, this); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> bufferReleaseConsumer; gui::BufferReleaseChannel::open(mName, bufferReleaseConsumer, mBufferReleaseProducer); mBufferReleaseReader = std::make_shared<BufferReleaseReader>(std::move(bufferReleaseConsumer)); #endif BQA_LOGV("BLASTBufferQueue created"); } Loading Loading @@ -259,9 +244,6 @@ BLASTBufferQueue::~BLASTBufferQueue() { void BLASTBufferQueue::onFirstRef() { // safe default, most producers are expected to override this mProducer->setMaxDequeuedBufferCount(2); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) mBufferReleaseThread.start(sp<BLASTBufferQueue>::fromExisting(this)); #endif } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, Loading @@ -287,9 +269,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, if (surfaceControlChanged) { t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, layer_state_t::eEnableBackpressure); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) t.setBufferReleaseChannel(mSurfaceControl, mBufferReleaseProducer); #endif applyTransaction = true; } mTransformHint = mSurfaceControl->getTransformHint(); Loading Loading @@ -407,7 +386,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence stat.latchTime, stat.frameEventStats.dequeueReadyTime); } #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) auto currFrameNumber = stat.frameEventStats.frameNumber; std::vector<ReleaseCallbackId> staleReleases; for (const auto& [key, value]: mSubmitted) { Loading @@ -423,7 +401,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence stat.currentMaxAcquiredBufferCount, true /* fakeRelease */); } #endif } else { BQA_LOGE("Failed to find matching SurfaceControl in transactionCallback"); } Loading @@ -434,15 +411,6 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence } } void BLASTBufferQueue::flushShadowQueue() { BQA_LOGV("flushShadowQueue"); int numFramesToFlush = mNumFrameAvailable; while (numFramesToFlush > 0) { acquireNextBufferLocked(std::nullopt); numFramesToFlush--; } } // Unlike transactionCallbackThunk the release buffer callback does not extend the life of the // BBQ. This is because if the BBQ is destroyed, then the buffers will be released by the client. // So we pass in a weak pointer to the BBQ and if it still alive, then we release the buffer. Loading @@ -460,6 +428,15 @@ ReleaseBufferCallback BLASTBufferQueue::makeReleaseBufferCallbackThunk() { }; } void BLASTBufferQueue::flushShadowQueue() { BQA_LOGV("flushShadowQueue"); int numFramesToFlush = mNumFrameAvailable; while (numFramesToFlush > 0) { acquireNextBufferLocked(std::nullopt); numFramesToFlush--; } } void BLASTBufferQueue::releaseBufferCallback( const ReleaseCallbackId& id, const sp<Fence>& releaseFence, std::optional<uint32_t> currentMaxAcquiredBufferCount) { Loading Loading @@ -634,12 +611,7 @@ status_t BLASTBufferQueue::acquireNextBufferLocked( bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, bufferItem.mScalingMode, crop); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) ReleaseBufferCallback releaseBufferCallback = applyTransaction ? EMPTY_RELEASE_CALLBACK : makeReleaseBufferCallbackThunk(); #else auto releaseBufferCallback = makeReleaseBufferCallbackThunk(); #endif sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE; nsecs_t dequeueTime = -1; Loading Loading @@ -1252,120 +1224,7 @@ bool BLASTBufferQueue::isSameSurfaceControl(const sp<SurfaceControl>& surfaceCon void BLASTBufferQueue::setTransactionHangCallback( std::function<void(const std::string&)> callback) { std::lock_guard _lock{mMutex}; mTransactionHangCallback = std::move(callback); mTransactionHangCallback = callback; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader( std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> endpoint) : mEndpoint{std::move(endpoint)} { mEpollFd = android::base::unique_fd{epoll_create1(0)}; LOG_ALWAYS_FATAL_IF(!mEpollFd.ok(), "Failed to create buffer release epoll file descriptor. errno=%d " "message='%s'", errno, strerror(errno)); epoll_event registerEndpointFd{}; registerEndpointFd.events = EPOLLIN; registerEndpointFd.data.fd = mEndpoint->getFd(); status_t status = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEndpoint->getFd(), ®isterEndpointFd); LOG_ALWAYS_FATAL_IF(status == -1, "Failed to register buffer release consumer file descriptor with epoll. " "errno=%d message='%s'", errno, strerror(errno)); mEventFd = android::base::unique_fd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); LOG_ALWAYS_FATAL_IF(!mEventFd.ok(), "Failed to create buffer release event file descriptor. errno=%d " "message='%s'", errno, strerror(errno)); epoll_event registerEventFd{}; registerEventFd.events = EPOLLIN; registerEventFd.data.fd = mEventFd.get(); status = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEventFd.get(), ®isterEventFd); LOG_ALWAYS_FATAL_IF(status == -1, "Failed to register buffer release event file descriptor with epoll. " "errno=%d message='%s'", errno, strerror(errno)); } BLASTBufferQueue::BufferReleaseReader& BLASTBufferQueue::BufferReleaseReader::operator=( BufferReleaseReader&& other) { if (this != &other) { ftl::FakeGuard guard{mMutex}; ftl::FakeGuard otherGuard{other.mMutex}; mEndpoint = std::move(other.mEndpoint); mEpollFd = std::move(other.mEpollFd); mEventFd = std::move(other.mEventFd); } return *this; } status_t BLASTBufferQueue::BufferReleaseReader::readBlocking(ReleaseCallbackId& outId, sp<Fence>& outFence, uint32_t& outMaxAcquiredBufferCount) { epoll_event event{}; while (true) { int eventCount = epoll_wait(mEpollFd.get(), &event, 1 /* maxevents */, -1 /* timeout */); if (eventCount == 1) { break; } if (eventCount == -1 && errno != EINTR) { ALOGE("epoll_wait error while waiting for buffer release. errno=%d message='%s'", errno, strerror(errno)); } } if (event.data.fd == mEventFd.get()) { uint64_t value; if (read(mEventFd.get(), &value, sizeof(uint64_t)) == -1 && errno != EWOULDBLOCK) { ALOGE("error while reading from eventfd. errno=%d message='%s'", errno, strerror(errno)); } return WOULD_BLOCK; } std::lock_guard lock{mMutex}; return mEndpoint->readReleaseFence(outId, outFence, outMaxAcquiredBufferCount); } void BLASTBufferQueue::BufferReleaseReader::interruptBlockingRead() { uint64_t value = 1; if (write(mEventFd.get(), &value, sizeof(uint64_t)) == -1) { ALOGE("failed to notify dequeue event. errno=%d message='%s'", errno, strerror(errno)); } } void BLASTBufferQueue::BufferReleaseThread::start(const sp<BLASTBufferQueue>& bbq) { mRunning = std::make_shared<std::atomic_bool>(true); mReader = bbq->mBufferReleaseReader; std::thread([running = mRunning, reader = mReader, weakBbq = wp<BLASTBufferQueue>(bbq)]() { pthread_setname_np(pthread_self(), "BufferReleaseThread"); while (*running) { ReleaseCallbackId id; sp<Fence> fence; uint32_t maxAcquiredBufferCount; if (status_t status = reader->readBlocking(id, fence, maxAcquiredBufferCount); status != OK) { continue; } sp<BLASTBufferQueue> bbq = weakBbq.promote(); if (!bbq) { return; } bbq->releaseBufferCallback(id, fence, maxAcquiredBufferCount); } }).detach(); } BLASTBufferQueue::BufferReleaseThread::~BufferReleaseThread() { *mRunning = false; mReader->interruptBlockingRead(); } #endif } // namespace android
libs/gui/include/gui/BLASTBufferQueue.h +0 −45 Original line number Diff line number Diff line Loading @@ -315,51 +315,6 @@ private: std::function<void(const std::string&)> mTransactionHangCallback; std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) class BufferReleaseReader { public: BufferReleaseReader() = default; BufferReleaseReader(std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint>); BufferReleaseReader& operator=(BufferReleaseReader&&); // Block until we can read a buffer release message. // // Returns: // * OK if a ReleaseCallbackId and Fence were successfully read. // * WOULD_BLOCK if the blocking read was interrupted by interruptBlockingRead. // * UNKNOWN_ERROR if something went wrong. status_t readBlocking(ReleaseCallbackId& outId, sp<Fence>& outReleaseFence, uint32_t& outMaxAcquiredBufferCount); // Signals the reader's eventfd to wake up any threads waiting on readBlocking. void interruptBlockingRead(); private: std::mutex mMutex; std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> mEndpoint GUARDED_BY(mMutex); android::base::unique_fd mEpollFd; android::base::unique_fd mEventFd; }; // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to // the client. See BBQBufferQueueProducer::dequeueBuffer for details. std::shared_ptr<BufferReleaseReader> mBufferReleaseReader; std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseProducer; class BufferReleaseThread { public: BufferReleaseThread() = default; ~BufferReleaseThread(); void start(const sp<BLASTBufferQueue>&); private: std::shared_ptr<std::atomic_bool> mRunning; std::shared_ptr<BufferReleaseReader> mReader; }; BufferReleaseThread mBufferReleaseThread; #endif }; } // namespace android Loading
services/surfaceflinger/Layer.cpp +4 −19 Original line number Diff line number Diff line Loading @@ -1951,24 +1951,15 @@ bool Layer::setDropInputMode(gui::DropInputMode mode) { void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener, const sp<GraphicBuffer>& buffer, uint64_t framenumber, const sp<Fence>& releaseFence) { if (!listener && !mBufferReleaseChannel) { if (!listener) { return; } SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber); ReleaseCallbackId callbackId{buffer->getId(), framenumber}; const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE; uint32_t currentMaxAcquiredBufferCount = mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid); if (listener) { listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount); } if (mBufferReleaseChannel) { mBufferReleaseChannel->writeReleaseFence(callbackId, fence, currentMaxAcquiredBufferCount); } listener->onReleaseBuffer({buffer->getId(), framenumber}, releaseFence ? releaseFence : Fence::NO_FENCE, currentMaxAcquiredBufferCount); } sp<CallbackHandle> Layer::findCallbackHandle() { Loading Loading @@ -2086,7 +2077,6 @@ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult, void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) { for (const auto& handle : mDrawingState.callbackHandles) { handle->bufferReleaseChannel = mBufferReleaseChannel; handle->transformHint = mTransformHint; handle->dequeueReadyTime = dequeueReadyTime; handle->currentMaxAcquiredBufferCount = Loading Loading @@ -3518,11 +3508,6 @@ bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thre return haveTrustedPresentationListener; } void Layer::setBufferReleaseChannel( const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) { mBufferReleaseChannel = channel; } void Layer::updateLastLatchTime(nsecs_t latchTime) { mLastLatchTime = latchTime; } Loading
services/surfaceflinger/Layer.h +0 −3 Original line number Diff line number Diff line Loading @@ -537,7 +537,6 @@ public: }; BufferInfo mBufferInfo; std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseChannel; // implements compositionengine::LayerFE const compositionengine::LayerFECompositionState* getCompositionState() const; Loading Loading @@ -725,8 +724,6 @@ public: bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds, TrustedPresentationListener const& listener); void setBufferReleaseChannel( const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel); // Creates a new handle each time, so we only expect // this to be called once. Loading
services/surfaceflinger/SurfaceFlinger.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -5063,10 +5063,6 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } } if (what & layer_state_t::eBufferReleaseChannelChanged) { layer->setBufferReleaseChannel(s.bufferReleaseChannel); } const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence()); bool willPresentCurrentTransaction = requestedLayerState && (requestedLayerState->hasReadyFrame() || Loading