SF: Creating a basic Scheduler class.
Added a flag that can be turned on at runtime, and turns on the new path.
Added a basic Scheduler that encapsulates SF and App thread.
This is part of the go/surfce-flinger-scheduler move.
Test: All SF tests pass. Adding a Scheduler test in the next CL.
Change-Id: Ic45b662f82d60da1172bf64485c838344082b306
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 124b773..8c46e8a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -87,6 +87,7 @@
#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/InjectVSyncSource.h"
+#include "Scheduler/Scheduler.h"
#include <cutils/compiler.h>
@@ -399,6 +400,9 @@
property_get("debug.sf.early_gl_app_phase_offset_ns", value, "-1");
const int earlyGlAppOffsetNs = atoi(value);
+ property_get("debug.sf.use_scheduler", value, "0");
+ mUseScheduler = atoi(value);
+
const VSyncModulator::Offsets earlyOffsets =
{earlySfOffsetNs != -1 ? earlySfOffsetNs : sfVsyncPhaseOffsetNs,
earlyAppOffsetNs != -1 ? earlyAppOffsetNs : vsyncPhaseOffsetNs};
@@ -595,26 +599,47 @@
Mutex::Autolock _l(mStateLock);
// start the EventThread
- mEventThreadSource =
- std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
- SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
- mEventThread = std::make_unique<impl::EventThread>(mEventThreadSource.get(),
- [this] { resyncWithRateLimit(); },
- impl::EventThread::InterceptVSyncsCallback(),
- "appEventThread");
- mSfEventThreadSource =
- std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
- SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
+ if (mUseScheduler) {
+ mScheduler = std::make_unique<Scheduler>();
+ mAppConnectionHandle =
+ mScheduler->createConnection("appConnection", mPrimaryDispSync.get(),
+ SurfaceFlinger::vsyncPhaseOffsetNs,
+ [this] { resyncWithRateLimit(); },
+ impl::EventThread::InterceptVSyncsCallback());
+ mSfConnectionHandle =
+ mScheduler->createConnection("sfConnection", mPrimaryDispSync.get(),
+ SurfaceFlinger::sfVsyncPhaseOffsetNs,
+ [this] { resyncWithRateLimit(); },
+ [this](nsecs_t timestamp) {
+ mInterceptor->saveVSyncEvent(timestamp);
+ });
- mSFEventThread =
- std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),
- [this] { resyncWithRateLimit(); },
- [this](nsecs_t timestamp) {
- mInterceptor->saveVSyncEvent(timestamp);
- },
- "sfEventThread");
- mEventQueue->setEventThread(mSFEventThread.get());
- mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
+ mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
+ mVsyncModulator.setEventThreads(mScheduler->getEventThread(mSfConnectionHandle),
+ mScheduler->getEventThread(mAppConnectionHandle));
+ } else {
+ mEventThreadSource =
+ std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
+ SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
+ mEventThread =
+ std::make_unique<impl::EventThread>(mEventThreadSource.get(),
+ [this] { resyncWithRateLimit(); },
+ impl::EventThread::InterceptVSyncsCallback(),
+ "appEventThread");
+ mSfEventThreadSource =
+ std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
+ SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
+
+ mSFEventThread =
+ std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),
+ [this] { resyncWithRateLimit(); },
+ [this](nsecs_t timestamp) {
+ mInterceptor->saveVSyncEvent(timestamp);
+ },
+ "sfEventThread");
+ mEventQueue->setEventThread(mSFEventThread.get());
+ mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
+ }
// Get a RenderEngine for the given display / config (can't fail)
int32_t renderEngineFeature = 0;
@@ -1083,6 +1108,8 @@
return;
}
+ // TODO(akrulec): Part of the Injector should be refactored, so that it
+ // can be passed to Scheduler.
if (enable) {
ALOGV("VSync Injections enabled");
if (mVSyncInjector.get() == nullptr) {
@@ -1141,10 +1168,18 @@
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
- if (vsyncSource == eVsyncSourceSurfaceFlinger) {
- return mSFEventThread->createEventConnection();
+ if (mUseScheduler) {
+ if (vsyncSource == eVsyncSourceSurfaceFlinger) {
+ return mScheduler->createDisplayEventConnection(mSfConnectionHandle);
+ } else {
+ return mScheduler->createDisplayEventConnection(mAppConnectionHandle);
+ }
} else {
- return mEventThread->createEventConnection();
+ if (vsyncSource == eVsyncSourceSurfaceFlinger) {
+ return mSFEventThread->createEventConnection();
+ } else {
+ return mEventThread->createEventConnection();
+ }
}
}
@@ -2508,9 +2543,19 @@
display->disconnect(getHwComposer());
}
if (draw[i].type == DisplayDevice::DISPLAY_PRIMARY) {
- mEventThread->onHotplugReceived(EventThread::DisplayType::Primary, false);
+ if (mUseScheduler) {
+ mScheduler->hotplugReceived(mAppConnectionHandle,
+ EventThread::DisplayType::Primary, false);
+ } else {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::Primary, false);
+ }
} else if (draw[i].type == DisplayDevice::DISPLAY_EXTERNAL) {
- mEventThread->onHotplugReceived(EventThread::DisplayType::External, false);
+ if (mUseScheduler) {
+ mScheduler->hotplugReceived(mAppConnectionHandle,
+ EventThread::DisplayType::External, false);
+ } else {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::External, false);
+ }
}
mDisplays.erase(draw.keyAt(i));
} else {
@@ -2613,11 +2658,23 @@
dispSurface, producer));
if (!state.isVirtual()) {
if (state.type == DisplayDevice::DISPLAY_PRIMARY) {
- mEventThread->onHotplugReceived(EventThread::DisplayType::Primary,
+ if (mUseScheduler) {
+ mScheduler->hotplugReceived(mAppConnectionHandle,
+ EventThread::DisplayType::Primary,
true);
+ } else {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::Primary,
+ true);
+ }
} else if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
- mEventThread->onHotplugReceived(EventThread::DisplayType::External,
+ if (mUseScheduler) {
+ mScheduler->hotplugReceived(mAppConnectionHandle,
+ EventThread::DisplayType::External,
true);
+ } else {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::External,
+ true);
+ }
}
}
}
@@ -3942,7 +3999,11 @@
getHwComposer().setPowerMode(type, mode);
if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
// FIXME: eventthread only knows about the main display right now
- mEventThread->onScreenAcquired();
+ if (mUseScheduler) {
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ } else {
+ mEventThread->onScreenAcquired();
+ }
resyncToHardwareVsync(true);
}
@@ -3966,7 +4027,11 @@
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
- mEventThread->onScreenReleased();
+ if (mUseScheduler) {
+ mScheduler->onScreenReleased(mAppConnectionHandle);
+ } else {
+ mEventThread->onScreenReleased();
+ }
}
getHwComposer().setPowerMode(type, mode);
@@ -3978,7 +4043,11 @@
getHwComposer().setPowerMode(type, mode);
if (display->isPrimary() && currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
// FIXME: eventthread only knows about the main display right now
- mEventThread->onScreenAcquired();
+ if (mUseScheduler) {
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ } else {
+ mEventThread->onScreenAcquired();
+ }
resyncToHardwareVsync(true);
}
} else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
@@ -3986,7 +4055,11 @@
if (display->isPrimary()) {
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
- mEventThread->onScreenReleased();
+ if (mUseScheduler) {
+ mScheduler->onScreenReleased(mAppConnectionHandle);
+ } else {
+ mEventThread->onScreenReleased();
+ }
}
getHwComposer().setPowerMode(type, mode);
} else {
@@ -4584,10 +4657,15 @@
result.appendFormat(" transaction time: %f us\n",
inTransactionDuration/1000.0);
+ result.appendFormat(" use Scheduler: %s\n", mUseScheduler ? "true" : "false");
/*
* VSYNC state
*/
- mEventThread->dump(result);
+ if (mUseScheduler) {
+ mScheduler->dump(mAppConnectionHandle, result);
+ } else {
+ mEventThread->dump(result);
+ }
result.append("\n");
/*
@@ -4923,12 +5001,20 @@
}
case 1018: { // Modify Choreographer's phase offset
n = data.readInt32();
- mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+ if (mUseScheduler) {
+ mScheduler->setPhaseOffset(mAppConnectionHandle, static_cast<nsecs_t>(n));
+ } else {
+ mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+ }
return NO_ERROR;
}
case 1019: { // Modify SurfaceFlinger's phase offset
n = data.readInt32();
- mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+ if (mUseScheduler) {
+ mScheduler->setPhaseOffset(mSfConnectionHandle, static_cast<nsecs_t>(n));
+ } else {
+ mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+ }
return NO_ERROR;
}
case 1020: { // Layer updates interceptor