CE: Update layer composition state outside of CE
First step in breaking CE dependencies with frontend.
FE should provide a snapshot of the state for CE to
consume. This cl updates the composition state
based on whether visible regions are dirty before
calling into composition engine.
Test: presubmit
Test: go/wm-smoke
Bug: 238781169
Change-Id: I6efd71cf66d9e1cae163c98ad4ce3097e09848af
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index 9753a6c..a738da0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -53,31 +53,8 @@
// Called before composition starts. Should return true if this layer has
// pending updates which would require an extra display refresh cycle to
// process.
- virtual bool onPreComposition(nsecs_t refreshStartTime) = 0;
-
- // Used with latchCompositionState()
- enum class StateSubset {
- // Gets the basic geometry (bounds, transparent region, visibility,
- // transforms, alpha) for the layer, for computing visibility and
- // coverage.
- BasicGeometry,
-
- // Gets the full geometry (crops, buffer transforms, metadata) and
- // content (buffer or color) state for the layer.
- GeometryAndContent,
-
- // Gets the per frame content (buffer or color) state for the layer.
- Content,
-
- // Gets the cursor state for the layer.
- Cursor,
- };
-
- // Prepares the output-independent composition state for the layer. The
- // StateSubset argument selects what portion of the state is actually needed
- // by the CompositionEngine code, since computing everything may be
- // expensive.
- virtual void prepareCompositionState(StateSubset) = 0;
+ virtual bool onPreComposition(nsecs_t refreshStartTime,
+ bool updatingOutputGeometryThisFrame) = 0;
struct ClientCompositionTargetSettings {
enum class BlurSetting {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 2203639..874b330 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -262,9 +262,6 @@
// Presents the output, finalizing all composition details
virtual void present(const CompositionRefreshArgs&) = 0;
- // Latches the front-end layer state for each output layer
- virtual void updateLayerStateFromFE(const CompositionRefreshArgs&) const = 0;
-
// Enables predicting composition strategy to run client composition earlier
virtual void setPredictCompositionStrategy(bool) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
index 386808d..0907926 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -51,8 +51,6 @@
// Debugging
void dump(std::string&) const override;
- void updateLayerStateFromFE(CompositionRefreshArgs& args);
-
// Testing
void setNeedsAnotherUpdateForTest(bool);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 38a391b..23d5570 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -89,7 +89,6 @@
compositionengine::Output::CoverageState&) override;
void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
- void updateLayerStateFromFE(const CompositionRefreshArgs&) const override;
void updateCompositionState(const compositionengine::CompositionRefreshArgs&) override;
void planComposition() override;
void writeCompositionState(const compositionengine::CompositionRefreshArgs&) override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 2b704e6..be0dbce 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -42,9 +42,8 @@
MOCK_CONST_METHOD0(getCompositionState, const LayerFECompositionState*());
- MOCK_METHOD1(onPreComposition, bool(nsecs_t));
+ MOCK_METHOD2(onPreComposition, bool(nsecs_t, bool));
- MOCK_METHOD1(prepareCompositionState, void(compositionengine::LayerFE::StateSubset));
MOCK_CONST_METHOD1(prepareClientComposition,
std::optional<compositionengine::LayerFE::LayerSettings>(
compositionengine::LayerFE::ClientCompositionTargetSettings&));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 2a04949..7592cac 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -91,7 +91,6 @@
void(sp<compositionengine::LayerFE>&, compositionengine::Output::CoverageState&));
MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
- MOCK_CONST_METHOD1(updateLayerStateFromFE, void(const CompositionRefreshArgs&));
MOCK_METHOD1(updateCompositionState, void(const CompositionRefreshArgs&));
MOCK_METHOD0(planComposition, void());
MOCK_METHOD1(writeCompositionState, void(const CompositionRefreshArgs&));
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index 6203dc6..855507e 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -105,8 +105,6 @@
}
}
- updateLayerStateFromFE(args);
-
for (const auto& output : args.outputs) {
output->present(args);
}
@@ -119,8 +117,6 @@
for (const auto& output : args.outputs) {
for (auto* layer : output->getOutputLayersOrderedByZ()) {
if (layer->isHardwareCursor()) {
- // Latch the cursor composition state from each front-end layer.
- layer->getLayerFE().prepareCompositionState(LayerFE::StateSubset::Cursor);
layer->writeCursorPositionToHWC();
}
}
@@ -136,7 +132,7 @@
mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
for (auto& layer : args.layers) {
- if (layer->onPreComposition(mRefreshStartTime)) {
+ if (layer->onPreComposition(mRefreshStartTime, args.updatingOutputGeometryThisFrame)) {
needsAnotherUpdate = true;
}
}
@@ -152,12 +148,5 @@
mNeedsAnotherUpdate = value;
}
-void CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args) {
- // Update the composition state from each front-end layer
- for (const auto& output : args.outputs) {
- output->updateLayerStateFromFE(args);
- }
-}
-
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index b5894cf..e3f3680 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -501,7 +501,6 @@
// appear on multiple outputs.
if (!coverage.latchedLayers.count(layerFE)) {
coverage.latchedLayers.insert(layerFE);
- layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
}
// Only consider the layers on this output
@@ -725,14 +724,6 @@
// The base class does nothing with this call.
}
-void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
- for (auto* layer : getOutputLayersOrderedByZ()) {
- layer->getLayerFE().prepareCompositionState(
- args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
- : LayerFE::StateSubset::Content);
- }
-}
-
void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
index de9de01..b570979 100644
--- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -108,12 +108,6 @@
EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
- // The next step in presenting is to make sure all outputs have the latest
- // state from the front-end (SurfaceFlinger).
- EXPECT_CALL(*mOutput1, updateLayerStateFromFE(Ref(mRefreshArgs)));
- EXPECT_CALL(*mOutput2, updateLayerStateFromFE(Ref(mRefreshArgs)));
- EXPECT_CALL(*mOutput3, updateLayerStateFromFE(Ref(mRefreshArgs)));
-
// The last step is to actually present each output.
EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)));
EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)));
@@ -175,21 +169,18 @@
{
InSequence seq;
EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
- EXPECT_CALL(*mOutput2Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
EXPECT_CALL(mOutput2Layer1.outputLayer, writeCursorPositionToHWC());
}
{
InSequence seq;
EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
- EXPECT_CALL(*mOutput3Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
EXPECT_CALL(mOutput3Layer1.outputLayer, writeCursorPositionToHWC());
}
{
InSequence seq;
EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
- EXPECT_CALL(*mOutput3Layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
EXPECT_CALL(mOutput3Layer2.outputLayer, writeCursorPositionToHWC());
}
@@ -222,9 +213,12 @@
nsecs_t ts1 = 0;
nsecs_t ts2 = 0;
nsecs_t ts3 = 0;
- EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
- EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
- EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
+ EXPECT_CALL(*mLayer1FE, onPreComposition(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
+ EXPECT_CALL(*mLayer2FE, onPreComposition(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
+ EXPECT_CALL(*mLayer3FE, onPreComposition(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
mRefreshArgs.outputs = {mOutput1};
mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
@@ -238,9 +232,9 @@
}
TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
- EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
- EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
- EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
+ EXPECT_CALL(*mLayer1FE, onPreComposition(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*mLayer2FE, onPreComposition(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*mLayer3FE, onPreComposition(_, _)).WillOnce(Return(false));
mEngine.setNeedsAnotherUpdateForTest(true);
@@ -255,9 +249,9 @@
TEST_F(CompositionTestPreComposition,
preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
- EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
- EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
- EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
+ EXPECT_CALL(*mLayer1FE, onPreComposition(_, _)).WillOnce(Return(true));
+ EXPECT_CALL(*mLayer2FE, onPreComposition(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*mLayer3FE, onPreComposition(_, _)).WillOnce(Return(false));
mRefreshArgs.outputs = {mOutput1};
mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index ace2864..eb209e9 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -758,56 +758,6 @@
}
/*
- * Output::updateLayerStateFromFE()
- */
-
-using OutputUpdateLayerStateFromFETest = OutputTest;
-
-TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
- CompositionRefreshArgs refreshArgs;
-
- mOutput->updateLayerStateFromFE(refreshArgs);
-}
-
-TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
- InjectedLayer layer1;
- InjectedLayer layer2;
- InjectedLayer layer3;
-
- EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
- EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
- EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
-
- injectOutputLayer(layer1);
- injectOutputLayer(layer2);
- injectOutputLayer(layer3);
-
- CompositionRefreshArgs refreshArgs;
- refreshArgs.updatingGeometryThisFrame = false;
-
- mOutput->updateLayerStateFromFE(refreshArgs);
-}
-
-TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
- InjectedLayer layer1;
- InjectedLayer layer2;
- InjectedLayer layer3;
-
- EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
- EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
- EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
-
- injectOutputLayer(layer1);
- injectOutputLayer(layer2);
- injectOutputLayer(layer3);
-
- CompositionRefreshArgs refreshArgs;
- refreshArgs.updatingGeometryThisFrame = true;
-
- mOutput->updateLayerStateFromFE(refreshArgs);
-}
-
-/*
* Output::updateAndWriteCompositionState()
*/
@@ -1536,9 +1486,6 @@
TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
- EXPECT_CALL(*mLayer.layerFE,
- prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
-
mGeomSnapshots.clear();
ensureOutputLayerIfVisible();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1c720cc..08b71c2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -465,6 +465,10 @@
for (const sp<Layer>& child : mDrawingChildren) {
child->computeBounds(mBounds, mEffectiveTransform, childShadowRadius);
}
+
+ if (mPotentialCursor) {
+ prepareCursorCompositionState();
+ }
}
Rect Layer::getCroppedBufferSize(const State& s) const {
@@ -650,30 +654,6 @@
return sp<compositionengine::LayerFE>::fromExisting(layerFE);
}
-void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
- using StateSubset = compositionengine::LayerFE::StateSubset;
-
- switch (subset) {
- case StateSubset::BasicGeometry:
- prepareBasicGeometryCompositionState();
- break;
-
- case StateSubset::GeometryAndContent:
- prepareBasicGeometryCompositionState();
- prepareGeometryCompositionState();
- preparePerFrameCompositionState();
- break;
-
- case StateSubset::Content:
- preparePerFrameCompositionState();
- break;
-
- case StateSubset::Cursor:
- prepareCursorCompositionState();
- break;
- }
-}
-
const char* Layer::getDebugName() const {
return mName.c_str();
}
@@ -3426,7 +3406,7 @@
return fenceSignaled;
}
-bool Layer::onPreComposition(nsecs_t refreshStartTime) {
+bool Layer::onPreComposition(nsecs_t refreshStartTime, bool /* updatingOutputGeometryThisFrame */) {
for (const auto& handle : mDrawingState.callbackHandles) {
handle->refreshStartTime = refreshStartTime;
}
@@ -4240,6 +4220,18 @@
return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0;
}
+void Layer::updateSnapshot(bool updateGeometry) {
+ if (!getCompositionEngineLayerFE()) {
+ return;
+ }
+
+ if (updateGeometry) {
+ prepareBasicGeometryCompositionState();
+ prepareGeometryCompositionState();
+ }
+ preparePerFrameCompositionState();
+}
+
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f6b9b0f..5030fd8 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -574,9 +574,8 @@
// implements compositionengine::LayerFE
const compositionengine::LayerFECompositionState* getCompositionState() const;
bool fenceHasSignaled() const;
- bool onPreComposition(nsecs_t);
- void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override;
-
+ // Called before composition. updatingOutputGeometryThisFrame is used by ARC++'s Layer subclass.
+ bool onPreComposition(nsecs_t refreshStartTime, bool updatingOutputGeometryThisFrame);
std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
compositionengine::LayerFE::ClientCompositionTargetSettings&) const override;
void onLayerDisplayed(ftl::SharedFuture<FenceResult>);
@@ -868,6 +867,7 @@
bool simpleBufferUpdate(const layer_state_t&) const;
static bool isOpaqueFormat(PixelFormat format);
+ void updateSnapshot(bool updateGeometry);
protected:
friend class impl::SurfaceInterceptor;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9dd3713..e31490c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2189,10 +2189,6 @@
displayIds.push_back(display->getId());
}
mPowerAdvisor->setDisplays(displayIds);
- mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
- if (auto layerFE = layer->getCompositionEngineLayerFE())
- refreshArgs.layers.push_back(layerFE);
- });
if (DOES_CONTAIN_BORDER) {
refreshArgs.borderInfoList.clear();
@@ -2223,6 +2219,12 @@
refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) || mVisibleRegionsDirty;
+ mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
+ layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
+ if (auto layerFE = layer->getCompositionEngineLayerFE()) {
+ refreshArgs.layers.push_back(layerFE);
+ }
+ });
refreshArgs.blursAreExpensive = mBlursAreExpensive;
refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();
diff --git a/services/surfaceflinger/fuzzer/README.md b/services/surfaceflinger/fuzzer/README.md
index 7a5f229..a06c41b 100644
--- a/services/surfaceflinger/fuzzer/README.md
+++ b/services/surfaceflinger/fuzzer/README.md
@@ -78,9 +78,8 @@
Layer supports the following parameters:
1. Display Connection Types (parameter name: `fakeDisplay`)
2. State Sets (parameter name: `traverseInZOrder`)
-3. State Subsets (parameter name: `prepareCompositionState`)
-4. Disconnect modes (parameter name: `disconnect`)
-5. Data Spaces (parameter name: `setDataspace`)
+3. Disconnect modes (parameter name: `disconnect`)
+4. Data Spaces (parameter name: `setDataspace`)
You can find the possible values in the fuzzer's source code.
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 5b2ec96..9ece260 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -148,7 +148,8 @@
layer->computeSourceBounds(getFuzzedFloatRect(&mFdp));
layer->fenceHasSignaled();
- layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>());
+ layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>(),
+ false /*updatingOutputGeometryThisFrame*/);
const std::vector<sp<CallbackHandle>> callbacks;
layer->setTransactionCompletedListeners(callbacks);