diff options
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 15 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 24 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/WindowInfosListenerInvoker.cpp | 93 | ||||
-rw-r--r-- | services/surfaceflinger/WindowInfosListenerInvoker.h | 12 |
6 files changed, 38 insertions, 122 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 4593b40b7d..aff94d132e 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2391,7 +2391,16 @@ WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) { info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE; } - info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !isVisibleForInput()); + // For compatibility reasons we let layers which can receive input + // receive input before they have actually submitted a buffer. Because + // of this we use canReceiveInput instead of isVisible to check the + // policy-visibility, ignoring the buffer state. However for layers with + // hasInputInfo()==false we can use the real visibility state. + // We are just using these layers for occlusion detection in + // InputDispatcher, and obviously if they aren't visible they can't occlude + // anything. + const bool visible = hasInputInfo() ? canReceiveInput() : isVisible(); + info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible); info.alpha = getAlpha(); fillTouchOcclusionMode(info); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 1724c150ad..200baf0ba1 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -471,21 +471,6 @@ public: virtual bool canReceiveInput() const; /* - * Whether or not the layer should be considered visible for input calculations. - */ - virtual bool isVisibleForInput() const { - // For compatibility reasons we let layers which can receive input - // receive input before they have actually submitted a buffer. Because - // of this we use canReceiveInput instead of isVisible to check the - // policy-visibility, ignoring the buffer state. However for layers with - // hasInputInfo()==false we can use the real visibility state. - // We are just using these layers for occlusion detection in - // InputDispatcher, and obviously if they aren't visible they can't occlude - // anything. - return hasInputInfo() ? canReceiveInput() : isVisible(); - } - - /* * isProtected - true if the layer may contain protected contents in the * GRALLOC_USAGE_PROTECTED sense. */ diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1dfb1d3e9b..494aa2c2cf 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3249,34 +3249,16 @@ void SurfaceFlinger::updateInputFlinger() { if (!updateWindowInfo && mInputWindowCommands.empty()) { return; } - - std::unordered_set<Layer*> visibleLayers; - mDrawingState.traverse([&visibleLayers](Layer* layer) { - if (layer->isVisibleForInput()) { - visibleLayers.insert(layer); - } - }); - bool visibleLayersChanged = false; - if (visibleLayers != mVisibleLayers) { - visibleLayersChanged = true; - mVisibleLayers = std::move(visibleLayers); - } - BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo, windowInfos = std::move(windowInfos), displayInfos = std::move(displayInfos), inputWindowCommands = std::move(mInputWindowCommands), - inputFlinger = mInputFlinger, this, - visibleLayersChanged]() { + inputFlinger = mInputFlinger, this]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { - mWindowInfosListenerInvoker - ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos), - /* shouldSync= */ inputWindowCommands.syncInputWindows, - /* forceImmediateCall= */ - visibleLayersChanged || - !inputWindowCommands.focusRequests.empty()); + mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos, + inputWindowCommands.syncInputWindows); } else if (inputWindowCommands.syncInputWindows) { // If the caller requested to sync input windows, but there are no // changes to input windows, notify immediately. diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a78144dea2..3a45229ed3 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1449,11 +1449,6 @@ private: nsecs_t mAnimationTransactionTimeout = s2ns(5); friend class SurfaceComposerAIDL; - - // Layers visible during the last commit. This set should only be used for testing set equality - // and membership. The pointers should not be dereferenced as it's possible the set contains - // pointers to freed layers. - std::unordered_set<Layer*> mVisibleLayers; }; class SurfaceComposerAIDL : public gui::BnSurfaceComposer { diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp index 023402f747..30b9d8f1cb 100644 --- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp +++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp @@ -28,26 +28,19 @@ using gui::WindowInfo; struct WindowInfosListenerInvoker::WindowInfosReportedListener : gui::BnWindowInfosReportedListener { - explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker, size_t callbackCount, - bool shouldSync) - : mInvoker(invoker), mCallbacksPending(callbackCount), mShouldSync(shouldSync) {} + explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker) : mInvoker(invoker) {} binder::Status onWindowInfosReported() override { - mCallbacksPending--; - if (mCallbacksPending == 0) { - mInvoker.windowInfosReported(mShouldSync); - } + mInvoker.windowInfosReported(); return binder::Status::ok(); } -private: WindowInfosListenerInvoker& mInvoker; - std::atomic<size_t> mCallbacksPending; - bool mShouldSync; }; WindowInfosListenerInvoker::WindowInfosListenerInvoker(SurfaceFlinger& flinger) - : mFlinger(flinger) {} + : mFlinger(flinger), + mWindowInfosReportedListener(sp<WindowInfosReportedListener>::make(*this)) {} void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) { sp<IBinder> asBinder = IInterface::asBinder(listener); @@ -71,76 +64,30 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) { mWindowInfosListeners.erase(who); } -void WindowInfosListenerInvoker::windowInfosChanged(std::vector<WindowInfo> windowInfos, - std::vector<DisplayInfo> displayInfos, - bool shouldSync, bool forceImmediateCall) { - auto callListeners = [this, windowInfos = std::move(windowInfos), - displayInfos = std::move(displayInfos)](bool shouldSync) mutable { - ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners; - { - std::scoped_lock lock(mListenersMutex); - for (const auto& [_, listener] : mWindowInfosListeners) { - windowInfosListeners.push_back(listener); - } - } - - auto reportedListener = - sp<WindowInfosReportedListener>::make(*this, windowInfosListeners.size(), - shouldSync); - - for (const auto& listener : windowInfosListeners) { - auto status = - listener->onWindowInfosChanged(windowInfos, displayInfos, reportedListener); - if (!status.isOk()) { - reportedListener->onWindowInfosReported(); - } - } - }; - +void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos, + const std::vector<DisplayInfo>& displayInfos, + bool shouldSync) { + ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners; { - 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); - mShouldSyncDelayed |= shouldSync; - return; + std::scoped_lock lock(mListenersMutex); + for (const auto& [_, listener] : mWindowInfosListeners) { + windowInfosListeners.push_back(listener); } + } - mWindowInfosChangedDelayed = nullptr; - shouldSync |= mShouldSyncDelayed; - mShouldSyncDelayed = false; - mActiveMessageCount++; + mCallbacksPending = windowInfosListeners.size(); + + for (const auto& listener : windowInfosListeners) { + listener->onWindowInfosChanged(windowInfos, displayInfos, + shouldSync ? mWindowInfosReportedListener : nullptr); } - callListeners(shouldSync); } -void WindowInfosListenerInvoker::windowInfosReported(bool shouldSync) { - if (shouldSync) { +void WindowInfosListenerInvoker::windowInfosReported() { + mCallbacksPending--; + if (mCallbacksPending == 0) { mFlinger.windowInfosReported(); } - - std::function<void(bool)> callListeners; - bool shouldSyncDelayed; - { - std::scoped_lock lock{mMessagesMutex}; - mActiveMessageCount--; - if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) { - return; - } - - mActiveMessageCount++; - callListeners = std::move(mWindowInfosChangedDelayed); - mWindowInfosChangedDelayed = nullptr; - shouldSyncDelayed = mShouldSyncDelayed; - mShouldSyncDelayed = false; - } - - callListeners(shouldSyncDelayed); } } // namespace android diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h index 701f11efcd..d8d8d0f570 100644 --- a/services/surfaceflinger/WindowInfosListenerInvoker.h +++ b/services/surfaceflinger/WindowInfosListenerInvoker.h @@ -34,15 +34,15 @@ public: void addWindowInfosListener(sp<gui::IWindowInfosListener>); void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); - void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>, - bool shouldSync, bool forceImmediateCall); + void windowInfosChanged(const std::vector<gui::WindowInfo>&, + const std::vector<gui::DisplayInfo>&, bool shouldSync); protected: void binderDied(const wp<IBinder>& who) override; private: struct WindowInfosReportedListener; - void windowInfosReported(bool shouldSync); + void windowInfosReported(); SurfaceFlinger& mFlinger; std::mutex mListenersMutex; @@ -51,10 +51,8 @@ private: ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity> mWindowInfosListeners GUARDED_BY(mListenersMutex); - std::mutex mMessagesMutex; - uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0; - std::function<void(bool)> mWindowInfosChangedDelayed GUARDED_BY(mMessagesMutex); - bool mShouldSyncDelayed; + sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener; + std::atomic<size_t> mCallbacksPending{0}; }; } // namespace android |