diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2023-04-05 10:55:26 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2023-04-05 10:55:26 +0000 |
commit | 34cf3256da02f62431adfa8228c0eb971e940034 (patch) | |
tree | f664a13a5659c157e363763709693661f0bca262 | |
parent | d294901e63fd57e884531a5dd7aea010770ec6f7 (diff) | |
parent | 243e2e9af82700c76f743ee71e0f27fe1a3f4383 (diff) | |
download | native-34cf3256da02f62431adfa8228c0eb971e940034.tar.gz |
Merge "DO NOT MERGE: Force input window updates when layer visibility changes" into tm-qpr-dev
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 15 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 5 |
4 files changed, 38 insertions, 12 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index aff94d132e..4593b40b7d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2391,16 +2391,7 @@ WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) { info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE; } - // 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.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !isVisibleForInput()); info.alpha = getAlpha(); fillTouchOcclusionMode(info); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 200baf0ba1..1724c150ad 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -471,6 +471,21 @@ 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 5db79999c8..1dfb1d3e9b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3249,19 +3249,34 @@ 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]() { + inputFlinger = mInputFlinger, this, + visibleLayersChanged]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { mWindowInfosListenerInvoker ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos), /* shouldSync= */ inputWindowCommands.syncInputWindows, /* forceImmediateCall= */ - !inputWindowCommands.focusRequests.empty()); + visibleLayersChanged || + !inputWindowCommands.focusRequests.empty()); } 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 3a45229ed3..a78144dea2 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1449,6 +1449,11 @@ 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 { |