Merge "Composition strategy prediction: Make broader predictions." into tm-dev
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index c65d467..7709b96 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -164,6 +164,9 @@
bool treat170mAsSrgb = false;
+ uint64_t lastOutputLayerHash = 0;
+ uint64_t outputLayerHash = 0;
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 4c30f99..daae6dd 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -763,6 +763,7 @@
bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
uint32_t z = 0;
bool overrideZ = false;
+ uint64_t outputLayerHash = 0;
for (auto* layer : getOutputLayersOrderedByZ()) {
if (layer == peekThroughLayer) {
// No longer needed, although it should not show up again, so
@@ -789,6 +790,10 @@
constexpr bool isPeekingThrough = true;
peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ,
isPeekingThrough);
+ outputLayerHash ^= android::hashCombine(
+ reinterpret_cast<uint64_t>(&peekThroughLayer->getLayerFE()),
+ z, includeGeometry, overrideZ, isPeekingThrough,
+ peekThroughLayer->requiresClientComposition());
}
previousOverride = overrideInfo.buffer->getBuffer();
@@ -797,7 +802,14 @@
constexpr bool isPeekingThrough = false;
layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
+ if (!skipLayer) {
+ outputLayerHash ^= android::hashCombine(
+ reinterpret_cast<uint64_t>(&layer->getLayerFE()),
+ z, includeGeometry, overrideZ, isPeekingThrough,
+ layer->requiresClientComposition());
+ }
}
+ editState().outputLayerHash = outputLayerHash;
}
compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
@@ -1493,6 +1505,10 @@
}
bool Output::canPredictCompositionStrategy(const CompositionRefreshArgs& refreshArgs) {
+ uint64_t lastOutputLayerHash = getState().lastOutputLayerHash;
+ uint64_t outputLayerHash = getState().outputLayerHash;
+ editState().lastOutputLayerHash = outputLayerHash;
+
if (!getState().isEnabled || !mHwComposerAsyncWorker) {
ALOGV("canPredictCompositionStrategy disabled");
return false;
@@ -1513,6 +1529,11 @@
return false;
}
+ if (lastOutputLayerHash != outputLayerHash) {
+ ALOGV("canPredictCompositionStrategy output layers changed");
+ return false;
+ }
+
// If no layer uses clientComposition, then don't predict composition strategy
// because we have less work to do in parallel.
if (!anyLayersRequireClientComposition()) {
@@ -1520,12 +1541,7 @@
return false;
}
- if (!refreshArgs.updatingOutputGeometryThisFrame) {
- return true;
- }
-
- ALOGV("canPredictCompositionStrategy updatingOutputGeometryThisFrame");
- return false;
+ return true;
}
bool Output::anyLayersRequireClientComposition() const {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 862ab1d..3b88aac 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -850,14 +850,20 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
EXPECT_CALL(*layer3.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
injectOutputLayer(layer1);
injectOutputLayer(layer2);
@@ -884,14 +890,20 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer3.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
injectOutputLayer(layer1);
injectOutputLayer(layer2);
@@ -917,14 +929,20 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
EXPECT_CALL(*layer3.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
injectOutputLayer(layer1);
injectOutputLayer(layer2);
@@ -950,6 +968,8 @@
InSequence seq;
EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
@@ -957,6 +977,9 @@
EXPECT_CALL(*layer0.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
+
// After calling planComposition (which clears overrideInfo), this test sets
// layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
@@ -966,12 +989,18 @@
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ true, /*isPeekingThrough*/
true));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
/*zIsOverridden*/ true, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
/*zIsOverridden*/ true, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
injectOutputLayer(layer0);
injectOutputLayer(layer1);
@@ -4798,10 +4827,14 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
layer2.layerFEState.backgroundBlurRadius = 10;
layer2.layerFEState.isOpaque = true;
@@ -4830,14 +4863,20 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer3.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
layer2.layerFEState.backgroundBlurRadius = 10;
layer2.layerFEState.isOpaque = false;
@@ -4867,14 +4906,20 @@
EXPECT_CALL(*layer1.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
EXPECT_CALL(*layer2.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
EXPECT_CALL(*layer3.outputLayer,
writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
/*zIsOverridden*/ false, /*isPeekingThrough*/ false));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(false));
BlurRegion region;
layer2.layerFEState.blurRegions.push_back(region);