Moving DispSync into Scheduler.

This change is part of go/surface-flinger-scheduler.

Test: SF tests pass.
Change-Id: I073a54c2111fa3146af3eb68f3294c3c5c95543c
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 54e19c7..18a8bb1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -20,15 +20,25 @@
 #include <cstdint>
 #include <memory>
 
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
+#include <configstore/Utils.h>
+
 #include <gui/ISurfaceComposer.h>
+#include <ui/DisplayStatInfo.h>
 
 #include "DispSync.h"
 #include "DispSyncSource.h"
+#include "EventControlThread.h"
 #include "EventThread.h"
 #include "InjectVSyncSource.h"
 
 namespace android {
 
+using namespace android::hardware::configstore;
+using namespace android::hardware::configstore::V1_0;
+
 #define RETURN_VALUE_IF_INVALID(value) \
     if (handle == nullptr || mConnections.count(handle->id) == 0) return value
 #define RETURN_IF_INVALID() \
@@ -36,17 +46,34 @@
 
 std::atomic<int64_t> Scheduler::sNextId = 0;
 
+Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function)
+      : mHasSyncFramework(
+                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasSyncFramework>(true)),
+        mDispSyncPresentTimeOffset(
+                getInt64<ISurfaceFlingerConfigs,
+                         &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0)),
+        mPrimaryHWVsyncEnabled(false),
+        mHWVsyncAvailable(false) {
+    // Note: We create a local temporary with the real DispSync implementation
+    // type temporarily so we can initialize it with the configured values,
+    // before storing it for more generic use using the interface type.
+    auto primaryDispSync = std::make_unique<impl::DispSync>("SchedulerDispSync");
+    primaryDispSync->init(mHasSyncFramework, mDispSyncPresentTimeOffset);
+    mPrimaryDispSync = std::move(primaryDispSync);
+    mEventControlThread = std::make_unique<impl::EventControlThread>(function);
+}
+
 Scheduler::~Scheduler() = default;
 
 sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
-        const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
+        const std::string& connectionName, int64_t phaseOffsetNs,
         impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
         impl::EventThread::InterceptVSyncsCallback interceptCallback) {
     const int64_t id = sNextId++;
     ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
 
     std::unique_ptr<EventThread> eventThread =
-            makeEventThread(connectionName, dispSync, phaseOffsetNs, resyncCallback,
+            makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs, resyncCallback,
                             interceptCallback);
     auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
                                                    eventThread->createEventConnection(),
@@ -108,4 +135,65 @@
     RETURN_IF_INVALID();
     mConnections[handle->id]->thread->setPhaseOffset(phaseOffset);
 }
+
+void Scheduler::getDisplayStatInfo(DisplayStatInfo* stats) {
+    stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
+    stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
+}
+
+void Scheduler::enableHardwareVsync() {
+    std::lock_guard<std::mutex> lock(mHWVsyncLock);
+    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
+        mPrimaryDispSync->beginResync();
+        mEventControlThread->setVsyncEnabled(true);
+        mPrimaryHWVsyncEnabled = true;
+    }
+}
+
+void Scheduler::disableHardwareVsync(bool makeUnavailable) {
+    std::lock_guard<std::mutex> lock(mHWVsyncLock);
+    if (mPrimaryHWVsyncEnabled) {
+        mEventControlThread->setVsyncEnabled(false);
+        mPrimaryDispSync->endResync();
+        mPrimaryHWVsyncEnabled = false;
+    }
+    if (makeUnavailable) {
+        mHWVsyncAvailable = false;
+    }
+}
+
+void Scheduler::setVsyncPeriod(const nsecs_t period) {
+    mPrimaryDispSync->reset();
+    mPrimaryDispSync->setPeriod(period);
+    enableHardwareVsync();
+}
+
+void Scheduler::addResyncSample(const nsecs_t timestamp) {
+    bool needsHwVsync = false;
+    { // Scope for the lock
+        std::lock_guard<std::mutex> lock(mHWVsyncLock);
+        if (mPrimaryHWVsyncEnabled) {
+            needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
+        }
+    }
+
+    if (needsHwVsync) {
+        enableHardwareVsync();
+    } else {
+        disableHardwareVsync(false);
+    }
+}
+
+void Scheduler::addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) {
+    if (mPrimaryDispSync->addPresentFence(fenceTime)) {
+        enableHardwareVsync();
+    } else {
+        disableHardwareVsync(false);
+    }
+}
+
+void Scheduler::setIgnorePresentFences(bool ignore) {
+    mPrimaryDispSync->setIgnorePresentFences(ignore);
+}
+
 } // namespace android