[SF] Intersect layers with display frame not bounds
Currently when we test if a layer is visible we
intersect the tranformed visible region with the display
bounds. This is not correct because the display bounds
match the size of the the framebuffer, and transform
is mapping from viewport to frame. That's why instead we
should use frame.
The problem occurs when we are rendering UI with limited width
(using config_maxUiWidth in the framework) on a limited
framebuffer (using ro.surface_flinger.max_graphics_width).
For example if the UI and framebuffer are limited to 1080p
and display size is 2160p, we have bounds=1080p, frame=2160p,
viewport=1080p, transform=scaling x2 (by definition
transform maps the viewport to the frame). If we transform
a rect from the viewport space (i.e. layer space)
Test: atest libsurfaceflinger_unittest
Test: atest atest libcompositionengine_test
Test: manually check that b/159595100 doesn't reproduce
Bug: 159595100
Change-Id: I08d22fb5041abe6bd5ee00697c33bec281f94b91
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index b07c904..8883ef3 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -539,7 +539,7 @@
// TODO(b/121291683): Why does this not use visibleRegion? (see outputSpaceVisibleRegion below)
const auto& outputState = getState();
Region drawRegion(outputState.transform.transform(visibleNonTransparentRegion));
- drawRegion.andSelf(outputState.bounds);
+ drawRegion.andSelf(outputState.frame);
if (drawRegion.isEmpty()) {
return;
}