SF: Fix a defect in the layer filtering logic
Change 32cbe2 broke the layer filtering logic when moving it over to
CompositionEngine. It would allow certain layers to appear on a virtual
display when they were supposed to be filtered out.
This corrects the logic to be what it was supposed to be, and adds a
unit test that verifies and documents the expected behavior.
Bug: 123248930
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: atest android.media.cts.EncodeVirtualDisplayWithCompositionTest
Change-Id: Id2c4b4d32da405c64533924027795620f2d6ee61
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5df2876..4443df4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2226,7 +2226,8 @@
mDrawingState.traverseInZOrder([&](Layer* layer) {
bool hwcLayerDestroyed = false;
const auto displayId = displayDevice->getId();
- if (display->belongsInOutput(layer->getLayerStack())) {
+ if (display->belongsInOutput(layer->getLayerStack(),
+ layer->getPrimaryDisplayOnly())) {
Region drawRegion(tr.transform(
layer->visibleNonTransparentRegion));
drawRegion.andSelf(bounds);
@@ -2879,7 +2880,9 @@
// if not, pick the only display it's on.
hintDisplay = nullptr;
for (const auto& [token, display] : mDisplays) {
- if (display->getCompositionDisplay()->belongsInOutput(layer->getLayerStack())) {
+ if (display->getCompositionDisplay()
+ ->belongsInOutput(layer->getLayerStack(),
+ layer->getPrimaryDisplayOnly())) {
if (hintDisplay) {
hintDisplay = nullptr;
break;
@@ -3063,7 +3066,7 @@
const Layer::State& s(layer->getDrawingState());
// only consider the layers on the given layer stack
- if (!display->belongsInOutput(layer->getLayerStack())) {
+ if (!display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
return;
}
@@ -3189,7 +3192,7 @@
void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();
- if (display->belongsInOutput(layer->getLayerStack())) {
+ if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
display->editState().dirtyRegion.orSelf(dirty);
}
}