diff options
-rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 11 | ||||
-rw-r--r-- | libs/gui/FenceMonitor.cpp | 36 | ||||
-rw-r--r-- | libs/gui/include/gui/BLASTBufferQueue.h | 3 | ||||
-rw-r--r-- | libs/gui/include/gui/FenceMonitor.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/TransactionCallbackInvoker.cpp | 4 |
6 files changed, 53 insertions, 13 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 3c1971fd81..94998e5ab7 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -31,6 +31,7 @@ #include <sys/epoll.h> #include <sys/eventfd.h> +#include <gui/FenceMonitor.h> #include <gui/FrameRateUtils.h> #include <gui/GLConsumer.h> #include <gui/IProducerListener.h> @@ -475,6 +476,16 @@ void BLASTBufferQueue::releaseBufferCallbackLocked( ATRACE_CALL(); BQA_LOGV("releaseBufferCallback %s", id.to_string().c_str()); + if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { + if (!mFenceMonitor) { + std::string monitorName = "release :"; + monitorName.append(mName.c_str()); + mFenceMonitor.emplace(monitorName.c_str()); + } + + mFenceMonitor->queueFence(releaseFence); + } + // 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 diff --git a/libs/gui/FenceMonitor.cpp b/libs/gui/FenceMonitor.cpp index 230c81a0b3..e38f1a8ce6 100644 --- a/libs/gui/FenceMonitor.cpp +++ b/libs/gui/FenceMonitor.cpp @@ -25,9 +25,18 @@ namespace android::gui { FenceMonitor::FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) { - std::thread thread(&FenceMonitor::loop, this); - pthread_setname_np(thread.native_handle(), mName); - thread.detach(); + mThread = std::thread(&FenceMonitor::loop, this); +} + +FenceMonitor::~FenceMonitor() { + { + std::lock_guard<std::mutex> lock(mMutex); + mStopped = true; + mCondition.notify_one(); + } + if (mThread.joinable()) { + mThread.join(); + } } void FenceMonitor::queueFence(const sp<Fence>& fence) { @@ -35,24 +44,26 @@ void FenceMonitor::queueFence(const sp<Fence>& fence) { std::lock_guard<std::mutex> lock(mMutex); if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) { - snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued); + snprintf(message, sizeof(message), "%s fence %u has signaled", mName.c_str(), + mFencesQueued); ATRACE_NAME(message); // Need an increment on both to make the trace number correct. mFencesQueued++; mFencesSignaled++; return; } - snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued); + snprintf(message, sizeof(message), "Trace %s fence %u", mName.c_str(), mFencesQueued); ATRACE_NAME(message); mQueue.push_back(fence); mCondition.notify_one(); mFencesQueued++; - ATRACE_INT(mName, int32_t(mQueue.size())); + ATRACE_INT(mName.c_str(), int32_t(mQueue.size())); } void FenceMonitor::loop() { - while (true) { + pthread_setname_np(pthread_self(), mName.c_str()); + while (!mStopped) { threadLoop(); } } @@ -62,15 +73,18 @@ void FenceMonitor::threadLoop() { uint32_t fenceNum; { std::unique_lock<std::mutex> lock(mMutex); - while (mQueue.empty()) { + while (mQueue.empty() && !mStopped) { mCondition.wait(lock); } + if (mStopped) { + return; + } fence = mQueue[0]; fenceNum = mFencesSignaled; } { char message[64]; - snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum); + snprintf(message, sizeof(message), "waiting for %s %u", mName.c_str(), fenceNum); ATRACE_NAME(message); status_t result = fence->waitForever(message); @@ -82,8 +96,8 @@ void FenceMonitor::threadLoop() { std::lock_guard<std::mutex> lock(mMutex); mQueue.pop_front(); mFencesSignaled++; - ATRACE_INT(mName, int32_t(mQueue.size())); + ATRACE_INT(mName.c_str(), int32_t(mQueue.size())); } } -} // namespace android::gui
\ No newline at end of file +} // namespace android::gui diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index d787d6cc45..868dbd06ec 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -20,6 +20,7 @@ #include <com_android_graphics_libgui_flags.h> #include <gui/BufferItem.h> #include <gui/BufferItemConsumer.h> +#include <gui/FenceMonitor.h> #include <gui/IGraphicBufferConsumer.h> #include <gui/IGraphicBufferProducer.h> #include <gui/SurfaceComposerClient.h> @@ -316,6 +317,8 @@ private: std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex); + std::optional<gui::FenceMonitor> mFenceMonitor GUARDED_BY(mMutex); + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) class BufferReleaseReader { public: diff --git a/libs/gui/include/gui/FenceMonitor.h b/libs/gui/include/gui/FenceMonitor.h index 62ceddee5f..ac5cc0a574 100644 --- a/libs/gui/include/gui/FenceMonitor.h +++ b/libs/gui/include/gui/FenceMonitor.h @@ -19,6 +19,7 @@ #include <cstdint> #include <deque> #include <mutex> +#include <thread> #include <ui/Fence.h> @@ -28,17 +29,20 @@ class FenceMonitor { public: explicit FenceMonitor(const char* name); void queueFence(const sp<Fence>& fence); + ~FenceMonitor(); private: void loop(); void threadLoop(); - const char* mName; + std::string mName; uint32_t mFencesQueued; uint32_t mFencesSignaled; std::deque<sp<Fence>> mQueue; std::condition_variable mCondition; std::mutex mMutex; + std::thread mThread; + std::atomic_bool mStopped = false; }; -} // namespace android::gui
\ No newline at end of file +} // namespace android::gui diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c8bb068fa9..c17ea3b579 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -769,6 +769,10 @@ void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult, // Older fences for the same layer stack can be dropped when a new fence arrives. // An assumption here is that RenderEngine performs work sequentially, so an // incoming fence will not fire before an existing fence. + SFTRACE_NAME( + ftl::Concat("Adding additional fence for: ", ftl::truncated<20>(mName.c_str()), + ", Replacing?: ", mAdditionalPreviousReleaseFences.contains(layerStack)) + .c_str()); mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack, std::move(futureFenceResult)); } diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp index c6856aea75..2b20648e42 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.cpp +++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp @@ -30,6 +30,7 @@ #include <binder/IInterface.h> #include <common/FlagManager.h> #include <common/trace.h> +#include <ftl/concat.h> #include <utils/RefBase.h> namespace android { @@ -129,6 +130,9 @@ status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>& if (FlagManager::getInstance().ce_fence_promise()) { for (auto& future : handle->previousReleaseFences) { + SFTRACE_NAME(ftl::Concat("Merging fence for layer: ", + ftl::truncated<20>(handle->name.c_str())) + .c_str()); mergeFence(handle->name.c_str(), future.get().value_or(Fence::NO_FENCE), prevFence); } } else { |