SF: Set up libscheduler headers

Start pulling Scheduler sources into a libscheduler target akin to
librenderengine and libcompositionengine.

Bug: 185535769
Test: Build
Change-Id: I8ee871cce96209c8c53601152501129b09c5e46f
diff --git a/services/surfaceflinger/Scheduler/Android.bp b/services/surfaceflinger/Scheduler/Android.bp
new file mode 100644
index 0000000..2318a57
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/Android.bp
@@ -0,0 +1,26 @@
+cc_defaults {
+    name: "libscheduler_defaults",
+    defaults: ["surfaceflinger_defaults"],
+    cflags: [
+        "-DLOG_TAG=\"Scheduler\"",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    shared_libs: [
+        "libbase",
+        "libutils",
+    ],
+}
+
+cc_library_headers {
+    name: "libscheduler_headers",
+    defaults: ["libscheduler_defaults"],
+    export_include_dirs: ["include"],
+}
+
+cc_library_static {
+    name: "libscheduler",
+    defaults: ["libscheduler_defaults"],
+    srcs: [],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h
index 92abbae..18ed95e 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.h
+++ b/services/surfaceflinger/Scheduler/LayerInfo.h
@@ -16,15 +16,19 @@
 
 #pragma once
 
+#include <chrono>
+#include <deque>
+#include <optional>
+#include <string>
+#include <unordered_map>
+
 #include <ui/Transform.h>
 #include <utils/Timers.h>
 
-#include <chrono>
-#include <deque>
+#include <scheduler/Seamlessness.h>
 
 #include "LayerHistory.h"
 #include "RefreshRateConfigs.h"
-#include "Scheduler/Seamlessness.h"
 #include "SchedulerUtils.h"
 
 namespace android {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 53472ef..85c31e8 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -16,20 +16,21 @@
 
 #pragma once
 
-#include <android-base/stringprintf.h>
-#include <gui/DisplayEventReceiver.h>
-
 #include <algorithm>
 #include <numeric>
 #include <optional>
 #include <type_traits>
 
+#include <android-base/stringprintf.h>
+#include <gui/DisplayEventReceiver.h>
+
+#include <scheduler/Fps.h>
+#include <scheduler/Seamlessness.h>
+
 #include "DisplayHardware/DisplayMode.h"
 #include "DisplayHardware/HWComposer.h"
-#include "Fps.h"
 #include "Scheduler/OneShotTimer.h"
 #include "Scheduler/SchedulerUtils.h"
-#include "Scheduler/Seamlessness.h"
 #include "Scheduler/StrongTyping.h"
 
 namespace android::scheduler {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateStats.h b/services/surfaceflinger/Scheduler/RefreshRateStats.h
index 80aa96f..23ebb06 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateStats.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateStats.h
@@ -23,7 +23,8 @@
 #include <ftl/small_map.h>
 #include <utils/Timers.h>
 
-#include "Fps.h"
+#include <scheduler/Fps.h>
+
 #include "Scheduler/SchedulerUtils.h"
 #include "TimeStats/TimeStats.h"
 
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 95750ad..76315d2 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -17,7 +17,9 @@
 #pragma once
 
 #include <utils/Timers.h>
-#include "Fps.h"
+
+#include <scheduler/Fps.h>
+
 #include "VSyncDispatch.h"
 
 namespace android::scheduler {
diff --git a/services/surfaceflinger/Scheduler/VsyncConfiguration.h b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
index 8447512..02ebd70 100644
--- a/services/surfaceflinger/Scheduler/VsyncConfiguration.h
+++ b/services/surfaceflinger/Scheduler/VsyncConfiguration.h
@@ -23,7 +23,8 @@
 #include <ftl/small_map.h>
 #include <utils/Timers.h>
 
-#include "Fps.h"
+#include <scheduler/Fps.h>
+
 #include "VsyncModulator.h"
 
 namespace android::scheduler {
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Fps.h b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h
new file mode 100644
index 0000000..639b3e5
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h
@@ -0,0 +1,128 @@
+/*
+ * 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 <cmath>
+#include <ostream>
+#include <string>
+#include <type_traits>
+
+#include <android-base/stringprintf.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+// Frames per second, stored as floating-point frequency. Provides conversion from/to period in
+// nanoseconds, and relational operators with precision threshold.
+//
+//     const Fps fps = 60_Hz;
+//
+//     using namespace fps_approx_ops;
+//     assert(fps == Fps::fromPeriodNsecs(16'666'667));
+//
+class Fps {
+public:
+    constexpr Fps() = default;
+
+    static constexpr Fps fromValue(float frequency) {
+        return frequency > 0.f ? Fps(frequency, static_cast<nsecs_t>(1e9f / frequency)) : Fps();
+    }
+
+    static constexpr Fps fromPeriodNsecs(nsecs_t period) {
+        return period > 0 ? Fps(1e9f / period, period) : Fps();
+    }
+
+    constexpr bool isValid() const { return mFrequency > 0.f; }
+
+    constexpr float getValue() const { return mFrequency; }
+    int getIntValue() const { return static_cast<int>(std::round(mFrequency)); }
+
+    constexpr nsecs_t getPeriodNsecs() const { return mPeriod; }
+
+private:
+    constexpr Fps(float frequency, nsecs_t period) : mFrequency(frequency), mPeriod(period) {}
+
+    float mFrequency = 0.f;
+    nsecs_t mPeriod = 0;
+};
+
+static_assert(std::is_trivially_copyable_v<Fps>);
+
+constexpr Fps operator""_Hz(unsigned long long frequency) {
+    return Fps::fromValue(static_cast<float>(frequency));
+}
+
+constexpr Fps operator""_Hz(long double frequency) {
+    return Fps::fromValue(static_cast<float>(frequency));
+}
+
+inline bool isStrictlyLess(Fps lhs, Fps rhs) {
+    return lhs.getValue() < rhs.getValue();
+}
+
+// Does not satisfy equivalence relation.
+inline bool isApproxEqual(Fps lhs, Fps rhs) {
+    // TODO(b/185536303): Replace with ULP distance.
+    return std::abs(lhs.getValue() - rhs.getValue()) < 0.001f;
+}
+
+// Does not satisfy strict weak order.
+inline bool isApproxLess(Fps lhs, Fps rhs) {
+    return isStrictlyLess(lhs, rhs) && !isApproxEqual(lhs, rhs);
+}
+
+namespace fps_approx_ops {
+
+inline bool operator==(Fps lhs, Fps rhs) {
+    return isApproxEqual(lhs, rhs);
+}
+
+inline bool operator<(Fps lhs, Fps rhs) {
+    return isApproxLess(lhs, rhs);
+}
+
+inline bool operator!=(Fps lhs, Fps rhs) {
+    return !isApproxEqual(lhs, rhs);
+}
+
+inline bool operator>(Fps lhs, Fps rhs) {
+    return isApproxLess(rhs, lhs);
+}
+
+inline bool operator<=(Fps lhs, Fps rhs) {
+    return !isApproxLess(rhs, lhs);
+}
+
+inline bool operator>=(Fps lhs, Fps rhs) {
+    return !isApproxLess(lhs, rhs);
+}
+
+} // namespace fps_approx_ops
+
+struct FpsApproxEqual {
+    bool operator()(Fps lhs, Fps rhs) const { return isApproxEqual(lhs, rhs); }
+};
+
+inline std::string to_string(Fps fps) {
+    return base::StringPrintf("%.2f Hz", fps.getValue());
+}
+
+inline std::ostream& operator<<(std::ostream& stream, Fps fps) {
+    return stream << to_string(fps);
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/Scheduler/Seamlessness.h b/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h
similarity index 93%
rename from services/surfaceflinger/Scheduler/Seamlessness.h
rename to services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h
index 3e42a4d..d7667ec 100644
--- a/services/surfaceflinger/Scheduler/Seamlessness.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h
@@ -16,11 +16,10 @@
 
 #pragma once
 
-#include <cstring>
 #include <ostream>
+#include <string>
 
-namespace android {
-namespace scheduler {
+namespace android::scheduler {
 
 // The seamlessness requirement of a Layer.
 enum class Seamlessness {
@@ -50,5 +49,4 @@
     return os << toString(val);
 }
 
-} // namespace scheduler
-} // namespace android
+} // namespace android::scheduler