SF: Hook up VSYNC injection to Scheduler
This CL refactors VSYNC injection to interface with the Scheduler API,
and removes otherwise unused EventThread members.
Bug: 128863962
Test: sffakehwc_test
Change-Id: I2ba143bb78baf3e66a47b90163eacf0d0e431124
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.h b/services/surfaceflinger/Scheduler/DispSyncSource.h
index 740c8c4..536464e 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.h
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.h
@@ -32,6 +32,7 @@
~DispSyncSource() override = default;
// The following methods are implementation of VSyncSource.
+ const char* getName() const override { return mName; }
void setVSyncEnabled(bool enable) override;
void setCallback(VSyncSource::Callback* callback) override;
void setPhaseOffset(nsecs_t phaseOffset) override;
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 9d1f777..8d9adc8 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -154,23 +154,11 @@
namespace impl {
-EventThread::EventThread(std::unique_ptr<VSyncSource> src,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
- : EventThread(nullptr, std::move(src), std::move(interceptVSyncsCallback), threadName) {}
-
-EventThread::EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
- const char* threadName)
- : EventThread(src, nullptr, std::move(interceptVSyncsCallback), threadName) {}
-
-EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
- : mVSyncSource(src),
- mVSyncSourceUnique(std::move(uniqueSrc)),
+EventThread::EventThread(std::unique_ptr<VSyncSource> vsyncSource,
+ InterceptVSyncsCallback interceptVSyncsCallback)
+ : mVSyncSource(std::move(vsyncSource)),
mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),
- mThreadName(threadName) {
- if (src == nullptr) {
- mVSyncSource = mVSyncSourceUnique.get();
- }
+ mThreadName(mVSyncSource->getName()) {
mVSyncSource->setCallback(this);
mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
@@ -178,7 +166,7 @@
threadMain(lock);
});
- pthread_setname_np(mThread.native_handle(), threadName);
+ pthread_setname_np(mThread.native_handle(), mThreadName);
pid_t tid = pthread_gettid_np(mThread.native_handle());
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index dd23b88..a029586 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -62,6 +62,8 @@
};
virtual ~VSyncSource() {}
+
+ virtual const char* getName() const = 0;
virtual void setVSyncEnabled(bool enable) = 0;
virtual void setCallback(Callback* callback) = 0;
virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
@@ -126,9 +128,7 @@
public:
using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
- // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete.
- EventThread(VSyncSource*, InterceptVSyncsCallback, const char* threadName);
- EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback, const char* threadName);
+ EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback);
~EventThread();
sp<EventThreadConnection> createEventConnection(
@@ -157,10 +157,6 @@
using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
- // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete.
- EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
- InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
-
void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex);
bool shouldConsumeEvent(const DisplayEventReceiver::Event& event,
@@ -174,9 +170,7 @@
// Implements VSyncSource::Callback
void onVSyncEvent(nsecs_t timestamp) override;
- // TODO(b/128863962): Once the Scheduler is complete this pointer will become obsolete.
- VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
- std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
+ const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
const InterceptVSyncsCallback mInterceptVSyncsCallback;
const char* const mThreadName;
diff --git a/services/surfaceflinger/Scheduler/InjectVSyncSource.h b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
index 90609af..6c502e6 100644
--- a/services/surfaceflinger/Scheduler/InjectVSyncSource.h
+++ b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
@@ -42,6 +42,7 @@
}
}
+ const char* getName() const override { return "inject"; }
void setVSyncEnabled(bool) override {}
void setPhaseOffset(nsecs_t) override {}
void pauseVsyncCallback(bool) {}
@@ -51,4 +52,4 @@
VSyncSource::Callback* mCallback GUARDED_BY(mCallbackMutex) = nullptr;
};
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index fcb307f..5318b00 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -85,24 +85,6 @@
mHandler = new Handler(*this);
}
-void MessageQueue::setEventThread(android::EventThread* eventThread,
- ResyncCallback resyncCallback) {
- if (mEventThread == eventThread) {
- return;
- }
-
- if (mEventTube.getFd() >= 0) {
- mLooper->removeFd(mEventTube.getFd());
- }
-
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection(std::move(resyncCallback),
- ISurfaceComposer::eConfigChangedSuppress);
- mEvents->stealReceiveChannel(&mEventTube);
- mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
- this);
-}
-
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 0b2206d..fcfc4aa 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -85,8 +85,6 @@
virtual ~MessageQueue();
virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
- // TODO(b/128863962): Remove this function once everything is migrated to Scheduler.
- virtual void setEventThread(EventThread* events, ResyncCallback resyncCallback) = 0;
virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
virtual void waitMessage() = 0;
virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
@@ -115,7 +113,6 @@
sp<SurfaceFlinger> mFlinger;
sp<Looper> mLooper;
- android::EventThread* mEventThread;
sp<EventThreadConnection> mEvents;
gui::BitTube mEventTube;
sp<Handler> mHandler;
@@ -126,7 +123,6 @@
public:
~MessageQueue() override = default;
void init(const sp<SurfaceFlinger>& flinger) override;
- void setEventThread(android::EventThread* events, ResyncCallback resyncCallback) override;
void setEventConnection(const sp<EventThreadConnection>& connection) override;
void waitMessage() override;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index add56fc..d60e101 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -41,6 +41,7 @@
#include "DispSyncSource.h"
#include "EventControlThread.h"
#include "EventThread.h"
+#include "InjectVSyncSource.h"
#include "OneShotTimer.h"
#include "SchedulerUtils.h"
#include "SurfaceFlingerProperties.h"
@@ -116,11 +117,20 @@
return *mPrimaryDispSync;
}
+std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
+ const char* name, nsecs_t phaseOffsetNs, nsecs_t offsetThresholdForNextVsync) {
+ return std::make_unique<DispSyncSource>(mPrimaryDispSync.get(), phaseOffsetNs,
+ offsetThresholdForNextVsync, true /* traceVsync */,
+ name);
+}
+
Scheduler::ConnectionHandle Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs, nsecs_t offsetThresholdForNextVsync,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
- auto eventThread = makeEventThread(connectionName, phaseOffsetNs, offsetThresholdForNextVsync,
- std::move(interceptCallback));
+ auto vsyncSource =
+ makePrimaryDispSyncSource(connectionName, phaseOffsetNs, offsetThresholdForNextVsync);
+ auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),
+ std::move(interceptCallback));
return createConnection(std::move(eventThread));
}
@@ -135,16 +145,6 @@
return handle;
}
-std::unique_ptr<EventThread> Scheduler::makeEventThread(
- const char* connectionName, nsecs_t phaseOffsetNs, nsecs_t offsetThresholdForNextVsync,
- impl::EventThread::InterceptVSyncsCallback&& interceptCallback) {
- auto source = std::make_unique<DispSyncSource>(mPrimaryDispSync.get(), phaseOffsetNs,
- offsetThresholdForNextVsync,
- true /* traceVsync */, connectionName);
- return std::make_unique<impl::EventThread>(std::move(source), std::move(interceptCallback),
- connectionName);
-}
-
sp<EventThreadConnection> Scheduler::createConnectionInternal(
EventThread* eventThread, ISurfaceComposer::ConfigChanged configChanged) {
return eventThread->createEventConnection([&] { resync(); }, configChanged);
@@ -156,11 +156,6 @@
return createConnectionInternal(mConnections[handle].thread.get(), configChanged);
}
-EventThread* Scheduler::getEventThread(ConnectionHandle handle) {
- RETURN_IF_INVALID_HANDLE(handle, nullptr);
- return mConnections[handle].thread.get();
-}
-
sp<EventThreadConnection> Scheduler::getEventConnection(ConnectionHandle handle) {
RETURN_IF_INVALID_HANDLE(handle, nullptr);
return mConnections[handle].connection;
@@ -203,6 +198,37 @@
stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
}
+Scheduler::ConnectionHandle Scheduler::enableVSyncInjection(bool enable) {
+ if (mInjectVSyncs == enable) {
+ return {};
+ }
+
+ ALOGV("%s VSYNC injection", enable ? "Enabling" : "Disabling");
+
+ if (!mInjectorConnectionHandle) {
+ auto vsyncSource = std::make_unique<InjectVSyncSource>();
+ mVSyncInjector = vsyncSource.get();
+
+ auto eventThread =
+ std::make_unique<impl::EventThread>(std::move(vsyncSource),
+ impl::EventThread::InterceptVSyncsCallback());
+
+ mInjectorConnectionHandle = createConnection(std::move(eventThread));
+ }
+
+ mInjectVSyncs = enable;
+ return mInjectorConnectionHandle;
+}
+
+bool Scheduler::injectVSync(nsecs_t when) {
+ if (!mInjectVSyncs || !mVSyncInjector) {
+ return false;
+ }
+
+ mVSyncInjector->onInjectSyncEvent(when);
+ return true;
+}
+
void Scheduler::enableHardwareVsync() {
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 0c8c335..a5971fe 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -36,6 +36,7 @@
class DispSync;
class FenceTime;
+class InjectVSyncSource;
struct DisplayStateInfo;
class Scheduler {
@@ -63,7 +64,6 @@
sp<IDisplayEventConnection> createDisplayEventConnection(ConnectionHandle,
ISurfaceComposer::ConfigChanged);
- EventThread* getEventThread(ConnectionHandle);
sp<EventThreadConnection> getEventConnection(ConnectionHandle);
void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
@@ -77,6 +77,12 @@
void getDisplayStatInfo(DisplayStatInfo* stats);
+ // Returns injector handle if injection has toggled, or an invalid handle otherwise.
+ ConnectionHandle enableVSyncInjection(bool enable);
+
+ // Returns false if injection is disabled.
+ bool injectVSync(nsecs_t when);
+
void enableHardwareVsync();
void disableHardwareVsync(bool makeUnavailable);
@@ -138,12 +144,10 @@
Scheduler(std::unique_ptr<DispSync>, std::unique_ptr<EventControlThread>,
const scheduler::RefreshRateConfigs&);
- // Creates a connection on the given EventThread and forwards the given callbacks.
- std::unique_ptr<EventThread> makeEventThread(const char* connectionName, nsecs_t phaseOffsetNs,
- nsecs_t offsetThresholdForNextVsync,
- impl::EventThread::InterceptVSyncsCallback&&);
+ std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name, nsecs_t phaseOffsetNs,
+ nsecs_t offsetThresholdForNextVsync);
- // Create a connection on the given EventThread and forward the resync callback.
+ // Create a connection on the given EventThread.
ConnectionHandle createConnection(std::unique_ptr<EventThread>);
sp<EventThreadConnection> createConnectionInternal(EventThread*,
ISurfaceComposer::ConfigChanged);
@@ -173,6 +177,10 @@
ConnectionHandle::Id mNextConnectionHandleId = 0;
std::unordered_map<ConnectionHandle, Connection> mConnections;
+ bool mInjectVSyncs = false;
+ InjectVSyncSource* mVSyncInjector = nullptr;
+ ConnectionHandle mInjectorConnectionHandle;
+
std::mutex mHWVsyncLock;
bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock) = false;
bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock) = false;