Loading include/ftl/algorithm.h +25 −0 Original line number Diff line number Diff line Loading @@ -68,4 +68,29 @@ constexpr auto to_mapped_ref(const Pair& pair) -> std::reference_wrapper<const M return std::cref(pair.second); } // Combinator for ftl::Optional<T>::or_else when T is std::reference_wrapper<const V>. Given a // lambda argument that returns a `constexpr` value, ftl::static_ref<T> binds a reference to a // static T initialized to that constant. // // const ftl::SmallMap map = ftl::init::map(13, "tiramisu"sv)(14, "upside-down cake"sv); // assert("???"sv == // map.get(20).or_else(ftl::static_ref<std::string_view>([] { return "???"sv; }))->get()); // // using Map = decltype(map); // // assert("snow cone"sv == // ftl::find_if(map, [](const auto& pair) { return pair.second.front() == 's'; }) // .transform(ftl::to_mapped_ref<Map>) // .or_else(ftl::static_ref<std::string_view>([] { return "snow cone"sv; })) // ->get()); // template <typename T, typename F> constexpr auto static_ref(F&& f) { return [f = std::forward<F>(f)] { constexpr auto kInitializer = f(); static const T kValue = kInitializer; return Optional(std::cref(kValue)); }; } } // namespace android::ftl libs/ftl/algorithm_test.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -47,4 +47,20 @@ TEST(Algorithm, FindIf) { EXPECT_EQ(opt->get(), ftl::StaticVector("tiramisu"sv)); } TEST(Algorithm, StaticRef) { using namespace std::string_view_literals; const ftl::SmallMap map = ftl::init::map(13, "tiramisu"sv)(14, "upside-down cake"sv); ASSERT_EQ("???"sv, map.get(20).or_else(ftl::static_ref<std::string_view>([] { return "???"sv; }))->get()); using Map = decltype(map); ASSERT_EQ("snow cone"sv, ftl::find_if(map, [](const auto& pair) { return pair.second.front() == 's'; }) .transform(ftl::to_mapped_ref<Map>) .or_else(ftl::static_ref<std::string_view>([] { return "snow cone"sv; })) ->get()); } } // namespace android::test services/surfaceflinger/Scheduler/RefreshRateStats.h +15 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <android-base/stringprintf.h> #include <ftl/algorithm.h> #include <ftl/small_map.h> #include <utils/Timers.h> Loading Loading @@ -82,12 +83,18 @@ public: flushTime(); TotalTimes totalTimes = ftl::init::map("ScreenOff", mScreenOffTime); const auto zero = std::chrono::milliseconds::zero(); // Sum the times for modes that map to the same name, e.g. "60 Hz". for (const auto& [fps, time] : mFpsTotalTimes) { const auto string = to_string(fps); const auto total = std::as_const(totalTimes).get(string).value_or(std::cref(zero)); const auto total = std::as_const(totalTimes) .get(string) .or_else(ftl::static_ref<std::chrono::milliseconds>([] { using namespace std::chrono_literals; return 0ms; })) .value(); totalTimes.emplace_or_replace(string, total.get() + time); } Loading @@ -114,15 +121,18 @@ private: mPreviousRecordedTime = currentTime; const auto duration = std::chrono::milliseconds{ns2ms(timeElapsed)}; const auto zero = std::chrono::milliseconds::zero(); uint32_t fps = 0; if (mCurrentPowerMode == PowerMode::ON) { // Normal power mode is counted under different config modes. const auto total = std::as_const(mFpsTotalTimes) .get(mCurrentRefreshRate) .value_or(std::cref(zero)); .or_else(ftl::static_ref<std::chrono::milliseconds>([] { using namespace std::chrono_literals; return 0ms; })) .value(); mFpsTotalTimes.emplace_or_replace(mCurrentRefreshRate, total.get() + duration); fps = static_cast<uint32_t>(mCurrentRefreshRate.getIntValue()); Loading services/surfaceflinger/Scheduler/Scheduler.h +3 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <ui/GraphicTypes.h> #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" #include <ftl/algorithm.h> #include <ftl/fake_guard.h> #include <ftl/optional.h> #include <scheduler/Features.h> Loading Loading @@ -438,13 +439,13 @@ private: RefreshRateSelectorPtr pacesetterSelectorPtrLocked() const REQUIRES(mDisplayLock) { ftl::FakeGuard guard(kMainThreadContext); const RefreshRateSelectorPtr noPacesetter; return mPacesetterDisplayId .and_then([this](PhysicalDisplayId pacesetterId) REQUIRES(mDisplayLock, kMainThreadContext) { return mRefreshRateSelectors.get(pacesetterId); }) .value_or(std::cref(noPacesetter)); .or_else(ftl::static_ref<RefreshRateSelectorPtr>([] { return nullptr; })) .value(); } std::shared_ptr<const VsyncSchedule> getVsyncScheduleLocked( Loading services/surfaceflinger/SurfaceFlinger.h +6 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <android/gui/ISurfaceComposerClient.h> #include <cutils/atomic.h> #include <cutils/compiler.h> #include <ftl/algorithm.h> #include <ftl/future.h> #include <ftl/non_null.h> #include <gui/BufferQueue.h> Loading Loading @@ -854,8 +855,9 @@ private: } sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) { const sp<DisplayDevice> nullDisplay; return mDisplays.get(displayToken).value_or(std::cref(nullDisplay)); return mDisplays.get(displayToken) .or_else(ftl::static_ref<sp<DisplayDevice>>([] { return nullptr; })) .value(); } sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const Loading Loading @@ -1011,10 +1013,10 @@ private: */ sp<display::DisplayToken> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { const sp<display::DisplayToken> nullToken; return mPhysicalDisplays.get(displayId) .transform([](const display::PhysicalDisplay& display) { return display.token(); }) .value_or(std::cref(nullToken)); .or_else([] { return std::optional<sp<display::DisplayToken>>(nullptr); }) .value(); } std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked( Loading Loading
include/ftl/algorithm.h +25 −0 Original line number Diff line number Diff line Loading @@ -68,4 +68,29 @@ constexpr auto to_mapped_ref(const Pair& pair) -> std::reference_wrapper<const M return std::cref(pair.second); } // Combinator for ftl::Optional<T>::or_else when T is std::reference_wrapper<const V>. Given a // lambda argument that returns a `constexpr` value, ftl::static_ref<T> binds a reference to a // static T initialized to that constant. // // const ftl::SmallMap map = ftl::init::map(13, "tiramisu"sv)(14, "upside-down cake"sv); // assert("???"sv == // map.get(20).or_else(ftl::static_ref<std::string_view>([] { return "???"sv; }))->get()); // // using Map = decltype(map); // // assert("snow cone"sv == // ftl::find_if(map, [](const auto& pair) { return pair.second.front() == 's'; }) // .transform(ftl::to_mapped_ref<Map>) // .or_else(ftl::static_ref<std::string_view>([] { return "snow cone"sv; })) // ->get()); // template <typename T, typename F> constexpr auto static_ref(F&& f) { return [f = std::forward<F>(f)] { constexpr auto kInitializer = f(); static const T kValue = kInitializer; return Optional(std::cref(kValue)); }; } } // namespace android::ftl
libs/ftl/algorithm_test.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -47,4 +47,20 @@ TEST(Algorithm, FindIf) { EXPECT_EQ(opt->get(), ftl::StaticVector("tiramisu"sv)); } TEST(Algorithm, StaticRef) { using namespace std::string_view_literals; const ftl::SmallMap map = ftl::init::map(13, "tiramisu"sv)(14, "upside-down cake"sv); ASSERT_EQ("???"sv, map.get(20).or_else(ftl::static_ref<std::string_view>([] { return "???"sv; }))->get()); using Map = decltype(map); ASSERT_EQ("snow cone"sv, ftl::find_if(map, [](const auto& pair) { return pair.second.front() == 's'; }) .transform(ftl::to_mapped_ref<Map>) .or_else(ftl::static_ref<std::string_view>([] { return "snow cone"sv; })) ->get()); } } // namespace android::test
services/surfaceflinger/Scheduler/RefreshRateStats.h +15 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <android-base/stringprintf.h> #include <ftl/algorithm.h> #include <ftl/small_map.h> #include <utils/Timers.h> Loading Loading @@ -82,12 +83,18 @@ public: flushTime(); TotalTimes totalTimes = ftl::init::map("ScreenOff", mScreenOffTime); const auto zero = std::chrono::milliseconds::zero(); // Sum the times for modes that map to the same name, e.g. "60 Hz". for (const auto& [fps, time] : mFpsTotalTimes) { const auto string = to_string(fps); const auto total = std::as_const(totalTimes).get(string).value_or(std::cref(zero)); const auto total = std::as_const(totalTimes) .get(string) .or_else(ftl::static_ref<std::chrono::milliseconds>([] { using namespace std::chrono_literals; return 0ms; })) .value(); totalTimes.emplace_or_replace(string, total.get() + time); } Loading @@ -114,15 +121,18 @@ private: mPreviousRecordedTime = currentTime; const auto duration = std::chrono::milliseconds{ns2ms(timeElapsed)}; const auto zero = std::chrono::milliseconds::zero(); uint32_t fps = 0; if (mCurrentPowerMode == PowerMode::ON) { // Normal power mode is counted under different config modes. const auto total = std::as_const(mFpsTotalTimes) .get(mCurrentRefreshRate) .value_or(std::cref(zero)); .or_else(ftl::static_ref<std::chrono::milliseconds>([] { using namespace std::chrono_literals; return 0ms; })) .value(); mFpsTotalTimes.emplace_or_replace(mCurrentRefreshRate, total.get() + duration); fps = static_cast<uint32_t>(mCurrentRefreshRate.getIntValue()); Loading
services/surfaceflinger/Scheduler/Scheduler.h +3 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <ui/GraphicTypes.h> #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" #include <ftl/algorithm.h> #include <ftl/fake_guard.h> #include <ftl/optional.h> #include <scheduler/Features.h> Loading Loading @@ -438,13 +439,13 @@ private: RefreshRateSelectorPtr pacesetterSelectorPtrLocked() const REQUIRES(mDisplayLock) { ftl::FakeGuard guard(kMainThreadContext); const RefreshRateSelectorPtr noPacesetter; return mPacesetterDisplayId .and_then([this](PhysicalDisplayId pacesetterId) REQUIRES(mDisplayLock, kMainThreadContext) { return mRefreshRateSelectors.get(pacesetterId); }) .value_or(std::cref(noPacesetter)); .or_else(ftl::static_ref<RefreshRateSelectorPtr>([] { return nullptr; })) .value(); } std::shared_ptr<const VsyncSchedule> getVsyncScheduleLocked( Loading
services/surfaceflinger/SurfaceFlinger.h +6 −4 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <android/gui/ISurfaceComposerClient.h> #include <cutils/atomic.h> #include <cutils/compiler.h> #include <ftl/algorithm.h> #include <ftl/future.h> #include <ftl/non_null.h> #include <gui/BufferQueue.h> Loading Loading @@ -854,8 +855,9 @@ private: } sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) { const sp<DisplayDevice> nullDisplay; return mDisplays.get(displayToken).value_or(std::cref(nullDisplay)); return mDisplays.get(displayToken) .or_else(ftl::static_ref<sp<DisplayDevice>>([] { return nullptr; })) .value(); } sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const Loading Loading @@ -1011,10 +1013,10 @@ private: */ sp<display::DisplayToken> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { const sp<display::DisplayToken> nullToken; return mPhysicalDisplays.get(displayId) .transform([](const display::PhysicalDisplay& display) { return display.token(); }) .value_or(std::cref(nullToken)); .or_else([] { return std::optional<sp<display::DisplayToken>>(nullptr); }) .value(); } std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked( Loading