Loading libs/gui/BLASTBufferQueue.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading libs/gui/FenceMonitor.cpp +25 −11 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); } } Loading @@ -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); Loading @@ -82,7 +96,7 @@ 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())); } } Loading libs/gui/include/gui/BLASTBufferQueue.h +3 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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: Loading libs/gui/include/gui/FenceMonitor.h +6 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <cstdint> #include <deque> #include <mutex> #include <thread> #include <ui/Fence.h> Loading @@ -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 services/surfaceflinger/Layer.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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)); } Loading Loading
libs/gui/BLASTBufferQueue.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading
libs/gui/FenceMonitor.cpp +25 −11 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); } } Loading @@ -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); Loading @@ -82,7 +96,7 @@ 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())); } } Loading
libs/gui/include/gui/BLASTBufferQueue.h +3 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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: Loading
libs/gui/include/gui/FenceMonitor.h +6 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <cstdint> #include <deque> #include <mutex> #include <thread> #include <ui/Fence.h> Loading @@ -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
services/surfaceflinger/Layer.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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)); } Loading