Loading services/surfaceflinger/SurfaceFlinger.cpp +15 −29 Original line number Original line Diff line number Diff line Loading @@ -2529,7 +2529,7 @@ bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expe } } updateCursorAsync(); updateCursorAsync(); updateInputFlinger(vsyncId); updateInputFlinger(vsyncId, frameTime); if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { // This will block and tracing should only be enabled for debugging. // This will block and tracing should only be enabled for debugging. Loading Loading @@ -3723,7 +3723,7 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { doCommitTransactions(); doCommitTransactions(); } } void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) { if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) { if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) { return; return; } } Loading @@ -3735,8 +3735,6 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { if (mUpdateInputInfo) { if (mUpdateInputInfo) { mUpdateInputInfo = false; mUpdateInputInfo = false; updateWindowInfo = true; updateWindowInfo = true; mLastInputFlingerUpdateVsyncId = vsyncId; mLastInputFlingerUpdateTimestamp = systemTime(); buildWindowInfos(windowInfos, displayInfos); buildWindowInfos(windowInfos, displayInfos); } } Loading @@ -3758,17 +3756,18 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { inputWindowCommands = inputWindowCommands = std::move(mInputWindowCommands), std::move(mInputWindowCommands), inputFlinger = mInputFlinger, this, inputFlinger = mInputFlinger, this, visibleWindowsChanged]() { visibleWindowsChanged, vsyncId, frameTime]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { if (updateWindowInfo) { mWindowInfosListenerInvoker mWindowInfosListenerInvoker ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos), ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos), std::move(displayInfos), ftl::to_underlying(vsyncId), frameTime.ns()}, std::move( std::move( inputWindowCommands.windowInfosReportedListeners), inputWindowCommands.windowInfosReportedListeners), /* forceImmediateCall= */ visibleWindowsChanged || /* forceImmediateCall= */ visibleWindowsChanged || !inputWindowCommands.focusRequests.empty(), !inputWindowCommands.focusRequests.empty()); mLastInputFlingerUpdateVsyncId, mLastInputFlingerUpdateTimestamp); } else { } else { // If there are listeners but no changes to input windows, call the listeners // If there are listeners but no changes to input windows, call the listeners // immediately. // immediately. Loading Loading @@ -6143,27 +6142,14 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, const std::string& comp result.append("\n"); result.append("\n"); result.append("Window Infos:\n"); result.append("Window Infos:\n"); StringAppendF(&result, " input flinger update vsync id: %" PRId64 "\n", auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo(); ftl::to_underlying(mLastInputFlingerUpdateVsyncId)); StringAppendF(&result, " max send vsync id: %" PRId64 "\n", StringAppendF(&result, " input flinger update timestamp (ns): %" PRId64 "\n", ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId)); mLastInputFlingerUpdateTimestamp); StringAppendF(&result, " max send delay (ns): %" PRId64 " ns\n", windowInfosDebug.maxSendDelayDuration); StringAppendF(&result, " unsent messages: %" PRIu32 "\n", windowInfosDebug.pendingMessageCount); result.append("\n"); result.append("\n"); if (VsyncId unsentVsyncId = mWindowInfosListenerInvoker->getUnsentMessageVsyncId(); unsentVsyncId != VsyncId()) { StringAppendF(&result, " unsent input flinger update vsync id: %" PRId64 "\n", ftl::to_underlying(unsentVsyncId)); StringAppendF(&result, " unsent input flinger update timestamp (ns): %" PRId64 "\n", mWindowInfosListenerInvoker->getUnsentMessageTimestamp()); result.append("\n"); } if (uint32_t pendingMessages = mWindowInfosListenerInvoker->getPendingMessageCount(); pendingMessages != 0) { StringAppendF(&result, " pending input flinger calls: %" PRIu32 "\n", mWindowInfosListenerInvoker->getPendingMessageCount()); result.append("\n"); } } } mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { Loading services/surfaceflinger/SurfaceFlinger.h +1 −4 Original line number Original line Diff line number Diff line Loading @@ -718,7 +718,7 @@ private: void updateLayerHistory(const frontend::LayerSnapshot& snapshot); void updateLayerHistory(const frontend::LayerSnapshot& snapshot); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, std::vector<gui::DisplayInfo>& outDisplayInfos); std::vector<gui::DisplayInfo>& outDisplayInfos); Loading Loading @@ -1250,9 +1250,6 @@ private: VsyncId mLastCommittedVsyncId; VsyncId mLastCommittedVsyncId; VsyncId mLastInputFlingerUpdateVsyncId; nsecs_t mLastInputFlingerUpdateTimestamp; // If blurs should be enabled on this device. // If blurs should be enabled on this device. bool mSupportsBlur = false; bool mSupportsBlur = false; std::atomic<uint32_t> mFrameMissedCount = 0; std::atomic<uint32_t> mFrameMissedCount = 0; Loading services/surfaceflinger/WindowInfosListenerInvoker.cpp +84 −64 Original line number Original line Diff line number Diff line Loading @@ -16,8 +16,11 @@ #include <ftl/small_vector.h> #include <ftl/small_vector.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h> #include <gui/TraceUtils.h> #include <gui/WindowInfosUpdate.h> #include <gui/WindowInfosUpdate.h> #include <scheduler/Time.h> #include "BackgroundExecutor.h" #include "WindowInfosListenerInvoker.h" #include "WindowInfosListenerInvoker.h" namespace android { namespace android { Loading @@ -26,7 +29,7 @@ using gui::DisplayInfo; using gui::IWindowInfosListener; using gui::IWindowInfosListener; using gui::WindowInfo; using gui::WindowInfo; using WindowInfosListenerVector = ftl::SmallVector<const sp<IWindowInfosListener>, 3>; using WindowInfosListenerVector = ftl::SmallVector<const sp<gui::IWindowInfosListener>, 3>; struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener, struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener, IBinder::DeathRecipient { IBinder::DeathRecipient { Loading Loading @@ -86,29 +89,60 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) { } } void WindowInfosListenerInvoker::windowInfosChanged( void WindowInfosListenerInvoker::windowInfosChanged( std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos, gui::WindowInfosUpdate update, WindowInfosReportedListenerSet reportedListeners, WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall, VsyncId vsyncId, bool forceImmediateCall) { nsecs_t timestamp) { WindowInfosListenerVector listeners; reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this)); auto callListeners = [this, windowInfos = std::move(windowInfos), displayInfos = std::move(displayInfos), vsyncId, timestamp](WindowInfosReportedListenerSet reportedListeners) mutable { WindowInfosListenerVector windowInfosListeners; { { std::scoped_lock lock(mListenersMutex); std::scoped_lock lock{mMessagesMutex}; if (!mDelayInfo) { mDelayInfo = DelayInfo{ .vsyncId = update.vsyncId, .frameTime = update.timestamp, }; } // If there are unacked messages and this isn't a forced call, then return immediately. // If a forced window infos change doesn't happen first, the update will be sent after // the WindowInfosReportedListeners are called. If a forced window infos change happens or // if there are subsequent delayed messages before this update is sent, then this message // will be dropped and the listeners will only be called with the latest info. This is done // to reduce the amount of binder memory used. if (mActiveMessageCount > 0 && !forceImmediateCall) { mDelayedUpdate = std::move(update); mReportedListeners.merge(reportedListeners); return; } if (mDelayedUpdate) { mDelayedUpdate.reset(); } { std::scoped_lock lock{mListenersMutex}; for (const auto& [_, listener] : mWindowInfosListeners) { for (const auto& [_, listener] : mWindowInfosListeners) { windowInfosListeners.push_back(listener); listeners.push_back(listener); } } } } if (CC_UNLIKELY(listeners.empty())) { mReportedListeners.merge(reportedListeners); mDelayInfo.reset(); return; } auto reportedInvoker = reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this)); sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners, reportedListeners.merge(mReportedListeners); std::move(reportedListeners)); mReportedListeners.clear(); gui::WindowInfosUpdate update(std::move(windowInfos), std::move(displayInfos), mActiveMessageCount++; ftl::to_underlying(vsyncId), timestamp); updateMaxSendDelay(); mDelayInfo.reset(); } for (const auto& listener : windowInfosListeners) { auto reportedInvoker = sp<WindowInfosReportedListenerInvoker>::make(listeners, std::move(reportedListeners)); for (const auto& listener : listeners) { sp<IBinder> asBinder = IInterface::asBinder(listener); sp<IBinder> asBinder = IInterface::asBinder(listener); // linkToDeath is used here to ensure that the windowInfosReportedListeners // linkToDeath is used here to ensure that the windowInfosReportedListeners Loading @@ -121,55 +155,41 @@ void WindowInfosListenerInvoker::windowInfosChanged( reportedInvoker->onWindowInfosReported(); reportedInvoker->onWindowInfosReported(); } } } } }; { std::scoped_lock lock(mMessagesMutex); // If there are unacked messages and this isn't a forced call, then return immediately. // If a forced window infos change doesn't happen first, the update will be sent after // the WindowInfosReportedListeners are called. If a forced window infos change happens or // if there are subsequent delayed messages before this update is sent, then this message // will be dropped and the listeners will only be called with the latest info. This is done // to reduce the amount of binder memory used. if (mActiveMessageCount > 0 && !forceImmediateCall) { mWindowInfosChangedDelayed = std::move(callListeners); mUnsentVsyncId = vsyncId; mUnsentTimestamp = timestamp; mReportedListenersDelayed.merge(reportedListeners); return; } mWindowInfosChangedDelayed = nullptr; mUnsentVsyncId = VsyncId(); mUnsentTimestamp = -1; reportedListeners.merge(mReportedListenersDelayed); mActiveMessageCount++; } callListeners(std::move(reportedListeners)); } } binder::Status WindowInfosListenerInvoker::onWindowInfosReported() { binder::Status WindowInfosListenerInvoker::onWindowInfosReported() { std::function<void(WindowInfosReportedListenerSet)> callListeners; BackgroundExecutor::getInstance().sendCallbacks({[this]() { WindowInfosReportedListenerSet reportedListeners; gui::WindowInfosUpdate update; { { std::scoped_lock lock{mMessagesMutex}; std::scoped_lock lock{mMessagesMutex}; mActiveMessageCount--; mActiveMessageCount--; if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) { if (!mDelayedUpdate || mActiveMessageCount > 0) { return; } update = std::move(*mDelayedUpdate); mDelayedUpdate.reset(); } windowInfosChanged(std::move(update), {}, false); }}); return binder::Status::ok(); return binder::Status::ok(); } } mActiveMessageCount++; WindowInfosListenerInvoker::DebugInfo WindowInfosListenerInvoker::getDebugInfo() { callListeners = std::move(mWindowInfosChangedDelayed); std::scoped_lock lock{mMessagesMutex}; mWindowInfosChangedDelayed = nullptr; updateMaxSendDelay(); mUnsentVsyncId = VsyncId(); mDebugInfo.pendingMessageCount = mActiveMessageCount; mUnsentTimestamp = -1; return mDebugInfo; reportedListeners = std::move(mReportedListenersDelayed); mReportedListenersDelayed.clear(); } } callListeners(std::move(reportedListeners)); void WindowInfosListenerInvoker::updateMaxSendDelay() { return binder::Status::ok(); if (!mDelayInfo) { return; } nsecs_t delay = TimePoint::now().ns() - mDelayInfo->frameTime; if (delay > mDebugInfo.maxSendDelayDuration) { mDebugInfo.maxSendDelayDuration = delay; mDebugInfo.maxSendDelayVsyncId = VsyncId{mDelayInfo->vsyncId}; } } } } // namespace android } // namespace android services/surfaceflinger/WindowInfosListenerInvoker.h +19 −21 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #pragma once #include <optional> #include <unordered_set> #include <unordered_set> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/BnWindowInfosReportedListener.h> Loading @@ -40,26 +41,18 @@ public: void addWindowInfosListener(sp<gui::IWindowInfosListener>); void addWindowInfosListener(sp<gui::IWindowInfosListener>); void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>, void windowInfosChanged(gui::WindowInfosUpdate update, WindowInfosReportedListenerSet windowInfosReportedListeners, WindowInfosReportedListenerSet windowInfosReportedListeners, bool forceImmediateCall, VsyncId vsyncId, nsecs_t timestamp); bool forceImmediateCall); binder::Status onWindowInfosReported() override; binder::Status onWindowInfosReported() override; VsyncId getUnsentMessageVsyncId() { struct DebugInfo { std::scoped_lock lock(mMessagesMutex); VsyncId maxSendDelayVsyncId; return mUnsentVsyncId; nsecs_t maxSendDelayDuration; } uint32_t pendingMessageCount; }; nsecs_t getUnsentMessageTimestamp() { DebugInfo getDebugInfo(); std::scoped_lock lock(mMessagesMutex); return mUnsentTimestamp; } uint32_t getPendingMessageCount() { std::scoped_lock lock(mMessagesMutex); return mActiveMessageCount; } protected: protected: void binderDied(const wp<IBinder>& who) override; void binderDied(const wp<IBinder>& who) override; Loading @@ -73,11 +66,16 @@ private: std::mutex mMessagesMutex; std::mutex mMessagesMutex; uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0; uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0; std::function<void(WindowInfosReportedListenerSet)> mWindowInfosChangedDelayed std::optional<gui::WindowInfosUpdate> mDelayedUpdate GUARDED_BY(mMessagesMutex); GUARDED_BY(mMessagesMutex); WindowInfosReportedListenerSet mReportedListeners; VsyncId mUnsentVsyncId GUARDED_BY(mMessagesMutex); nsecs_t mUnsentTimestamp GUARDED_BY(mMessagesMutex) = -1; DebugInfo mDebugInfo GUARDED_BY(mMessagesMutex); WindowInfosReportedListenerSet mReportedListenersDelayed; struct DelayInfo { int64_t vsyncId; nsecs_t frameTime; }; std::optional<DelayInfo> mDelayInfo GUARDED_BY(mMessagesMutex); void updateMaxSendDelay() REQUIRES(mMessagesMutex); }; }; } // namespace android } // namespace android services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -590,7 +590,7 @@ public: mFlinger->binderDied(display); mFlinger->binderDied(display); mFlinger->onFirstRef(); mFlinger->onFirstRef(); mFlinger->updateInputFlinger(VsyncId{0}); mFlinger->updateInputFlinger(VsyncId{}, TimePoint{}); mFlinger->updateCursorAsync(); mFlinger->updateCursorAsync(); mutableScheduler().setVsyncConfig({.sfOffset = mFdp.ConsumeIntegral<nsecs_t>(), mutableScheduler().setVsyncConfig({.sfOffset = mFdp.ConsumeIntegral<nsecs_t>(), Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +15 −29 Original line number Original line Diff line number Diff line Loading @@ -2529,7 +2529,7 @@ bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expe } } updateCursorAsync(); updateCursorAsync(); updateInputFlinger(vsyncId); updateInputFlinger(vsyncId, frameTime); if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) { // This will block and tracing should only be enabled for debugging. // This will block and tracing should only be enabled for debugging. Loading Loading @@ -3723,7 +3723,7 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { doCommitTransactions(); doCommitTransactions(); } } void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) { if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) { if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) { return; return; } } Loading @@ -3735,8 +3735,6 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { if (mUpdateInputInfo) { if (mUpdateInputInfo) { mUpdateInputInfo = false; mUpdateInputInfo = false; updateWindowInfo = true; updateWindowInfo = true; mLastInputFlingerUpdateVsyncId = vsyncId; mLastInputFlingerUpdateTimestamp = systemTime(); buildWindowInfos(windowInfos, displayInfos); buildWindowInfos(windowInfos, displayInfos); } } Loading @@ -3758,17 +3756,18 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) { inputWindowCommands = inputWindowCommands = std::move(mInputWindowCommands), std::move(mInputWindowCommands), inputFlinger = mInputFlinger, this, inputFlinger = mInputFlinger, this, visibleWindowsChanged]() { visibleWindowsChanged, vsyncId, frameTime]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { if (updateWindowInfo) { mWindowInfosListenerInvoker mWindowInfosListenerInvoker ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos), ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos), std::move(displayInfos), ftl::to_underlying(vsyncId), frameTime.ns()}, std::move( std::move( inputWindowCommands.windowInfosReportedListeners), inputWindowCommands.windowInfosReportedListeners), /* forceImmediateCall= */ visibleWindowsChanged || /* forceImmediateCall= */ visibleWindowsChanged || !inputWindowCommands.focusRequests.empty(), !inputWindowCommands.focusRequests.empty()); mLastInputFlingerUpdateVsyncId, mLastInputFlingerUpdateTimestamp); } else { } else { // If there are listeners but no changes to input windows, call the listeners // If there are listeners but no changes to input windows, call the listeners // immediately. // immediately. Loading Loading @@ -6143,27 +6142,14 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, const std::string& comp result.append("\n"); result.append("\n"); result.append("Window Infos:\n"); result.append("Window Infos:\n"); StringAppendF(&result, " input flinger update vsync id: %" PRId64 "\n", auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo(); ftl::to_underlying(mLastInputFlingerUpdateVsyncId)); StringAppendF(&result, " max send vsync id: %" PRId64 "\n", StringAppendF(&result, " input flinger update timestamp (ns): %" PRId64 "\n", ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId)); mLastInputFlingerUpdateTimestamp); StringAppendF(&result, " max send delay (ns): %" PRId64 " ns\n", windowInfosDebug.maxSendDelayDuration); StringAppendF(&result, " unsent messages: %" PRIu32 "\n", windowInfosDebug.pendingMessageCount); result.append("\n"); result.append("\n"); if (VsyncId unsentVsyncId = mWindowInfosListenerInvoker->getUnsentMessageVsyncId(); unsentVsyncId != VsyncId()) { StringAppendF(&result, " unsent input flinger update vsync id: %" PRId64 "\n", ftl::to_underlying(unsentVsyncId)); StringAppendF(&result, " unsent input flinger update timestamp (ns): %" PRId64 "\n", mWindowInfosListenerInvoker->getUnsentMessageTimestamp()); result.append("\n"); } if (uint32_t pendingMessages = mWindowInfosListenerInvoker->getPendingMessageCount(); pendingMessages != 0) { StringAppendF(&result, " pending input flinger calls: %" PRIu32 "\n", mWindowInfosListenerInvoker->getPendingMessageCount()); result.append("\n"); } } } mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { Loading
services/surfaceflinger/SurfaceFlinger.h +1 −4 Original line number Original line Diff line number Diff line Loading @@ -718,7 +718,7 @@ private: void updateLayerHistory(const frontend::LayerSnapshot& snapshot); void updateLayerHistory(const frontend::LayerSnapshot& snapshot); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, std::vector<gui::DisplayInfo>& outDisplayInfos); std::vector<gui::DisplayInfo>& outDisplayInfos); Loading Loading @@ -1250,9 +1250,6 @@ private: VsyncId mLastCommittedVsyncId; VsyncId mLastCommittedVsyncId; VsyncId mLastInputFlingerUpdateVsyncId; nsecs_t mLastInputFlingerUpdateTimestamp; // If blurs should be enabled on this device. // If blurs should be enabled on this device. bool mSupportsBlur = false; bool mSupportsBlur = false; std::atomic<uint32_t> mFrameMissedCount = 0; std::atomic<uint32_t> mFrameMissedCount = 0; Loading
services/surfaceflinger/WindowInfosListenerInvoker.cpp +84 −64 Original line number Original line Diff line number Diff line Loading @@ -16,8 +16,11 @@ #include <ftl/small_vector.h> #include <ftl/small_vector.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h> #include <gui/TraceUtils.h> #include <gui/WindowInfosUpdate.h> #include <gui/WindowInfosUpdate.h> #include <scheduler/Time.h> #include "BackgroundExecutor.h" #include "WindowInfosListenerInvoker.h" #include "WindowInfosListenerInvoker.h" namespace android { namespace android { Loading @@ -26,7 +29,7 @@ using gui::DisplayInfo; using gui::IWindowInfosListener; using gui::IWindowInfosListener; using gui::WindowInfo; using gui::WindowInfo; using WindowInfosListenerVector = ftl::SmallVector<const sp<IWindowInfosListener>, 3>; using WindowInfosListenerVector = ftl::SmallVector<const sp<gui::IWindowInfosListener>, 3>; struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener, struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener, IBinder::DeathRecipient { IBinder::DeathRecipient { Loading Loading @@ -86,29 +89,60 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) { } } void WindowInfosListenerInvoker::windowInfosChanged( void WindowInfosListenerInvoker::windowInfosChanged( std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos, gui::WindowInfosUpdate update, WindowInfosReportedListenerSet reportedListeners, WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall, VsyncId vsyncId, bool forceImmediateCall) { nsecs_t timestamp) { WindowInfosListenerVector listeners; reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this)); auto callListeners = [this, windowInfos = std::move(windowInfos), displayInfos = std::move(displayInfos), vsyncId, timestamp](WindowInfosReportedListenerSet reportedListeners) mutable { WindowInfosListenerVector windowInfosListeners; { { std::scoped_lock lock(mListenersMutex); std::scoped_lock lock{mMessagesMutex}; if (!mDelayInfo) { mDelayInfo = DelayInfo{ .vsyncId = update.vsyncId, .frameTime = update.timestamp, }; } // If there are unacked messages and this isn't a forced call, then return immediately. // If a forced window infos change doesn't happen first, the update will be sent after // the WindowInfosReportedListeners are called. If a forced window infos change happens or // if there are subsequent delayed messages before this update is sent, then this message // will be dropped and the listeners will only be called with the latest info. This is done // to reduce the amount of binder memory used. if (mActiveMessageCount > 0 && !forceImmediateCall) { mDelayedUpdate = std::move(update); mReportedListeners.merge(reportedListeners); return; } if (mDelayedUpdate) { mDelayedUpdate.reset(); } { std::scoped_lock lock{mListenersMutex}; for (const auto& [_, listener] : mWindowInfosListeners) { for (const auto& [_, listener] : mWindowInfosListeners) { windowInfosListeners.push_back(listener); listeners.push_back(listener); } } } } if (CC_UNLIKELY(listeners.empty())) { mReportedListeners.merge(reportedListeners); mDelayInfo.reset(); return; } auto reportedInvoker = reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this)); sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners, reportedListeners.merge(mReportedListeners); std::move(reportedListeners)); mReportedListeners.clear(); gui::WindowInfosUpdate update(std::move(windowInfos), std::move(displayInfos), mActiveMessageCount++; ftl::to_underlying(vsyncId), timestamp); updateMaxSendDelay(); mDelayInfo.reset(); } for (const auto& listener : windowInfosListeners) { auto reportedInvoker = sp<WindowInfosReportedListenerInvoker>::make(listeners, std::move(reportedListeners)); for (const auto& listener : listeners) { sp<IBinder> asBinder = IInterface::asBinder(listener); sp<IBinder> asBinder = IInterface::asBinder(listener); // linkToDeath is used here to ensure that the windowInfosReportedListeners // linkToDeath is used here to ensure that the windowInfosReportedListeners Loading @@ -121,55 +155,41 @@ void WindowInfosListenerInvoker::windowInfosChanged( reportedInvoker->onWindowInfosReported(); reportedInvoker->onWindowInfosReported(); } } } } }; { std::scoped_lock lock(mMessagesMutex); // If there are unacked messages and this isn't a forced call, then return immediately. // If a forced window infos change doesn't happen first, the update will be sent after // the WindowInfosReportedListeners are called. If a forced window infos change happens or // if there are subsequent delayed messages before this update is sent, then this message // will be dropped and the listeners will only be called with the latest info. This is done // to reduce the amount of binder memory used. if (mActiveMessageCount > 0 && !forceImmediateCall) { mWindowInfosChangedDelayed = std::move(callListeners); mUnsentVsyncId = vsyncId; mUnsentTimestamp = timestamp; mReportedListenersDelayed.merge(reportedListeners); return; } mWindowInfosChangedDelayed = nullptr; mUnsentVsyncId = VsyncId(); mUnsentTimestamp = -1; reportedListeners.merge(mReportedListenersDelayed); mActiveMessageCount++; } callListeners(std::move(reportedListeners)); } } binder::Status WindowInfosListenerInvoker::onWindowInfosReported() { binder::Status WindowInfosListenerInvoker::onWindowInfosReported() { std::function<void(WindowInfosReportedListenerSet)> callListeners; BackgroundExecutor::getInstance().sendCallbacks({[this]() { WindowInfosReportedListenerSet reportedListeners; gui::WindowInfosUpdate update; { { std::scoped_lock lock{mMessagesMutex}; std::scoped_lock lock{mMessagesMutex}; mActiveMessageCount--; mActiveMessageCount--; if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) { if (!mDelayedUpdate || mActiveMessageCount > 0) { return; } update = std::move(*mDelayedUpdate); mDelayedUpdate.reset(); } windowInfosChanged(std::move(update), {}, false); }}); return binder::Status::ok(); return binder::Status::ok(); } } mActiveMessageCount++; WindowInfosListenerInvoker::DebugInfo WindowInfosListenerInvoker::getDebugInfo() { callListeners = std::move(mWindowInfosChangedDelayed); std::scoped_lock lock{mMessagesMutex}; mWindowInfosChangedDelayed = nullptr; updateMaxSendDelay(); mUnsentVsyncId = VsyncId(); mDebugInfo.pendingMessageCount = mActiveMessageCount; mUnsentTimestamp = -1; return mDebugInfo; reportedListeners = std::move(mReportedListenersDelayed); mReportedListenersDelayed.clear(); } } callListeners(std::move(reportedListeners)); void WindowInfosListenerInvoker::updateMaxSendDelay() { return binder::Status::ok(); if (!mDelayInfo) { return; } nsecs_t delay = TimePoint::now().ns() - mDelayInfo->frameTime; if (delay > mDebugInfo.maxSendDelayDuration) { mDebugInfo.maxSendDelayDuration = delay; mDebugInfo.maxSendDelayVsyncId = VsyncId{mDelayInfo->vsyncId}; } } } } // namespace android } // namespace android
services/surfaceflinger/WindowInfosListenerInvoker.h +19 −21 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #pragma once #include <optional> #include <unordered_set> #include <unordered_set> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/BnWindowInfosReportedListener.h> Loading @@ -40,26 +41,18 @@ public: void addWindowInfosListener(sp<gui::IWindowInfosListener>); void addWindowInfosListener(sp<gui::IWindowInfosListener>); void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>, void windowInfosChanged(gui::WindowInfosUpdate update, WindowInfosReportedListenerSet windowInfosReportedListeners, WindowInfosReportedListenerSet windowInfosReportedListeners, bool forceImmediateCall, VsyncId vsyncId, nsecs_t timestamp); bool forceImmediateCall); binder::Status onWindowInfosReported() override; binder::Status onWindowInfosReported() override; VsyncId getUnsentMessageVsyncId() { struct DebugInfo { std::scoped_lock lock(mMessagesMutex); VsyncId maxSendDelayVsyncId; return mUnsentVsyncId; nsecs_t maxSendDelayDuration; } uint32_t pendingMessageCount; }; nsecs_t getUnsentMessageTimestamp() { DebugInfo getDebugInfo(); std::scoped_lock lock(mMessagesMutex); return mUnsentTimestamp; } uint32_t getPendingMessageCount() { std::scoped_lock lock(mMessagesMutex); return mActiveMessageCount; } protected: protected: void binderDied(const wp<IBinder>& who) override; void binderDied(const wp<IBinder>& who) override; Loading @@ -73,11 +66,16 @@ private: std::mutex mMessagesMutex; std::mutex mMessagesMutex; uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0; uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0; std::function<void(WindowInfosReportedListenerSet)> mWindowInfosChangedDelayed std::optional<gui::WindowInfosUpdate> mDelayedUpdate GUARDED_BY(mMessagesMutex); GUARDED_BY(mMessagesMutex); WindowInfosReportedListenerSet mReportedListeners; VsyncId mUnsentVsyncId GUARDED_BY(mMessagesMutex); nsecs_t mUnsentTimestamp GUARDED_BY(mMessagesMutex) = -1; DebugInfo mDebugInfo GUARDED_BY(mMessagesMutex); WindowInfosReportedListenerSet mReportedListenersDelayed; struct DelayInfo { int64_t vsyncId; nsecs_t frameTime; }; std::optional<DelayInfo> mDelayInfo GUARDED_BY(mMessagesMutex); void updateMaxSendDelay() REQUIRES(mMessagesMutex); }; }; } // namespace android } // namespace android
services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -590,7 +590,7 @@ public: mFlinger->binderDied(display); mFlinger->binderDied(display); mFlinger->onFirstRef(); mFlinger->onFirstRef(); mFlinger->updateInputFlinger(VsyncId{0}); mFlinger->updateInputFlinger(VsyncId{}, TimePoint{}); mFlinger->updateCursorAsync(); mFlinger->updateCursorAsync(); mutableScheduler().setVsyncConfig({.sfOffset = mFdp.ConsumeIntegral<nsecs_t>(), mutableScheduler().setVsyncConfig({.sfOffset = mFdp.ConsumeIntegral<nsecs_t>(), Loading