[Shadows] Create a new composition layer for shadows [6/n]
When generating the list of composition layers, generate one to render
shadows based on the layer settings.
The function passes in the display view port to calculate shadow
position. When rendering a screenshot, use the layerstack of the
root layer to find the display and its viewport since the shadows
on the screenshot have to match how it was rendered on display.
Pass in display or target output dataspace so shadows do not have to
do any color conversion.
Bug: 136561771
Test: go/wm-smoke
Test: libcompositionengine_test
Change-Id: I89795707f054b6a08dabc278d80ed393a0da0a7e
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 682932b..f5cbb4b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4908,8 +4908,12 @@
}
// Couldn't find display by displayId. Try to get display by layerStack since virtual displays
// may not have a displayId.
+ return getDisplayByLayerStack(displayOrLayerStack);
+}
+
+const sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) {
for (const auto& [token, display] : mDisplays) {
- if (display->getLayerStack() == displayOrLayerStack) {
+ if (display->getLayerStack() == layerStack) {
return display;
}
}
@@ -4965,8 +4969,8 @@
public:
LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
int32_t reqWidth, int32_t reqHeight, Dataspace reqDataSpace,
- bool childrenOnly)
- : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR, reqDataSpace),
+ bool childrenOnly, const Rect& displayViewport)
+ : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR, reqDataSpace, displayViewport),
mLayer(layer),
mCrop(crop),
mNeedsFiltering(false),
@@ -5050,7 +5054,7 @@
sp<Layer> parent;
Rect crop(sourceCrop);
std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
-
+ Rect displayViewport;
{
Mutex::Autolock _l(mStateLock);
@@ -5088,6 +5092,13 @@
return NAME_NOT_FOUND;
}
}
+
+ auto display = getDisplayByLayerStack(parent->getLayerStack());
+ if (!display) {
+ return BAD_VALUE;
+ }
+
+ displayViewport = display->getViewport();
} // mStateLock
// really small crop or frameScale
@@ -5098,7 +5109,8 @@
reqHeight = 1;
}
- LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, reqDataspace, childrenOnly);
+ LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, reqDataspace, childrenOnly,
+ displayViewport);
auto traverseLayers = [parent, childrenOnly,
&excludeLayers](const LayerVector::Visitor& visitor) {
parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
@@ -5224,6 +5236,7 @@
const auto rotation = renderArea.getRotationFlags();
const auto transform = renderArea.getTransform();
const auto sourceCrop = renderArea.getSourceCrop();
+ const auto& displayViewport = renderArea.getDisplayViewport();
renderengine::DisplaySettings clientCompositionDisplay;
std::vector<renderengine::LayerSettings> clientCompositionLayers;
@@ -5308,6 +5321,12 @@
};
auto result = layer->prepareClientComposition(targetSettings);
if (result) {
+ std::optional<renderengine::LayerSettings> shadowLayer =
+ layer->prepareShadowClientComposition(*result, displayViewport,
+ clientCompositionDisplay.outputDataspace);
+ if (shadowLayer) {
+ clientCompositionLayers.push_back(*shadowLayer);
+ }
clientCompositionLayers.push_back(*result);
}
});