Skip to content

Commit b09293f

Browse files
author
Wenhui Yang
committed
Skip invisible windows in input list
To reduce traffic sent over binder and the number of copied objects in native code, we decide to remove windows from WindowInfosListener that are not visible because input doesn't need to know about the windows that aren't visible, and invisible windows don't affect the operation of other windows. Fixes: 305254099 Test: adb shell su root dumpsys SurfaceFlinger Test: atest LayerSnapshotTest Flag: EXEMPT bugfix Change-Id: I1ccc29565ee92277a703d16c07fd1141d6df6862
1 parent 28c8e15 commit b09293f

5 files changed

Lines changed: 73 additions & 14 deletions

File tree

services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,20 +261,25 @@ void updateVisibility(LayerSnapshot& snapshot, bool visible) {
261261
}
262262
snapshot.isVisible = visible;
263263

264-
// TODO(b/238781169) we are ignoring this compat for now, since we will have
265-
// to remove any optimization based on visibility.
266-
267-
// For compatibility reasons we let layers which can receive input
268-
// receive input before they have actually submitted a buffer. Because
269-
// of this we use canReceiveInput instead of isVisible to check the
270-
// policy-visibility, ignoring the buffer state. However for layers with
271-
// hasInputInfo()==false we can use the real visibility state.
272-
// We are just using these layers for occlusion detection in
273-
// InputDispatcher, and obviously if they aren't visible they can't occlude
274-
// anything.
275-
const bool visibleForInput =
276-
snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible;
277-
snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visibleForInput);
264+
if (FlagManager::getInstance().skip_invisible_windows_in_input()) {
265+
snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible);
266+
} else {
267+
// TODO(b/238781169) we are ignoring this compat for now, since we will have
268+
// to remove any optimization based on visibility.
269+
270+
// For compatibility reasons we let layers which can receive input
271+
// receive input before they have actually submitted a buffer. Because
272+
// of this we use canReceiveInput instead of isVisible to check the
273+
// policy-visibility, ignoring the buffer state. However for layers with
274+
// hasInputInfo()==false we can use the real visibility state.
275+
// We are just using these layers for occlusion detection in
276+
// InputDispatcher, and obviously if they aren't visible they can't occlude
277+
// anything.
278+
const bool visibleForInput =
279+
snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible;
280+
snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE,
281+
!visibleForInput);
282+
}
278283
LLOGV(snapshot.sequence, "updating visibility %s %s", visible ? "true" : "false",
279284
snapshot.getDebugString().c_str());
280285
}
@@ -1260,6 +1265,10 @@ void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) con
12601265
for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) {
12611266
LayerSnapshot& snapshot = *mSnapshots[(size_t)i];
12621267
if (!snapshot.hasInputInfo()) continue;
1268+
if (FlagManager::getInstance().skip_invisible_windows_in_input() &&
1269+
snapshot.inputInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)) {
1270+
continue;
1271+
}
12631272
visitor(snapshot);
12641273
}
12651274
}

services/surfaceflinger/common/FlagManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ void FlagManager::dump(std::string& result) const {
159159
DUMP_READ_ONLY_FLAG(display_config_error_hal);
160160
DUMP_READ_ONLY_FLAG(connected_display_hdr);
161161
DUMP_READ_ONLY_FLAG(deprecate_frame_tracker);
162+
DUMP_READ_ONLY_FLAG(skip_invisible_windows_in_input);
162163

163164
#undef DUMP_READ_ONLY_FLAG
164165
#undef DUMP_SERVER_FLAG
@@ -266,6 +267,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(true_hdr_screenshots, "debug.sf.true_hdr_screenshots
266267
FLAG_MANAGER_READ_ONLY_FLAG(display_config_error_hal, "");
267268
FLAG_MANAGER_READ_ONLY_FLAG(connected_display_hdr, "");
268269
FLAG_MANAGER_READ_ONLY_FLAG(deprecate_frame_tracker, "");
270+
FLAG_MANAGER_READ_ONLY_FLAG(skip_invisible_windows_in_input, "");
269271

270272
/// Trunk stable server flags ///
271273
FLAG_MANAGER_SERVER_FLAG(refresh_rate_overlay_on_external_display, "")

services/surfaceflinger/common/include/common/FlagManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class FlagManager {
9797
bool display_config_error_hal() const;
9898
bool connected_display_hdr() const;
9999
bool deprecate_frame_tracker() const;
100+
bool skip_invisible_windows_in_input() const;
100101

101102
protected:
102103
// overridden for unit tests

services/surfaceflinger/surfaceflinger_flags_new.aconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,17 @@ flag {
195195
}
196196
} # single_hop_screenshot
197197

198+
flag {
199+
name: "skip_invisible_windows_in_input"
200+
namespace: "window_surfaces"
201+
description: "Only send visible windows to input list"
202+
bug: "305254099"
203+
is_fixed_read_only: true
204+
metadata {
205+
purpose: PURPOSE_BUGFIX
206+
}
207+
} # skip_invisible_windows_in_input
208+
198209
flag {
199210
name: "true_hdr_screenshots"
200211
namespace: "core_graphics"

services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,9 @@ TEST_F(LayerSnapshotTest, propagateDropInputMode) {
15511551
}
15521552

15531553
TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) {
1554+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::
1555+
skip_invisible_windows_in_input,
1556+
false);
15541557
LayerHierarchyTestBase::createRootLayer(3);
15551558
setColor(3, {-1._hf, -1._hf, -1._hf});
15561559
UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
@@ -1576,6 +1579,39 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) {
15761579
EXPECT_TRUE(foundInputLayer);
15771580
}
15781581

1582+
TEST_F(LayerSnapshotTest, NonVisibleLayerWithInputShouldNotBeIncluded) {
1583+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::
1584+
skip_invisible_windows_in_input,
1585+
true);
1586+
LayerHierarchyTestBase::createRootLayer(3);
1587+
setColor(3, {-1._hf, -1._hf, -1._hf});
1588+
UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
1589+
1590+
std::vector<TransactionState> transactions;
1591+
transactions.emplace_back();
1592+
transactions.back().states.push_back({});
1593+
transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
1594+
transactions.back().states.front().layerId = 3;
1595+
transactions.back().states.front().state.windowInfoHandle = sp<gui::WindowInfoHandle>::make();
1596+
auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
1597+
inputInfo->token = sp<BBinder>::make();
1598+
hideLayer(3);
1599+
mLifecycleManager.applyTransactions(transactions);
1600+
1601+
update(mSnapshotBuilder);
1602+
1603+
bool foundInputLayer = false;
1604+
mSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
1605+
if (snapshot.uniqueSequence == 3) {
1606+
EXPECT_TRUE(
1607+
snapshot.inputInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE));
1608+
EXPECT_FALSE(snapshot.isVisible);
1609+
foundInputLayer = true;
1610+
}
1611+
});
1612+
EXPECT_FALSE(foundInputLayer);
1613+
}
1614+
15791615
TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) {
15801616
std::vector<uint32_t> visitedUniqueSequences;
15811617
mSnapshotBuilder.forEachSnapshot(

0 commit comments

Comments
 (0)