FTL: Import std::future utilities from SF
Now including docs and expanded tests.
Bug: 160012986
Test: ftl_test
Change-Id: If9eb25646bb33ebc417ea87e6718b46fe0b87cf3
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index e6bff04..426092d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -26,18 +26,17 @@
#include "HWC2.h"
+#include <android/configuration.h>
+#include <ftl/future.h>
#include <ui/Fence.h>
#include <ui/FloatRect.h>
#include <ui/GraphicBuffer.h>
-#include <android/configuration.h>
-
-#include <inttypes.h>
#include <algorithm>
+#include <cinttypes>
#include <iterator>
#include <set>
-#include "../Promise.h"
#include "ComposerHal.h"
namespace android {
@@ -647,7 +646,7 @@
}
std::future<Error> Display::setDisplayBrightness(float brightness) {
- return promise::defer([composer = &mComposer, id = mId, brightness] {
+ return ftl::defer([composer = &mComposer, id = mId, brightness] {
const auto intError = composer->setDisplayBrightness(id, brightness);
return static_cast<Error>(intError);
});
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 1548d18..5fa72b8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -30,6 +30,7 @@
#include <compositionengine/Output.h>
#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <ftl/future.h>
#include <log/log.h>
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
@@ -37,7 +38,6 @@
#include <utils/Trace.h>
#include "../Layer.h" // needed only for debugging
-#include "../Promise.h"
#include "../SurfaceFlinger.h"
#include "../SurfaceFlingerProperties.h"
#include "ComposerHal.h"
@@ -792,10 +792,10 @@
std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
float brightness) {
- RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
+ RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
auto& display = mDisplayData[displayId].hwcDisplay;
- return promise::chain(display->setDisplayBrightness(brightness))
+ return ftl::chain(display->setDisplayBrightness(brightness))
.then([displayId](hal::Error error) -> status_t {
if (error == hal::Error::UNSUPPORTED) {
RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
diff --git a/services/surfaceflinger/Promise.h b/services/surfaceflinger/Promise.h
deleted file mode 100644
index a80d441..0000000
--- a/services/surfaceflinger/Promise.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <future>
-#include <type_traits>
-#include <utility>
-
-namespace android::promise {
-namespace impl {
-
-template <typename T>
-struct FutureResult {
- using Type = T;
-};
-
-template <typename T>
-struct FutureResult<std::future<T>> {
- using Type = T;
-};
-
-} // namespace impl
-
-template <typename T>
-using FutureResult = typename impl::FutureResult<T>::Type;
-
-template <typename... Args>
-inline auto defer(Args... args) {
- return std::async(std::launch::deferred, std::forward<Args>(args)...);
-}
-
-template <typename T>
-inline std::future<T> yield(T&& v) {
- return defer([](T&& v) { return std::forward<T>(v); }, std::forward<T>(v));
-}
-
-template <typename T>
-struct Chain {
- Chain(std::future<T>&& f) : future(std::move(f)) {}
- operator std::future<T>&&() && { return std::move(future); }
-
- T get() && { return future.get(); }
-
- template <typename F, typename R = std::invoke_result_t<F, T>>
- auto then(F&& op) && -> Chain<FutureResult<R>> {
- return defer(
- [](auto&& f, F&& op) {
- R r = op(f.get());
- if constexpr (std::is_same_v<R, FutureResult<R>>) {
- return r;
- } else {
- return r.get();
- }
- },
- std::move(future), std::forward<F>(op));
- }
-
- std::future<T> future;
-};
-
-template <typename T>
-inline Chain<T> chain(std::future<T>&& f) {
- return std::move(f);
-}
-
-} // namespace android::promise
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 2511eb3..ad4877b 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -28,6 +28,7 @@
#include <compositionengine/Display.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <cutils/properties.h>
+#include <ftl/future.h>
#include <gui/IRegionSamplingListener.h>
#include <gui/SyncScreenCaptureListener.h>
#include <ui/DisplayStatInfo.h>
@@ -38,7 +39,6 @@
#include "DisplayDevice.h"
#include "DisplayRenderArea.h"
#include "Layer.h"
-#include "Promise.h"
#include "Scheduler/VsyncController.h"
#include "SurfaceFlinger.h"
@@ -389,7 +389,7 @@
const Rect sampledBounds = sampleRegion.bounds();
- SurfaceFlinger::RenderAreaFuture renderAreaFuture = promise::defer([=] {
+ SurfaceFlinger::RenderAreaFuture renderAreaFuture = ftl::defer([=] {
return DisplayRenderArea::create(displayWeak, screencapRegion.bounds(),
sampledBounds.getSize(), ui::Dataspace::V0_SRGB,
orientation);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2fb3626..f067922 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,8 +47,7 @@
#include <configstore/Utils.h>
#include <cutils/compiler.h>
#include <cutils/properties.h>
-#include <dlfcn.h>
-#include <errno.h>
+#include <ftl/future.h>
#include <gui/BufferQueue.h>
#include <gui/DebugEGLImageTracker.h>
#include <gui/IDisplayEventConnection.h>
@@ -81,6 +80,7 @@
#include <utils/misc.h>
#include <algorithm>
+#include <cerrno>
#include <cinttypes>
#include <cmath>
#include <cstdint>
@@ -112,7 +112,6 @@
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "NativeWindowSurface.h"
-#include "Promise.h"
#include "RefreshRateOverlay.h"
#include "RegionSamplingThread.h"
#include "Scheduler/DispSyncSource.h"
@@ -1502,12 +1501,12 @@
return BAD_VALUE;
}
- return promise::chain(schedule([=]() MAIN_THREAD {
+ return ftl::chain(schedule([=]() MAIN_THREAD {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().setDisplayBrightness(*displayId, brightness);
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
- return promise::yield<status_t>(NAME_NOT_FOUND);
+ return ftl::yield<status_t>(NAME_NOT_FOUND);
}
}))
.then([](std::future<status_t> task) { return task; })
@@ -5484,7 +5483,7 @@
}
}
- RenderAreaFuture renderAreaFuture = promise::defer([=] {
+ RenderAreaFuture renderAreaFuture = ftl::defer([=] {
return DisplayRenderArea::create(displayWeak, args.sourceCrop, reqSize, dataspace,
args.useIdentityTransform, args.captureSecureLayers);
});
@@ -5518,7 +5517,7 @@
pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
}
- RenderAreaFuture renderAreaFuture = promise::defer([=] {
+ RenderAreaFuture renderAreaFuture = ftl::defer([=] {
return DisplayRenderArea::create(displayWeak, Rect(), size, dataspace,
false /* useIdentityTransform */,
false /* captureSecureLayers */);
@@ -5622,7 +5621,7 @@
}
bool childrenOnly = args.childrenOnly;
- RenderAreaFuture renderAreaFuture = promise::defer([=]() -> std::unique_ptr<RenderArea> {
+ RenderAreaFuture renderAreaFuture = ftl::defer([=]() -> std::unique_ptr<RenderArea> {
return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,
childrenOnly, layerStackSpaceRect,
captureSecureLayers);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 871222c..20f8f42 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -50,7 +50,6 @@
"LayerHistoryTest.cpp",
"LayerMetadataTest.cpp",
"MessageQueueTest.cpp",
- "PromiseTest.cpp",
"SurfaceFlinger_CreateDisplayTest.cpp",
"SurfaceFlinger_DestroyDisplayTest.cpp",
"SurfaceFlinger_GetDisplayNativePrimariesTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/PromiseTest.cpp b/services/surfaceflinger/tests/unittests/PromiseTest.cpp
deleted file mode 100644
index e4dc1fe..0000000
--- a/services/surfaceflinger/tests/unittests/PromiseTest.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <algorithm>
-#include <future>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "Promise.h"
-
-namespace android {
-namespace {
-
-using Bytes = std::vector<uint8_t>;
-
-Bytes decrement(Bytes bytes) {
- std::transform(bytes.begin(), bytes.end(), bytes.begin(), [](auto b) { return b - 1; });
- return bytes;
-}
-
-} // namespace
-
-TEST(PromiseTest, yield) {
- EXPECT_EQ(42, promise::yield(42).get());
-
- auto ptr = std::make_unique<char>('!');
- auto future = promise::yield(std::move(ptr));
- EXPECT_EQ('!', *future.get());
-}
-
-TEST(PromiseTest, chain) {
- std::packaged_task<const char*()> fetchString([] { return "ifmmp-"; });
-
- std::packaged_task<Bytes(std::string)> appendString([](std::string str) {
- str += "!xpsme";
- return Bytes{str.begin(), str.end()};
- });
-
- std::packaged_task<std::future<Bytes>(Bytes)> decrementBytes(
- [](Bytes bytes) { return promise::defer(decrement, std::move(bytes)); });
-
- auto fetch = fetchString.get_future();
- std::thread fetchThread(std::move(fetchString));
-
- std::thread appendThread, decrementThread;
-
- EXPECT_EQ("hello, world",
- promise::chain(std::move(fetch))
- .then([](const char* str) { return std::string(str); })
- .then([&](std::string str) {
- auto append = appendString.get_future();
- appendThread = std::thread(std::move(appendString), std::move(str));
- return append;
- })
- .then([&](Bytes bytes) {
- auto decrement = decrementBytes.get_future();
- decrementThread = std::thread(std::move(decrementBytes),
- std::move(bytes));
- return decrement;
- })
- .then([](std::future<Bytes> bytes) { return bytes; })
- .then([](const Bytes& bytes) {
- return std::string(bytes.begin(), bytes.end());
- })
- .get());
-
- fetchThread.join();
- appendThread.join();
- decrementThread.join();
-}
-
-} // namespace android