CE: Remove compositionengine::Layer
This was a mostly straightforward refactor that restructures the
interface between SurfaceFlinger and CompositionEngine.
1) Instead of each SurfaceFlinger Layer creating and owning a
compositionengine::Layer, each Layer instead creates and owns a
compositionengine::LayerFECompositionState structure. Containing this
state structure was the only real purpose for
compositionengine::Layer.
2) Use the compositionengine::LayerFE interface in CompositionEngine in
place of compositionengine::Layer. This includes passing a
std::vector for the layers when SurfaceFlinger calls into
CompositionEngine.
3) Alters the LayerFE interface to add the ability to get the state, as
well as changing the existing "latchCompositionState" calls taking a
state reference as the first argument into "prepareCompositionState"
calls that do not need it, as the target of the call owns the state.
4) Alters the SurfaceFlinger Layer implementations to match the LayerFE
interface changes.
Test: atest libcompositionengine_test libsurfaceflinger_unittest
Test: atest CtsColorModeTestCases
Test: atest CtsDisplayTestCases
Test: atest CtsGraphicsTestCases
Test: atest CtsUiRenderingTestCases
Test: atest CtsViewTestCases
Test: atest android.media.cts.EncodeVirtualDisplayWithCompositionTest
Test: go/wm-smoke
Bug: 144117494
Change-Id: Id45df7c9cc389c8fd834ba379bc0d6360a984dac
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 55371df..47704ec 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -20,7 +20,6 @@
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/CompositionRefreshArgs.h>
#include <compositionengine/DisplayColorProfile.h>
-#include <compositionengine/Layer.h>
#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/RenderSurface.h>
@@ -265,31 +264,26 @@
(!internalOnly || outputState.layerStackInternal);
}
-bool Output::belongsInOutput(const compositionengine::Layer* layer) const {
- if (!layer) {
- return false;
- }
-
- const auto& layerFEState = layer->getFEState();
- return belongsInOutput(layerFEState.layerStackId, layerFEState.internalOnly);
+bool Output::belongsInOutput(const sp<compositionengine::LayerFE>& layerFE) const {
+ const auto* layerFEState = layerFE->getCompositionState();
+ return layerFEState && belongsInOutput(layerFEState->layerStackId, layerFEState->internalOnly);
}
std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
- const std::shared_ptr<compositionengine::Layer>& layer, const sp<LayerFE>& layerFE) const {
- return impl::createOutputLayer(*this, layer, layerFE);
+ const sp<LayerFE>& layerFE) const {
+ return impl::createOutputLayer(*this, layerFE);
}
-compositionengine::OutputLayer* Output::getOutputLayerForLayer(
- compositionengine::Layer* layer) const {
- auto index = findCurrentOutputLayerForLayer(layer);
+compositionengine::OutputLayer* Output::getOutputLayerForLayer(const sp<LayerFE>& layerFE) const {
+ auto index = findCurrentOutputLayerForLayer(layerFE);
return index ? getOutputLayerOrderedByZByIndex(*index) : nullptr;
}
std::optional<size_t> Output::findCurrentOutputLayerForLayer(
- compositionengine::Layer* layer) const {
+ const sp<compositionengine::LayerFE>& layer) const {
for (size_t i = 0; i < getOutputLayerCount(); i++) {
auto outputLayer = getOutputLayerOrderedByZByIndex(i);
- if (outputLayer && &outputLayer->getLayer() == layer) {
+ if (outputLayer && &outputLayer->getLayerFE() == layer.get()) {
return i;
}
}
@@ -352,7 +346,7 @@
// Evaluate the layers from front to back to determine what is visible. This
// also incrementally calculates the coverage information for each layer as
// well as the entire output.
- for (auto& layer : reversed(refreshArgs.layers)) {
+ for (auto layer : reversed(refreshArgs.layers)) {
// Incrementally process the coverage for each layer
ensureOutputLayerIfVisible(layer, coverage);
@@ -371,28 +365,29 @@
}
}
-void Output::ensureOutputLayerIfVisible(std::shared_ptr<compositionengine::Layer> layer,
+void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
compositionengine::Output::CoverageState& coverage) {
- // Note: Converts a wp<LayerFE> to a sp<LayerFE>
- auto layerFE = layer->getLayerFE();
- if (layerFE == nullptr) {
- return;
- }
-
// Ensure we have a snapshot of the basic geometry layer state. Limit the
// snapshots to once per frame for each candidate layer, as layers may
// appear on multiple outputs.
if (!coverage.latchedLayers.count(layerFE)) {
coverage.latchedLayers.insert(layerFE);
- layerFE->latchCompositionState(layer->editFEState(),
- compositionengine::LayerFE::StateSubset::BasicGeometry);
+ layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
}
- // Obtain a read-only reference to the front-end layer state
- const auto& layerFEState = layer->getFEState();
-
// Only consider the layers on the given layer stack
- if (!belongsInOutput(layer.get())) {
+ if (!belongsInOutput(layerFE)) {
+ return;
+ }
+
+ // Obtain a read-only pointer to the front-end layer state
+ const auto* layerFEState = layerFE->getCompositionState();
+ if (CC_UNLIKELY(!layerFEState)) {
+ return;
+ }
+
+ // handle hidden surfaces by setting the visible region to empty
+ if (CC_UNLIKELY(!layerFEState->isVisible)) {
return;
}
@@ -430,23 +425,18 @@
*/
Region shadowRegion;
- // handle hidden surfaces by setting the visible region to empty
- if (CC_UNLIKELY(!layerFEState.isVisible)) {
- return;
- }
-
- const ui::Transform& tr = layerFEState.geomLayerTransform;
+ const ui::Transform& tr = layerFEState->geomLayerTransform;
// Get the visible region
// TODO(b/121291683): Is it worth creating helper methods on LayerFEState
// for computations like this?
- const Rect visibleRect(tr.transform(layerFEState.geomLayerBounds));
+ const Rect visibleRect(tr.transform(layerFEState->geomLayerBounds));
visibleRegion.set(visibleRect);
- if (layerFEState.shadowRadius > 0.0f) {
+ if (layerFEState->shadowRadius > 0.0f) {
// if the layer casts a shadow, offset the layers visible region and
// calculate the shadow region.
- const auto inset = static_cast<int32_t>(ceilf(layerFEState.shadowRadius) * -1.0f);
+ const auto inset = static_cast<int32_t>(ceilf(layerFEState->shadowRadius) * -1.0f);
Rect visibleRectWithShadows(visibleRect);
visibleRectWithShadows.inset(inset, inset, inset, inset);
visibleRegion.set(visibleRectWithShadows);
@@ -458,10 +448,10 @@
}
// Remove the transparent area from the visible region
- if (!layerFEState.isOpaque) {
+ if (!layerFEState->isOpaque) {
if (tr.preserveRects()) {
// transform the transparent region
- transparentRegion = tr.transform(layerFEState.transparentRegionHint);
+ transparentRegion = tr.transform(layerFEState->transparentRegionHint);
} else {
// transformation too complex, can't do the
// transparent region optimization.
@@ -471,7 +461,7 @@
// compute the opaque region
const auto layerOrientation = tr.getOrientation();
- if (layerFEState.isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
+ if (layerFEState->isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
// If we one of the simple category of transforms (0/90/180/270 rotation
// + any flip), then the opaque region is the layer's footprint.
// Otherwise we don't try and compute the opaque region since there may
@@ -495,7 +485,7 @@
// Get coverage information for the layer as previously displayed,
// also taking over ownership from mOutputLayersorderedByZ.
- auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layer.get());
+ auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layerFE);
auto prevOutputLayer =
prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr;
@@ -509,7 +499,7 @@
// compute this layer's dirty region
Region dirty;
- if (layerFEState.contentDirty) {
+ if (layerFEState->contentDirty) {
// we need to invalidate the whole region
dirty = visibleRegion;
// as well, as the old visible region
@@ -556,7 +546,7 @@
// The layer is visible. Either reuse the existing outputLayer if we have
// one, or create a new one if we do not.
- auto result = ensureOutputLayer(prevOutputLayerIndex, layer, layerFE);
+ auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
// Store the layer coverage information into the layer state as some of it
// is useful later.
@@ -575,10 +565,9 @@
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
for (auto* layer : getOutputLayersOrderedByZ()) {
- layer->getLayerFE().latchCompositionState(layer->getLayer().editFEState(),
- args.updatingGeometryThisFrame
- ? LayerFE::StateSubset::GeometryAndContent
- : LayerFE::StateSubset::Content);
+ layer->getLayerFE().prepareCompositionState(
+ args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
+ : LayerFE::StateSubset::Content);
}
}
@@ -611,7 +600,7 @@
compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
- if (layer->getLayer().getFEState().backgroundBlurRadius > 0) {
+ if (layer->getLayerFE().getCompositionState()->backgroundBlurRadius > 0) {
layerRequestingBgComposition = layer;
}
}
@@ -637,7 +626,7 @@
*outHdrDataSpace = ui::Dataspace::UNKNOWN;
for (const auto* layer : getOutputLayersOrderedByZ()) {
- switch (layer->getLayer().getFEState().dataspace) {
+ switch (layer->getLayerFE().getCompositionState()->dataspace) {
case ui::Dataspace::V0_SCRGB:
case ui::Dataspace::V0_SCRGB_LINEAR:
case ui::Dataspace::BT2020:
@@ -653,7 +642,8 @@
case ui::Dataspace::BT2020_ITU_PQ:
bestDataSpace = ui::Dataspace::DISPLAY_P3;
*outHdrDataSpace = ui::Dataspace::BT2020_PQ;
- *outIsHdrClientComposition = layer->getLayer().getFEState().forceClientComposition;
+ *outIsHdrClientComposition =
+ layer->getLayerFE().getCompositionState()->forceClientComposition;
break;
case ui::Dataspace::BT2020_HLG:
case ui::Dataspace::BT2020_ITU_HLG:
@@ -865,7 +855,7 @@
if (outputState.isSecure && supportsProtectedContent) {
auto layers = getOutputLayersOrderedByZ();
bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) {
- return layer->getLayer().getFEState().hasProtectedContent;
+ return layer->getLayerFE().getCompositionState()->hasProtectedContent;
});
if (needsProtected != renderEngine.isProtected()) {
renderEngine.useProtectedContext(needsProtected);
@@ -954,7 +944,7 @@
for (auto* layer : getOutputLayersOrderedByZ()) {
const auto& layerState = layer->getState();
- const auto& layerFEState = layer->getLayer().getFEState();
+ const auto* layerFEState = layer->getLayerFE().getCompositionState();
auto& layerFE = layer->getLayerFE();
const Region clip(viewportRegion.intersect(layerState.visibleRegion));
@@ -973,7 +963,7 @@
// underneath. We also skip the first layer as the buffer target is
// guaranteed to start out cleared.
bool clearClientComposition =
- layerState.clearClientTarget && layerFEState.isOpaque && !firstLayer;
+ layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer;
ALOGV(" Composition type: client %d clear %d", clientComposition, clearClientComposition);