Merge "Improve Planner stability" into sc-dev
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index 8423a12..936dba3 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -42,7 +42,13 @@
}
Flags<LayerStateField> LayerState::update(compositionengine::OutputLayer* layer) {
- ALOGE_IF(layer != mOutputLayer, "[%s] Expected mOutputLayer to never change", __func__);
+ ALOGE_IF(mOutputLayer != layer && layer->getLayerFE().getSequence() != mId.get(),
+ "[%s] Expected mOutputLayer ID to never change: %d, %d", __func__,
+ layer->getLayerFE().getSequence(), mId.get());
+
+ // It's possible for the OutputLayer pointer to change even when the layer is logically the
+ // same, i.e., the LayerFE is the same. An example use-case is screen rotation.
+ mOutputLayer = layer;
Flags<LayerStateField> differences;
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index be2510f..f077470 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -113,15 +113,6 @@
}
}
- for (LayerId removedLayer : removedLayers) {
- if (const auto layerEntry = mPreviousLayers.find(removedLayer);
- layerEntry != mPreviousLayers.end()) {
- const auto& [id, state] = *layerEntry;
- ALOGV("Removed layer %s", state.getName().c_str());
- mPreviousLayers.erase(removedLayer);
- }
- }
-
mCurrentLayers.clear();
mCurrentLayers.reserve(currentLayerIds.size());
std::transform(currentLayerIds.cbegin(), currentLayerIds.cend(),
@@ -135,6 +126,7 @@
mFlattenedHash =
mFlattener.flattenLayers(mCurrentLayers, hash, std::chrono::steady_clock::now());
const bool layersWereFlattened = hash != mFlattenedHash;
+
ALOGV("[%s] Initial hash %zx flattened hash %zx", __func__, hash, mFlattenedHash);
if (mPredictorEnabled) {
@@ -148,6 +140,17 @@
ALOGV("[%s] No prediction found\n", __func__);
}
}
+
+ // Clean up the set of previous layers now that the view of the LayerStates in the flattener are
+ // up-to-date.
+ for (LayerId removedLayer : removedLayers) {
+ if (const auto layerEntry = mPreviousLayers.find(removedLayer);
+ layerEntry != mPreviousLayers.end()) {
+ const auto& [id, state] = *layerEntry;
+ ALOGV("Removed layer %s", state.getName().c_str());
+ mPreviousLayers.erase(removedLayer);
+ }
+ }
}
void Planner::reportFinalPlan(
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
index a09ce14..9ad3ab4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
@@ -117,6 +117,22 @@
EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer());
}
+TEST_F(LayerStateTest, updateOutputLayer) {
+ OutputLayerCompositionState outputLayerCompositionState;
+ LayerFECompositionState layerFECompositionState;
+ setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
+ layerFECompositionState);
+ mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+ EXPECT_EQ(&mOutputLayer, mLayerState->getOutputLayer());
+
+ mock::OutputLayer newOutputLayer;
+ mock::LayerFE newLayerFE;
+ setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionState,
+ layerFECompositionState);
+ mLayerState->update(&newOutputLayer);
+ EXPECT_EQ(&newOutputLayer, mLayerState->getOutputLayer());
+}
+
TEST_F(LayerStateTest, getId) {
OutputLayerCompositionState outputLayerCompositionState;
LayerFECompositionState layerFECompositionState;