SF: Include fence returned from renderScreen into layers' release fence
In previous SurfaceFlinger implementation, the release fence generated
from the call of renderScreen was returned to its callers only. However,
the access of those rendered buffers from other components wasn't aware
of the extra work inside renderScreen. This patch includes the fence
into layers' release fence to allow the GPU to finish reading the buffer
before codec writes new context into the buffer.
Bug: 149962883
Bug: 152292389
Test: Rotate video on youtube over 1 hour without fence leakge
Change-Id: I17cc3e816236d2695f30b45a0be560fb6741f16f
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 880be28..aa68726 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5792,6 +5792,7 @@
fillLayer.alpha = half(alpha);
clientCompositionLayers.push_back(fillLayer);
+ std::vector<Layer*> renderedLayers;
Region clearRegion = Region::INVALID_REGION;
traverseLayers([&](Layer* layer) {
const bool supportProtectedContent = false;
@@ -5810,19 +5811,19 @@
};
std::vector<compositionengine::LayerFE::LayerSettings> results =
layer->prepareClientCompositionList(targetSettings);
- clientCompositionLayers.insert(clientCompositionLayers.end(),
- std::make_move_iterator(results.begin()),
- std::make_move_iterator(results.end()));
- results.clear();
-
+ if (results.size() > 0) {
+ clientCompositionLayers.insert(clientCompositionLayers.end(),
+ std::make_move_iterator(results.begin()),
+ std::make_move_iterator(results.end()));
+ renderedLayers.push_back(layer);
+ }
});
- std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
- clientCompositionLayers.reserve(clientCompositionLayers.size());
+ std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers(
+ clientCompositionLayers.size());
std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
- std::back_inserter(clientCompositionLayerPointers),
- [](compositionengine::LayerFE::LayerSettings& settings)
- -> renderengine::LayerSettings* { return &settings; });
+ clientCompositionLayerPointers.begin(),
+ std::pointer_traits<renderengine::LayerSettings*>::pointer_to);
clientCompositionDisplay.clearRegion = clearRegion;
// Use an empty fence for the buffer fence, since we just created the buffer so
@@ -5834,6 +5835,13 @@
/*useFramebufferCache=*/false, std::move(bufferFence), &drawFence);
*outSyncFd = drawFence.release();
+
+ if (*outSyncFd >= 0) {
+ sp<Fence> releaseFence = new Fence(dup(*outSyncFd));
+ for (auto* layer : renderedLayers) {
+ layer->onLayerDisplayed(releaseFence);
+ }
+ }
}
status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,