diff options
author | 2024-11-16 03:38:36 +0000 | |
---|---|---|
committer | 2024-11-16 03:38:36 +0000 | |
commit | a60def99fb99f43ea33c6781cffca23fc6a027b0 (patch) | |
tree | 2497ba631e93fe43473e469725d461f4f1722f2f | |
parent | ff7a0f47d25d402a96aa05c2fd3eb588107b7004 (diff) | |
parent | b09293f068ddb3ce22c6bc2ce58295e4c80a0eeb (diff) |
Merge "Skip invisible windows in input list" into main
5 files changed, 73 insertions, 14 deletions
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp index 7569c1b8de..4d9a9ca06e 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp @@ -261,20 +261,25 @@ void updateVisibility(LayerSnapshot& snapshot, bool visible) { } snapshot.isVisible = visible; - // TODO(b/238781169) we are ignoring this compat for now, since we will have - // to remove any optimization based on visibility. - - // 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 visibleForInput = - snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible; - snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visibleForInput); + if (FlagManager::getInstance().skip_invisible_windows_in_input()) { + snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible); + } else { + // TODO(b/238781169) we are ignoring this compat for now, since we will have + // to remove any optimization based on visibility. + + // 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 visibleForInput = + snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible; + snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, + !visibleForInput); + } LLOGV(snapshot.sequence, "updating visibility %s %s", visible ? "true" : "false", snapshot.getDebugString().c_str()); } @@ -1260,6 +1265,10 @@ void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) con for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) { LayerSnapshot& snapshot = *mSnapshots[(size_t)i]; if (!snapshot.hasInputInfo()) continue; + if (FlagManager::getInstance().skip_invisible_windows_in_input() && + snapshot.inputInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)) { + continue; + } visitor(snapshot); } } diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index 12616e3edb..169fef9bde 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -159,6 +159,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(display_config_error_hal); DUMP_READ_ONLY_FLAG(connected_display_hdr); DUMP_READ_ONLY_FLAG(deprecate_frame_tracker); + DUMP_READ_ONLY_FLAG(skip_invisible_windows_in_input); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG @@ -266,6 +267,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(true_hdr_screenshots, "debug.sf.true_hdr_screenshots FLAG_MANAGER_READ_ONLY_FLAG(display_config_error_hal, ""); FLAG_MANAGER_READ_ONLY_FLAG(connected_display_hdr, ""); FLAG_MANAGER_READ_ONLY_FLAG(deprecate_frame_tracker, ""); +FLAG_MANAGER_READ_ONLY_FLAG(skip_invisible_windows_in_input, ""); /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(refresh_rate_overlay_on_external_display, "") diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index f5bea7237f..52435960f1 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -97,6 +97,7 @@ public: bool display_config_error_hal() const; bool connected_display_hdr() const; bool deprecate_frame_tracker() const; + bool skip_invisible_windows_in_input() const; protected: // overridden for unit tests diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig index 014c736a6b..6903941b4b 100644 --- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig @@ -196,6 +196,17 @@ flag { } # single_hop_screenshot flag { + name: "skip_invisible_windows_in_input" + namespace: "window_surfaces" + description: "Only send visible windows to input list" + bug: "305254099" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } + } # skip_invisible_windows_in_input + +flag { name: "true_hdr_screenshots" namespace: "core_graphics" description: "Enables screenshotting display content in HDR, sans tone mapping" diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 6aec7434de..8c53eef01a 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -1550,6 +1550,9 @@ TEST_F(LayerSnapshotTest, propagateDropInputMode) { } TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { + SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags:: + skip_invisible_windows_in_input, + false); LayerHierarchyTestBase::createRootLayer(3); setColor(3, {-1._hf, -1._hf, -1._hf}); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); @@ -1575,6 +1578,39 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { EXPECT_TRUE(foundInputLayer); } +TEST_F(LayerSnapshotTest, NonVisibleLayerWithInputShouldNotBeIncluded) { + SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags:: + skip_invisible_windows_in_input, + true); + LayerHierarchyTestBase::createRootLayer(3); + setColor(3, {-1._hf, -1._hf, -1._hf}); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + + std::vector<TransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; + transactions.back().states.front().layerId = 3; + transactions.back().states.front().state.windowInfoHandle = sp<gui::WindowInfoHandle>::make(); + auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + inputInfo->token = sp<BBinder>::make(); + hideLayer(3); + mLifecycleManager.applyTransactions(transactions); + + update(mSnapshotBuilder); + + bool foundInputLayer = false; + mSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) { + if (snapshot.uniqueSequence == 3) { + EXPECT_TRUE( + snapshot.inputInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)); + EXPECT_FALSE(snapshot.isVisible); + foundInputLayer = true; + } + }); + EXPECT_FALSE(foundInputLayer); +} + TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) { std::vector<uint32_t> visitedUniqueSequences; mSnapshotBuilder.forEachSnapshot( |