Skip to content

Commit 4cff1c7

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Implement stop layers" into main
2 parents 9bf557f + 42473a6 commit 4cff1c7

File tree

10 files changed

+266
-4
lines changed

10 files changed

+266
-4
lines changed

libs/gui/LayerState.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const {
919919
if (other.what & eLutsChanged) diff |= eLutsChanged;
920920
CHECK_DIFF(diff, ePictureProfileHandleChanged, other, pictureProfileHandle);
921921
CHECK_DIFF(diff, eAppContentPriorityChanged, other, appContentPriority);
922+
if (other.what & eStopLayerChanged) diff |= eStopLayerChanged;
922923

923924
return diff;
924925
}

libs/gui/include/gui/LayerState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ struct layer_state_t {
254254
eClientDrawnCornerRadiusChanged = 0x200000'00000000,
255255
eBorderSettingsChanged = 0x400000'00000000,
256256
eBoxShadowSettingsChanged = 0x800000'00000000,
257+
eStopLayerChanged = 0x1000000'00000000,
257258
};
258259

259260
layer_state_t();

services/surfaceflinger/FrontEnd/LayerCreationArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct LayerCreationArgs {
6161
ui::LayerStack layerStackToMirror = ui::UNASSIGNED_LAYER_STACK;
6262
uint32_t parentId = UNASSIGNED_LAYER_ID;
6363
uint32_t layerIdToMirror = UNASSIGNED_LAYER_ID;
64+
uint32_t stopLayerId = UNASSIGNED_LAYER_ID;
6465
std::atomic<int32_t>* pendingBuffers = 0;
6566
};
6667

services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,11 +450,17 @@ void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
450450
LayerHierarchy::TraversalPath childPath =
451451
root.makeChild(args.root.getLayer()->id, LayerHierarchy::Variant::Attached);
452452
updateSnapshotsInHierarchy(args, args.root, childPath, rootSnapshot, /*depth=*/0);
453+
if (FlagManager::getInstance().stop_layer()) {
454+
applyStopLayers(args.root, childPath);
455+
}
453456
} else {
454457
for (auto& [childHierarchy, variant] : args.root.mChildren) {
455458
LayerHierarchy::TraversalPath childPath =
456459
root.makeChild(childHierarchy->getLayer()->id, variant);
457460
updateSnapshotsInHierarchy(args, *childHierarchy, childPath, rootSnapshot, /*depth=*/0);
461+
if (FlagManager::getInstance().stop_layer()) {
462+
applyStopLayers(*childHierarchy, childPath);
463+
}
458464
}
459465
}
460466

@@ -1397,4 +1403,98 @@ void LayerSnapshotBuilder::updateTouchableRegionCrop(const Args& args) {
13971403
}
13981404
}
13991405

1406+
// Apply stop layers to the hierarchy.
1407+
//
1408+
// If layer X specifies stop layer Y, then any layer within X's subhierarchy that is z-ordered
1409+
// above Y is hidden. The stop layer itself, layer Y, is also hidden.
1410+
//
1411+
// This works by traversing the hierarchy in z-order. When a layer that specifies a stop layer is
1412+
// encountered, the specified stop layer is pushed to the stopLayer stack, the subhierarchy is
1413+
// traversed, then the stop layer is popped from the stack. If a layer whose id is stored in the
1414+
// stop layer stack is encountered during traversal, it is added to the activeStopLayers set. Any
1415+
// layer visited while the activeStopLayer set is non-empty is hidden. When an element is popped
1416+
// from the stopLayer stack, any active stop layers that are no longer in the stopLayer stack are
1417+
// removed from the activeStopLayers set.
1418+
void LayerSnapshotBuilder::applyStopLayers(const LayerHierarchy& hierarchy,
1419+
const LayerHierarchy::TraversalPath& traversalPath) {
1420+
ftl::SmallVector<uint32_t, 5> stopLayers;
1421+
ftl::SmallVector<uint32_t, 5> activeStopLayers;
1422+
applyStopLayersInternal(hierarchy, traversalPath, stopLayers, activeStopLayers);
1423+
}
1424+
1425+
void LayerSnapshotBuilder::applyStopLayersInternal(
1426+
const LayerHierarchy& hierarchy, const LayerHierarchy::TraversalPath& traversalPath,
1427+
ftl::SmallVector<uint32_t, 5>& stopLayers,
1428+
ftl::SmallVector<uint32_t, 5>& activeStopLayers) {
1429+
const RequestedLayerState* layer = hierarchy.getLayer();
1430+
1431+
// Push to the stopLayer stack.
1432+
if (layer->stopLayerId != UNASSIGNED_LAYER_ID) {
1433+
stopLayers.push_back(layer->stopLayerId);
1434+
}
1435+
1436+
// Hide this layer if the activeStopLayers set is non-empty.
1437+
if (!activeStopLayers.empty()) {
1438+
LayerSnapshot* snapshot = getSnapshot(traversalPath);
1439+
snapshot->isHiddenByPolicyFromParent = true;
1440+
}
1441+
1442+
// Traverse z-ordered below children before potentially activating this layer as a stop layer.
1443+
auto childIt = hierarchy.mChildren.begin();
1444+
while (childIt != hierarchy.mChildren.end()) {
1445+
auto& [childHierarchy, childVariant] = *childIt;
1446+
if (childHierarchy->getLayer()->z >= 0) {
1447+
break;
1448+
}
1449+
childIt++;
1450+
1451+
LayerHierarchy::TraversalPath childTraversalPath =
1452+
traversalPath.makeChild(childHierarchy->getLayer()->id, childVariant);
1453+
if (childTraversalPath.detached) {
1454+
continue;
1455+
}
1456+
1457+
applyStopLayersInternal(*childHierarchy, childTraversalPath, stopLayers, activeStopLayers);
1458+
}
1459+
1460+
// Activate this layer as a stop layer if it's in the stopLayers stack.
1461+
bool isStopLayer =
1462+
std::find(stopLayers.begin(), stopLayers.end(), layer->id) != stopLayers.end();
1463+
if (isStopLayer) {
1464+
activeStopLayers.push_back(layer->id);
1465+
LayerSnapshot* snapshot = getSnapshot(traversalPath);
1466+
snapshot->isHiddenByPolicyFromParent = true;
1467+
}
1468+
1469+
// Traverse z-ordered above children.
1470+
while (childIt != hierarchy.mChildren.end()) {
1471+
auto& [childHierarchy, childVariant] = *childIt++;
1472+
1473+
LayerHierarchy::TraversalPath childTraversalPath =
1474+
traversalPath.makeChild(childHierarchy->getLayer()->id, childVariant);
1475+
if (childTraversalPath.detached) {
1476+
continue;
1477+
}
1478+
1479+
applyStopLayersInternal(*childHierarchy, childTraversalPath, stopLayers, activeStopLayers);
1480+
}
1481+
1482+
// Pop from the stopLayer stack and remove active stop layers from the activeStopLayers set
1483+
// if necessary.
1484+
if (layer->stopLayerId != UNASSIGNED_LAYER_ID) {
1485+
stopLayers.pop_back();
1486+
1487+
auto it = activeStopLayers.begin();
1488+
while (it != activeStopLayers.end()) {
1489+
bool stopLayerNoLongerActive =
1490+
std::find(stopLayers.begin(), stopLayers.end(), *it) == stopLayers.end();
1491+
if (stopLayerNoLongerActive) {
1492+
activeStopLayers.unstable_erase(it);
1493+
} else {
1494+
it++;
1495+
}
1496+
}
1497+
}
1498+
}
1499+
14001500
} // namespace android::surfaceflinger::frontend

services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ class LayerSnapshotBuilder {
139139
const Args& args, bool* outChildHasValidFrameRate);
140140
void updateTouchableRegionCrop(const Args& args);
141141

142+
void applyStopLayers(const LayerHierarchy&, const LayerHierarchy::TraversalPath&);
143+
void applyStopLayersInternal(const LayerHierarchy&, const LayerHierarchy::TraversalPath&,
144+
ftl::SmallVector<uint32_t, 5>& stopLayers,
145+
ftl::SmallVector<uint32_t, 5>& activeStopLayers);
146+
142147
std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,
143148
LayerHierarchy::TraversalPathHash>
144149
mPathToSnapshot;

services/surfaceflinger/FrontEnd/RequestedLayerState.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
5757
ownerPid(args.ownerPid),
5858
parentId(args.parentId),
5959
layerIdToMirror(args.layerIdToMirror),
60+
stopLayerId(args.stopLayerId),
6061
pendingBuffers(args.pendingBuffers) {
6162
layerId = static_cast<int32_t>(args.sequence);
6263
changes |= RequestedLayerState::Changes::Created;
@@ -359,6 +360,11 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta
359360
changes |= RequestedLayerState::Changes::Geometry;
360361
}
361362

363+
if (clientState.what & layer_state_t::eStopLayerChanged) {
364+
stopLayerId = resolvedComposerState.stopLayerId;
365+
changes |= RequestedLayerState::Changes::Visibility;
366+
}
367+
362368
// We can't just check requestedTransform here because LayerSnapshotBuilder uses
363369
// getTransform which reads destinationFrame or buffer dimensions.
364370
// Display rotation does not affect validity so just use ROT_0.

services/surfaceflinger/FrontEnd/RequestedLayerState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct RequestedLayerState : layer_state_t {
128128
uint32_t parentId = UNASSIGNED_LAYER_ID;
129129
uint32_t relativeParentId = UNASSIGNED_LAYER_ID;
130130
uint32_t layerIdToMirror = UNASSIGNED_LAYER_ID;
131+
uint32_t stopLayerId = UNASSIGNED_LAYER_ID;
131132
ui::LayerStack layerStackToMirror = ui::UNASSIGNED_LAYER_STACK;
132133
uint32_t touchCropId = UNASSIGNED_LAYER_ID;
133134
uint32_t bgColorLayerId = UNASSIGNED_LAYER_ID;

services/surfaceflinger/QueuedTransactionState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class ResolvedComposerState : public ComposerState {
4646
uint32_t parentId = UNASSIGNED_LAYER_ID;
4747
uint32_t relativeParentId = UNASSIGNED_LAYER_ID;
4848
uint32_t touchCropId = UNASSIGNED_LAYER_ID;
49+
uint32_t stopLayerId = UNASSIGNED_LAYER_ID;
4950
};
5051

5152
struct QueuedTransactionState {

services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ class LayerLifecycleManagerHelper {
4545
return args;
4646
}
4747

48-
static LayerCreationArgs createDisplayMirrorArgs(uint32_t id,
49-
ui::LayerStack layerStackToMirror) {
48+
static LayerCreationArgs createDisplayMirrorArgs(uint32_t id, ui::LayerStack layerStackToMirror,
49+
uint32_t stopLayerId = UNASSIGNED_LAYER_ID) {
5050
LayerCreationArgs args(std::make_optional(id));
5151
args.name = "testlayer";
5252
args.addToRoot = true;
5353
args.layerStackToMirror = layerStackToMirror;
54+
args.stopLayerId = stopLayerId;
5455
return args;
5556
}
5657

@@ -94,10 +95,11 @@ class LayerLifecycleManagerHelper {
9495
mLifecycleManager.addLayers(std::move(layers));
9596
}
9697

97-
void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack) {
98+
void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack,
99+
uint32_t stopLayerId = UNASSIGNED_LAYER_ID) {
98100
std::vector<std::unique_ptr<RequestedLayerState>> layers;
99101
layers.emplace_back(std::make_unique<RequestedLayerState>(
100-
createDisplayMirrorArgs(/*id=*/id, layerStack)));
102+
createDisplayMirrorArgs(/*id=*/id, layerStack, stopLayerId)));
101103
mLifecycleManager.addLayers(std::move(layers));
102104
}
103105

@@ -577,6 +579,16 @@ class LayerLifecycleManagerHelper {
577579
mLifecycleManager.applyTransactions(transactions);
578580
}
579581

582+
void setStopLayer(uint32_t id, uint32_t stopLayerId) {
583+
std::vector<QueuedTransactionState> transactions;
584+
transactions.emplace_back();
585+
transactions.back().states.emplace_back();
586+
transactions.back().states.back().layerId = id;
587+
transactions.back().states.back().state.what = layer_state_t::eStopLayerChanged;
588+
transactions.back().states.back().stopLayerId = stopLayerId;
589+
mLifecycleManager.applyTransactions(transactions);
590+
}
591+
580592
private:
581593
LayerLifecycleManager& mLifecycleManager;
582594
};

services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,4 +2189,138 @@ TEST_F(LayerSnapshotTest, shouldUpdatePictureProfilePriorityFromAppContentPriori
21892189
}
21902190
}
21912191

2192+
// Test that child layers of the stop layer are hidden.
2193+
TEST_F(LayerSnapshotTest, stopLayer_hidesChildren) {
2194+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2195+
setStopLayer(1, 122);
2196+
2197+
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 2};
2198+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2199+
}
2200+
2201+
// Test that if a layer specifies itself as a stop layer, then it is hidden.
2202+
TEST_F(LayerSnapshotTest, stopLayer_hidesSelf) {
2203+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2204+
setStopLayer(122, 122);
2205+
2206+
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 13, 2};
2207+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2208+
}
2209+
2210+
// Test that siblings z-ordered above a stop layer are hidden.
2211+
TEST_F(LayerSnapshotTest, stopLayer_hidesSiblings) {
2212+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2213+
setStopLayer(1, 121);
2214+
2215+
std::vector<uint32_t> expected = {1, 11, 111, 12, 2};
2216+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2217+
}
2218+
2219+
// Test that children z-ordered below the stop layer aren't hidden.
2220+
TEST_F(LayerSnapshotTest, stopLayer_doesntHideZOrderedBelowChildren) {
2221+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2222+
setZ(121, -1);
2223+
setStopLayer(1, 12);
2224+
2225+
std::vector<uint32_t> expected = {1, 11, 111, 121, 2};
2226+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2227+
}
2228+
2229+
// Test that relative children are hidden by the stop layer.
2230+
TEST_F(LayerSnapshotTest, stopLayer_hidesRelativeChild) {
2231+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2232+
reparentRelativeLayer(111, 12);
2233+
setStopLayer(1, 12);
2234+
2235+
std::vector<uint32_t> expected = {1, 11, 2};
2236+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2237+
}
2238+
2239+
// Test that detached children aren't hidden by the stop layer.
2240+
TEST_F(LayerSnapshotTest, stopLayer_doesntHideDetachedChildren) {
2241+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2242+
reparentRelativeLayer(121, 11);
2243+
setStopLayer(1, 12);
2244+
2245+
std::vector<uint32_t> expected = {1, 11, 111, 121, 2};
2246+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2247+
}
2248+
2249+
// Test that stop layers work on hierarchies with a single root layer.
2250+
TEST_F(LayerSnapshotTest, stopLayer_singleRoot) {
2251+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2252+
setStopLayer(1, 11);
2253+
2254+
LayerHierarchy root = mHierarchyBuilder.getPartialHierarchy(1, /*childrenOnly=*/false);
2255+
LayerSnapshotBuilder::Args args{.root = root,
2256+
.layerLifecycleManager = mLifecycleManager,
2257+
.includeMetadata = false,
2258+
.displays = mFrontEndDisplayInfos,
2259+
.displayChanges = false,
2260+
.globalShadowSettings = globalShadowSettings,
2261+
.supportsBlur = true,
2262+
.supportedLayerGenericMetadata = {},
2263+
.genericLayerMetadataKeyMap = {}};
2264+
mSnapshotBuilder.update(args);
2265+
2266+
std::vector<uint32_t> expectedVisibleLayers = {1};
2267+
std::vector<uint32_t> actualVisibleLayers;
2268+
mSnapshotBuilder.forEachVisibleSnapshot([&actualVisibleLayers](const LayerSnapshot& snapshot) {
2269+
actualVisibleLayers.push_back(snapshot.path.id);
2270+
});
2271+
EXPECT_EQ(expectedVisibleLayers, actualVisibleLayers);
2272+
}
2273+
2274+
// Test two stop layers where there's no interaction between the two stop layers.
2275+
TEST_F(LayerSnapshotTest, stopLayer_multipleStopLayers_parentAfterChild) {
2276+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2277+
setStopLayer(1, 13);
2278+
setStopLayer(11, 111);
2279+
2280+
std::vector<uint32_t> expected = {1, 11, 12, 121, 122, 1221, 2};
2281+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2282+
}
2283+
2284+
// Test two stop layers where the hierarchy containing the second stop layer is hidden.
2285+
TEST_F(LayerSnapshotTest, stopLayer_multipleStopLayers_childHidden) {
2286+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2287+
setStopLayer(1, 12);
2288+
setStopLayer(12, 122);
2289+
2290+
std::vector<uint32_t> expected = {1, 11, 111, 2};
2291+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2292+
}
2293+
2294+
// Test two stop layers where the stop layer specified lower in the hierarchy overrides
2295+
// the stop layer specified higher in the hierarchy.
2296+
TEST_F(LayerSnapshotTest, stopLayer_multipleStopLayers_childStopLayerOverridden) {
2297+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2298+
setStopLayer(1, 121);
2299+
setStopLayer(12, 122);
2300+
2301+
std::vector<uint32_t> expected = {1, 11, 111, 12, 2};
2302+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2303+
}
2304+
2305+
// Test two stop layers where the stop layer specified higher in the hierarchy applies because
2306+
// it appears before the stop layer applied lower in the hierarchy.
2307+
TEST_F(LayerSnapshotTest, stopLayer_multipleStopLayers_childApplied) {
2308+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2309+
setStopLayer(1, 13);
2310+
setStopLayer(11, 111);
2311+
2312+
std::vector<uint32_t> expected = {1, 11, 12, 121, 122, 1221, 2};
2313+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2314+
}
2315+
2316+
// Test that the stop layer works on mirrored hierarchies.
2317+
TEST_F(LayerSnapshotTest, stopLayer_mirrorHierarchy) {
2318+
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::stop_layer, true);
2319+
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0), 121);
2320+
setLayerStack(3, 1);
2321+
2322+
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3, 1, 11, 111, 12};
2323+
UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
2324+
}
2325+
21922326
} // namespace android::surfaceflinger::frontend

0 commit comments

Comments
 (0)