FTL: Yield futures without overhead
ftl::yield, which lifts T to std::future<T>, incurs the cost of
allocating, ref counting, and locking the latter's shared state.
Consolidate the existing std::future extensions into ftl::Future,
and optimize ftl::yield by including static storage for T within.
Bug: 232436803
Test: simpleperf (-31% cycles in postFramebuffer)
Change-Id: I9a7ca7de17e7af10515de97d2f6a0dfa24e35d7a
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index b7fc62f..ec610c1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -16,7 +16,6 @@
#pragma once
-#include <future>
#include <optional>
#include <ostream>
#include <unordered_set>
@@ -33,6 +32,7 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
+#include <ftl/future.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
@@ -157,7 +157,7 @@
ClientCompositionTargetSettings&) = 0;
// Called after the layer is displayed to update the presentation fence
- virtual void onLayerDisplayed(std::shared_future<FenceResult>) = 0;
+ virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>) = 0;
// Gets some kind of identifier for the layer for debug purposes.
virtual const char* getDebugName() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 871599d..1c5c10f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -49,7 +49,7 @@
std::vector<compositionengine::LayerFE::LayerSettings>(
compositionengine::LayerFE::ClientCompositionTargetSettings&));
- MOCK_METHOD1(onLayerDisplayed, void(std::shared_future<FenceResult>));
+ MOCK_METHOD(void, onLayerDisplayed, (ftl::SharedFuture<FenceResult>), (override));
MOCK_CONST_METHOD0(getDebugName, const char*());
MOCK_CONST_METHOD0(getSequence, int32_t());
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index ff2aa15..9b12b08 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -84,9 +84,9 @@
MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(HalDisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
status_t(HalDisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
- MOCK_METHOD4(setDisplayBrightness,
- std::future<status_t>(PhysicalDisplayId, float, float,
- const Hwc2::Composer::DisplayBrightnessOptions&));
+ MOCK_METHOD(ftl::Future<status_t>, setDisplayBrightness,
+ (PhysicalDisplayId, float, float, const Hwc2::Composer::DisplayBrightnessOptions&),
+ (override));
MOCK_METHOD2(getDisplayBrightnessSupport, status_t(PhysicalDisplayId, bool*));
MOCK_METHOD2(onHotplug,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 784abea..deaea87 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3189,15 +3189,15 @@
// would not survive certain calls like Fence::merge() which would return a
// new instance.
EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
- .WillOnce([&layer1Fence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
});
EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
- .WillOnce([&layer2Fence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
});
EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
- .WillOnce([&layer3Fence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
});
@@ -3256,15 +3256,15 @@
// Each released layer should be given the presentFence.
EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
- .WillOnce([&presentFence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
});
EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
- .WillOnce([&presentFence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
});
EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
- .WillOnce([&presentFence](std::shared_future<FenceResult> futureFenceResult) {
+ .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
});