summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2020-01-21 14:36:08 -0800
committer Vishnu Nair <vishnun@google.com> 2020-01-21 21:17:50 -0800
commit9b079a2fef76ed1dfa69b158889edd0af5e6e52c (patch)
tree0072ca6810ee57122aa5b56abf52b18032b0f6f1 /services/surfaceflinger/SurfaceFlinger.cpp
parent0a4b951a590910bab35f20f03d25316426dbf8ae (diff)
Skip client composition requests
Keep track of client compositions requests in CompositionEngine and the buffer used to render the request. If the requests do not change and the buffer matches, reuse the buffer instead of going to client composition. Certain layers properties (buffer format, rounded corner or shadows) will force the device to go into GPU or mixed composition. In mixed composition scenarios, we can avoid redundant client composition requests by reusing the RenderSurface buffers. If the device goes into GPU composition then all the layers will be composited and there will be no performance benefit. Bug: b/136561771, b/144690120 Test: dump SurfaceFlinger --timestats -dump Test: manual testing with mixed and gpu composition scenarios Test: atest libcompositionengine_test libsurfaceflinger_unittest SurfaceFlinger_test Change-Id: I466d5dcded0c9fcfa64bc72fd91dfaddd795f315
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1b1b58b1e7..a894005c1d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -353,6 +353,9 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI
property_get("debug.sf.luma_sampling", value, "1");
mLumaSampling = atoi(value);
+ property_get("debug.sf.disable_client_composition_cache", value, "1");
+ mDisableClientCompositionCache = atoi(value);
+
// We should be reading 'persist.sys.sf.color_saturation' here
// but since /data may be encrypted, we need to wait until after vold
// comes online to attempt to read the property. The property is
@@ -1893,13 +1896,19 @@ void SurfaceFlinger::handleMessageRefresh() {
mHadClientComposition =
std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
auto& displayDevice = tokenDisplayPair.second;
- return displayDevice->getCompositionDisplay()->getState().usesClientComposition;
+ return displayDevice->getCompositionDisplay()->getState().usesClientComposition &&
+ !displayDevice->getCompositionDisplay()->getState().reusedClientComposition;
});
mHadDeviceComposition =
std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
auto& displayDevice = tokenDisplayPair.second;
return displayDevice->getCompositionDisplay()->getState().usesDeviceComposition;
});
+ mReusedClientComposition =
+ std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
+ auto& displayDevice = tokenDisplayPair.second;
+ return displayDevice->getCompositionDisplay()->getState().reusedClientComposition;
+ });
mVSyncModulator->onRefreshed(mHadClientComposition);
@@ -2079,6 +2088,10 @@ void SurfaceFlinger::postComposition()
mTimeStats->incrementClientCompositionFrames();
}
+ if (mReusedClientComposition) {
+ mTimeStats->incrementClientCompositionReusedFrames();
+ }
+
mTimeStats->setPresentFenceGlobal(presentFenceTime);
if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) &&
@@ -5408,7 +5421,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
const auto& displayViewport = renderArea.getDisplayViewport();
renderengine::DisplaySettings clientCompositionDisplay;
- std::vector<renderengine::LayerSettings> clientCompositionLayers;
+ std::vector<compositionengine::LayerFE::LayerSettings> clientCompositionLayers;
// assume that bounds are never offset, and that they are the same as the
// buffer bounds.
@@ -5469,7 +5482,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
- renderengine::LayerSettings fillLayer;
+ compositionengine::LayerFE::LayerSettings fillLayer;
fillLayer.source.buffer.buffer = nullptr;
fillLayer.source.solidColor = half3(0.0, 0.0, 0.0);
fillLayer.geometry.boundaries = FloatRect(0.0, 0.0, 1.0, 1.0);
@@ -5490,7 +5503,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
};
auto result = layer->prepareClientComposition(targetSettings);
if (result) {
- std::optional<renderengine::LayerSettings> shadowLayer =
+ std::optional<compositionengine::LayerFE::LayerSettings> shadowLayer =
layer->prepareShadowClientComposition(*result, displayViewport,
clientCompositionDisplay.outputDataspace);
if (shadowLayer) {
@@ -5500,13 +5513,20 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
}
});
+ std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
+ clientCompositionLayers.reserve(clientCompositionLayers.size());
+ std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
+ std::back_inserter(clientCompositionLayerPointers),
+ [](compositionengine::LayerFE::LayerSettings& settings)
+ -> renderengine::LayerSettings* { return &settings; });
+
clientCompositionDisplay.clearRegion = clearRegion;
// Use an empty fence for the buffer fence, since we just created the buffer so
// there is no need for synchronization with the GPU.
base::unique_fd bufferFence;
base::unique_fd drawFence;
getRenderEngine().useProtectedContext(false);
- getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayers, buffer,
+ getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
/*useFramebufferCache=*/false, std::move(bufferFence), &drawFence);
*outSyncFd = drawFence.release();