SF: Add Planner flattener
Adds the Planner flattener, which detects when layers are inactive and
flattens them using GPU composition in order to reduce the workload on
the display processor.
Bug: 158790260
Test: atest libcompositionengine_test libsurfaceflinger_unittest
Change-Id: Idc5c2927c8af6fe85653404a7d94c9e68ffc329b
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 57b7481..dc1aacc 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -198,6 +198,10 @@
const Rect newOrientedBounds(orientedSize);
state.orientedDisplaySpace.bounds = newOrientedBounds;
+ if (mPlanner) {
+ mPlanner->setDisplaySize(size);
+ }
+
dirtyEntireOutput();
}
@@ -317,7 +321,11 @@
void Output::setRenderSurface(std::unique_ptr<compositionengine::RenderSurface> surface) {
mRenderSurface = std::move(surface);
- editState().framebufferSpace.bounds = Rect(mRenderSurface->getSize());
+ const auto size = mRenderSurface->getSize();
+ editState().framebufferSpace.bounds = Rect(size);
+ if (mPlanner) {
+ mPlanner->setDisplaySize(size);
+ }
dirtyEntireOutput();
}
@@ -402,6 +410,7 @@
devOptRepaintFlash(refreshArgs);
finishFrame(refreshArgs);
postFramebuffer();
+ renderCachedSets();
}
void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
@@ -701,8 +710,23 @@
return;
}
+ sp<GraphicBuffer> previousOverride = nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
- layer->writeStateToHWC(refreshArgs.updatingGeometryThisFrame);
+ bool skipLayer = false;
+ if (layer->getState().overrideInfo.buffer != nullptr) {
+ if (previousOverride != nullptr &&
+ layer->getState().overrideInfo.buffer == previousOverride) {
+ ALOGV("Skipping redundant buffer");
+ skipLayer = true;
+ }
+ previousOverride = layer->getState().overrideInfo.buffer;
+ }
+
+ // TODO(b/181172795): We now update geometry for all flattened layers. We should update it
+ // only when the geometry actually changes
+ const bool includeGeometry = refreshArgs.updatingGeometryThisFrame ||
+ layer->getState().overrideInfo.buffer != nullptr || skipLayer;
+ layer->writeStateToHWC(includeGeometry, skipLayer);
}
}
@@ -1126,10 +1150,16 @@
.realContentIsVisible = realContentIsVisible,
.clearContent = !clientComposition,
.disableBlurs = disableBlurs};
- std::vector<LayerFE::LayerSettings> results =
- layerFE.prepareClientCompositionList(targetSettings);
- if (realContentIsVisible && !results.empty()) {
- layer->editState().clientCompositionTimestamp = systemTime();
+
+ std::vector<LayerFE::LayerSettings> results;
+ if (layer->getState().overrideInfo.buffer != nullptr) {
+ results = layer->getOverrideCompositionList();
+ ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName());
+ } else {
+ results = layerFE.prepareClientCompositionList(targetSettings);
+ if (realContentIsVisible && !results.empty()) {
+ layer->editState().clientCompositionTimestamp = systemTime();
+ }
}
clientCompositionLayers.insert(clientCompositionLayers.end(),
@@ -1220,6 +1250,12 @@
mReleasedLayers.clear();
}
+void Output::renderCachedSets() {
+ if (mPlanner) {
+ mPlanner->renderCachedSets(getCompositionEngine().getRenderEngine());
+ }
+}
+
void Output::dirtyEntireOutput() {
auto& outputState = editState();
outputState.dirtyRegion.set(outputState.displaySpace.bounds);