Merge "SF: Remove ConnectionHandle concept in Scheduler" into main
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 6979f03..e6c58a3 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -60,14 +60,6 @@
#include "VsyncController.h"
#include "VsyncSchedule.h"
-#define RETURN_IF_INVALID_HANDLE(handle, ...) \
- do { \
- if (mConnections.count(handle) == 0) { \
- ALOGE("Invalid connection handle %" PRIuPTR, handle.id); \
- return __VA_ARGS__; \
- } \
- } while (false)
-
namespace android::scheduler {
Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features,
@@ -344,40 +336,26 @@
}
}
-ConnectionHandle Scheduler::createEventThread(Cycle cycle,
- frametimeline::TokenManager* tokenManager,
- std::chrono::nanoseconds workDuration,
- std::chrono::nanoseconds readyDuration) {
+void Scheduler::createEventThread(Cycle cycle, frametimeline::TokenManager* tokenManager,
+ std::chrono::nanoseconds workDuration,
+ std::chrono::nanoseconds readyDuration) {
auto eventThread =
std::make_unique<android::impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
getVsyncSchedule(), tokenManager, *this,
workDuration, readyDuration);
- auto& handle = cycle == Cycle::Render ? mAppConnectionHandle : mSfConnectionHandle;
- handle = createConnection(std::move(eventThread));
- return handle;
-}
-
-ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventThread) {
- const ConnectionHandle handle = ConnectionHandle{mNextConnectionHandleId++};
- ALOGV("Creating a connection handle with ID %" PRIuPTR, handle.id);
-
- auto connection = eventThread->createEventConnection();
-
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- mConnections.emplace(handle, Connection{connection, std::move(eventThread)});
- return handle;
+ if (cycle == Cycle::Render) {
+ mRenderEventThread = std::move(eventThread);
+ mRenderEventConnection = mRenderEventThread->createEventConnection();
+ } else {
+ mLastCompositeEventThread = std::move(eventThread);
+ mLastCompositeEventConnection = mLastCompositeEventThread->createEventConnection();
+ }
}
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
- ConnectionHandle handle, EventRegistrationFlags eventRegistration,
- const sp<IBinder>& layerHandle) {
- const auto connection = [&]() -> sp<EventThreadConnection> {
- std::scoped_lock lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle, nullptr);
-
- return mConnections[handle].thread->createEventConnection(eventRegistration);
- }();
+ Cycle cycle, EventRegistrationFlags eventRegistration, const sp<IBinder>& layerHandle) {
+ const auto connection = eventThreadFor(cycle).createEventConnection(eventRegistration);
const auto layerId = static_cast<int32_t>(LayerHandle::getLayerId(layerHandle));
if (layerId != static_cast<int32_t>(UNASSIGNED_LAYER_ID)) {
@@ -397,85 +375,48 @@
return connection;
}
-sp<EventThreadConnection> Scheduler::getEventConnection(ConnectionHandle handle) {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle, nullptr);
- return mConnections[handle].connection;
+void Scheduler::onHotplugReceived(Cycle cycle, PhysicalDisplayId displayId, bool connected) {
+ if (hasEventThreads()) {
+ eventThreadFor(cycle).onHotplugReceived(displayId, connected);
+ }
}
-void Scheduler::onHotplugReceived(ConnectionHandle handle, PhysicalDisplayId displayId,
- bool connected) {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
+void Scheduler::onHotplugConnectionError(Cycle cycle, int32_t errorCode) {
+ if (hasEventThreads()) {
+ eventThreadFor(cycle).onHotplugConnectionError(errorCode);
}
-
- thread->onHotplugReceived(displayId, connected);
-}
-
-void Scheduler::onHotplugConnectionError(ConnectionHandle handle, int32_t errorCode) {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
- }
-
- thread->onHotplugConnectionError(errorCode);
}
void Scheduler::enableSyntheticVsync(bool enable) {
- // TODO(b/241285945): Remove connection handles.
- const ConnectionHandle handle = mAppConnectionHandle;
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
- }
- thread->enableSyntheticVsync(enable);
+ eventThreadFor(Cycle::Render).enableSyntheticVsync(enable);
}
-void Scheduler::onFrameRateOverridesChanged(ConnectionHandle handle, PhysicalDisplayId displayId) {
+void Scheduler::onFrameRateOverridesChanged(Cycle cycle, PhysicalDisplayId displayId) {
const bool supportsFrameRateOverrideByContent =
pacesetterSelectorPtr()->supportsAppFrameRateOverrideByContent();
std::vector<FrameRateOverride> overrides =
mFrameRateOverrideMappings.getAllFrameRateOverrides(supportsFrameRateOverrideByContent);
- android::EventThread* thread;
- {
- std::lock_guard lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
- }
- thread->onFrameRateOverridesChanged(displayId, std::move(overrides));
+ eventThreadFor(cycle).onFrameRateOverridesChanged(displayId, std::move(overrides));
}
-void Scheduler::onHdcpLevelsChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
+void Scheduler::onHdcpLevelsChanged(Cycle cycle, PhysicalDisplayId displayId,
int32_t connectedLevel, int32_t maxLevel) {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
- }
- thread->onHdcpLevelsChanged(displayId, connectedLevel, maxLevel);
+ eventThreadFor(cycle).onHdcpLevelsChanged(displayId, connectedLevel, maxLevel);
}
-void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
+void Scheduler::onPrimaryDisplayModeChanged(Cycle cycle, const FrameRateMode& mode) {
{
std::lock_guard<std::mutex> lock(mPolicyLock);
// Cache the last reported modes for primary display.
- mPolicy.cachedModeChangedParams = {handle, mode};
+ mPolicy.cachedModeChangedParams = {cycle, mode};
// Invalidate content based refresh rate selection so it could be calculated
// again for the new refresh rate.
mPolicy.contentRequirements.clear();
}
- onNonPrimaryDisplayModeChanged(handle, mode);
+ onNonPrimaryDisplayModeChanged(cycle, mode);
}
void Scheduler::dispatchCachedReportedMode() {
@@ -502,39 +443,25 @@
}
mPolicy.cachedModeChangedParams->mode = *mPolicy.modeOpt;
- onNonPrimaryDisplayModeChanged(mPolicy.cachedModeChangedParams->handle,
+ onNonPrimaryDisplayModeChanged(mPolicy.cachedModeChangedParams->cycle,
mPolicy.cachedModeChangedParams->mode);
}
-void Scheduler::onNonPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
+void Scheduler::onNonPrimaryDisplayModeChanged(Cycle cycle, const FrameRateMode& mode) {
+ if (hasEventThreads()) {
+ eventThreadFor(cycle).onModeChanged(mode);
}
- thread->onModeChanged(mode);
}
-void Scheduler::dump(ConnectionHandle handle, std::string& result) const {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections.at(handle).thread.get();
- }
- thread->dump(result);
+void Scheduler::dump(Cycle cycle, std::string& result) const {
+ eventThreadFor(cycle).dump(result);
}
-void Scheduler::setDuration(ConnectionHandle handle, std::chrono::nanoseconds workDuration,
+void Scheduler::setDuration(Cycle cycle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration) {
- android::EventThread* thread;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- RETURN_IF_INVALID_HANDLE(handle);
- thread = mConnections[handle].thread.get();
+ if (hasEventThreads()) {
+ eventThreadFor(cycle).setDuration(workDuration, readyDuration);
}
- thread->setDuration(workDuration, readyDuration);
}
void Scheduler::updatePhaseConfiguration(Fps refreshRate) {
@@ -557,10 +484,10 @@
}
void Scheduler::setVsyncConfig(const VsyncConfig& config, Period vsyncPeriod) {
- setDuration(mAppConnectionHandle,
+ setDuration(Cycle::Render,
/* workDuration */ config.appWorkDuration,
/* readyDuration */ config.sfWorkDuration);
- setDuration(mSfConnectionHandle,
+ setDuration(Cycle::LastComposite,
/* workDuration */ vsyncPeriod,
/* readyDuration */ config.sfWorkDuration);
setDuration(config.sfWorkDuration);
@@ -1027,16 +954,10 @@
void Scheduler::applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule> vsyncSchedule) {
onNewVsyncSchedule(vsyncSchedule->getDispatch());
- std::vector<android::EventThread*> threads;
- {
- std::lock_guard<std::mutex> lock(mConnectionsLock);
- threads.reserve(mConnections.size());
- for (auto& [_, connection] : mConnections) {
- threads.push_back(connection.thread.get());
- }
- }
- for (auto* thread : threads) {
- thread->onNewVsyncSchedule(vsyncSchedule);
+
+ if (hasEventThreads()) {
+ eventThreadFor(Cycle::Render).onNewVsyncSchedule(vsyncSchedule);
+ eventThreadFor(Cycle::LastComposite).onNewVsyncSchedule(vsyncSchedule);
}
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 9f29e9f..71df507 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -56,35 +56,6 @@
#include <FrontEnd/LayerHierarchy.h>
-namespace android::scheduler {
-
-// Opaque handle to scheduler connection.
-struct ConnectionHandle {
- using Id = std::uintptr_t;
- static constexpr Id INVALID_ID = static_cast<Id>(-1);
-
- Id id = INVALID_ID;
-
- explicit operator bool() const { return id != INVALID_ID; }
-};
-
-inline bool operator==(ConnectionHandle lhs, ConnectionHandle rhs) {
- return lhs.id == rhs.id;
-}
-
-} // namespace android::scheduler
-
-namespace std {
-
-template <>
-struct hash<android::scheduler::ConnectionHandle> {
- size_t operator()(android::scheduler::ConnectionHandle handle) const {
- return hash<android::scheduler::ConnectionHandle::Id>()(handle.id);
- }
-};
-
-} // namespace std
-
namespace android {
class FenceTime;
@@ -106,6 +77,11 @@
class VsyncConfiguration;
class VsyncSchedule;
+enum class Cycle {
+ Render, // Surface rendering.
+ LastComposite // Ahead of display compositing by one refresh period.
+};
+
class Scheduler : public IEventThreadCallback, android::impl::MessageQueue {
using Impl = android::impl::MessageQueue;
@@ -154,36 +130,32 @@
return std::move(future);
}
- enum class Cycle {
- Render, // Surface rendering.
- LastComposite // Ahead of display compositing by one refresh period.
- };
-
- ConnectionHandle createEventThread(Cycle, frametimeline::TokenManager*,
- std::chrono::nanoseconds workDuration,
- std::chrono::nanoseconds readyDuration);
+ void createEventThread(Cycle, frametimeline::TokenManager*,
+ std::chrono::nanoseconds workDuration,
+ std::chrono::nanoseconds readyDuration);
sp<IDisplayEventConnection> createDisplayEventConnection(
- ConnectionHandle, EventRegistrationFlags eventRegistration = {},
+ Cycle, EventRegistrationFlags eventRegistration = {},
const sp<IBinder>& layerHandle = nullptr) EXCLUDES(mChoreographerLock);
- sp<EventThreadConnection> getEventConnection(ConnectionHandle);
+ const sp<EventThreadConnection>& getEventConnection(Cycle cycle) const {
+ return cycle == Cycle::Render ? mRenderEventConnection : mLastCompositeEventConnection;
+ }
- void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
- void onHotplugConnectionError(ConnectionHandle, int32_t errorCode);
+ void onHotplugReceived(Cycle, PhysicalDisplayId, bool connected);
+ void onHotplugConnectionError(Cycle, int32_t errorCode);
- void onPrimaryDisplayModeChanged(ConnectionHandle, const FrameRateMode&) EXCLUDES(mPolicyLock);
- void onNonPrimaryDisplayModeChanged(ConnectionHandle, const FrameRateMode&);
+ void onPrimaryDisplayModeChanged(Cycle, const FrameRateMode&) EXCLUDES(mPolicyLock);
+ void onNonPrimaryDisplayModeChanged(Cycle, const FrameRateMode&);
void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext);
- void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId)
- EXCLUDES(mConnectionsLock);
+ void onFrameRateOverridesChanged(Cycle, PhysicalDisplayId);
- void onHdcpLevelsChanged(ConnectionHandle, PhysicalDisplayId, int32_t, int32_t);
+ void onHdcpLevelsChanged(Cycle, PhysicalDisplayId, int32_t, int32_t);
// Modifies work duration in the event thread.
- void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
+ void setDuration(Cycle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration);
VsyncModulator& vsyncModulator() { return *mVsyncModulator; }
@@ -288,7 +260,7 @@
bool isVsyncInPhase(TimePoint expectedVsyncTime, Fps frameRate) const;
void dump(utils::Dumper&) const;
- void dump(ConnectionHandle, std::string&) const;
+ void dump(Cycle, std::string&) const;
void dumpVsync(std::string&) const EXCLUDES(mDisplayLock);
// Returns the preferred refresh rate and frame rate for the pacesetter display.
@@ -369,8 +341,15 @@
void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) override
REQUIRES(kMainThreadContext, mDisplayLock);
- // Create a connection on the given EventThread.
- ConnectionHandle createConnection(std::unique_ptr<EventThread>);
+ // Used to skip event dispatch before EventThread creation during boot.
+ // TODO: b/241285191 - Reorder Scheduler initialization to avoid this.
+ bool hasEventThreads() const {
+ return CC_LIKELY(mRenderEventThread && mLastCompositeEventThread);
+ }
+
+ EventThread& eventThreadFor(Cycle cycle) const {
+ return *(cycle == Cycle::Render ? mRenderEventThread : mLastCompositeEventThread);
+ }
// Update feature state machine to given state when corresponding timer resets or expires.
void kernelIdleTimerCallback(TimerState) EXCLUDES(mDisplayLock);
@@ -460,18 +439,11 @@
void resync() override EXCLUDES(mDisplayLock);
void onExpectedPresentTimePosted(TimePoint expectedPresentTime) override EXCLUDES(mDisplayLock);
- // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
- struct Connection {
- sp<EventThreadConnection> connection;
- std::unique_ptr<EventThread> thread;
- };
+ std::unique_ptr<EventThread> mRenderEventThread;
+ sp<EventThreadConnection> mRenderEventConnection;
- ConnectionHandle::Id mNextConnectionHandleId = 0;
- mutable std::mutex mConnectionsLock;
- std::unordered_map<ConnectionHandle, Connection> mConnections GUARDED_BY(mConnectionsLock);
-
- ConnectionHandle mAppConnectionHandle;
- ConnectionHandle mSfConnectionHandle;
+ std::unique_ptr<EventThread> mLastCompositeEventThread;
+ sp<EventThreadConnection> mLastCompositeEventConnection;
std::atomic<nsecs_t> mLastResyncTime = 0;
@@ -585,7 +557,7 @@
ftl::Optional<FrameRateMode> modeOpt;
struct ModeChangedParams {
- ConnectionHandle handle;
+ Cycle cycle;
FrameRateMode mode;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e44f841..ecb266d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2085,12 +2085,11 @@
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration,
const sp<IBinder>& layerHandle) {
- const auto& handle =
- vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger
- ? mSfConnectionHandle
- : mAppConnectionHandle;
+ const auto cycle = vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger
+ ? scheduler::Cycle::LastComposite
+ : scheduler::Cycle::Render;
- return mScheduler->createDisplayEventConnection(handle, eventRegistration, layerHandle);
+ return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle);
}
void SurfaceFlinger::scheduleCommit(FrameHint hint) {
@@ -2132,7 +2131,7 @@
const int32_t hotplugErrorCode = static_cast<int32_t>(-timestamp);
ALOGD("SurfaceFlinger got hotplugErrorCode=%d for display %" PRIu64, hotplugErrorCode,
hwcDisplayId);
- mScheduler->onHotplugConnectionError(mAppConnectionHandle, hotplugErrorCode);
+ mScheduler->onHotplugConnectionError(scheduler::Cycle::Render, hotplugErrorCode);
return;
}
@@ -2183,7 +2182,7 @@
if (FlagManager::getInstance().hotplug2()) {
ALOGD("SurfaceFlinger got hotplug event=%d", static_cast<int32_t>(event));
// TODO(b/311403559): use enum type instead of int
- mScheduler->onHotplugConnectionError(mAppConnectionHandle, static_cast<int32_t>(event));
+ mScheduler->onHotplugConnectionError(scheduler::Cycle::Render, static_cast<int32_t>(event));
}
}
@@ -3473,7 +3472,7 @@
if (!activeMode) {
ALOGE("Failed to hotplug display %s", to_string(displayId).c_str());
if (FlagManager::getInstance().hotplug2()) {
- mScheduler->onHotplugConnectionError(mAppConnectionHandle,
+ mScheduler->onHotplugConnectionError(scheduler::Cycle::Render,
static_cast<int32_t>(
DisplayHotplugEvent::ERROR_UNKNOWN));
}
@@ -3526,8 +3525,8 @@
}
void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
- mScheduler->onHotplugReceived(mAppConnectionHandle, displayId, connected);
- mScheduler->onHotplugReceived(mSfConnectionHandle, displayId, connected);
+ mScheduler->onHotplugReceived(scheduler::Cycle::Render, displayId, connected);
+ mScheduler->onHotplugReceived(scheduler::Cycle::LastComposite, displayId, connected);
}
void SurfaceFlinger::dispatchDisplayModeChangeEvent(PhysicalDisplayId displayId,
@@ -3537,7 +3536,7 @@
? &scheduler::Scheduler::onPrimaryDisplayModeChanged
: &scheduler::Scheduler::onNonPrimaryDisplayModeChanged;
- ((*mScheduler).*onDisplayModeChanged)(mAppConnectionHandle, mode);
+ ((*mScheduler).*onDisplayModeChanged)(scheduler::Cycle::Render, mode);
}
sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
@@ -4189,7 +4188,7 @@
return getDefaultDisplayDeviceLocked()->getPhysicalId();
}();
- mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
+ mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
}
void SurfaceFlinger::notifyCpuLoadUp() {
@@ -4354,24 +4353,22 @@
mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
static_cast<ISchedulerCallback&>(*this), features,
getFactory(), activeRefreshRate, *mTimeStats);
+
+ // The pacesetter must be registered before EventThread creation below.
mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
if (FlagManager::getInstance().vrr_config()) {
mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps);
}
- mScheduler->startTimers();
const auto configs = mScheduler->getVsyncConfiguration().getCurrentConfigs();
- mAppConnectionHandle =
- mScheduler->createEventThread(Scheduler::Cycle::Render,
- mFrameTimeline->getTokenManager(),
- /* workDuration */ configs.late.appWorkDuration,
- /* readyDuration */ configs.late.sfWorkDuration);
- mSfConnectionHandle =
- mScheduler->createEventThread(Scheduler::Cycle::LastComposite,
- mFrameTimeline->getTokenManager(),
- /* workDuration */ activeRefreshRate.getPeriod(),
- /* readyDuration */ configs.late.sfWorkDuration);
+ mScheduler->createEventThread(scheduler::Cycle::Render, mFrameTimeline->getTokenManager(),
+ /* workDuration */ configs.late.appWorkDuration,
+ /* readyDuration */ configs.late.sfWorkDuration);
+ mScheduler->createEventThread(scheduler::Cycle::LastComposite,
+ mFrameTimeline->getTokenManager(),
+ /* workDuration */ activeRefreshRate.getPeriod(),
+ /* readyDuration */ configs.late.sfWorkDuration);
mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
@@ -4379,6 +4376,9 @@
sp<RegionSamplingThread>::make(*this,
RegionSamplingThread::EnvironmentTimingTunables());
mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline);
+
+ // Timer callbacks may fire, so do this last.
+ mScheduler->startTimers();
}
void SurfaceFlinger::doCommitTransactions() {
@@ -6315,7 +6315,7 @@
}
void SurfaceFlinger::dumpEvents(std::string& result) const {
- mScheduler->dump(mAppConnectionHandle, result);
+ mScheduler->dump(scheduler::Cycle::Render, result);
}
void SurfaceFlinger::dumpVsync(std::string& result) const {
@@ -7087,14 +7087,15 @@
mForceFullDamage = n != 0;
return NO_ERROR;
}
- case 1018: { // Modify Choreographer's duration
+ case 1018: { // Set the render deadline as a duration until VSYNC.
n = data.readInt32();
- mScheduler->setDuration(mAppConnectionHandle, std::chrono::nanoseconds(n), 0ns);
+ mScheduler->setDuration(scheduler::Cycle::Render, std::chrono::nanoseconds(n), 0ns);
return NO_ERROR;
}
- case 1019: { // Modify SurfaceFlinger's duration
+ case 1019: { // Set the deadline of the last composite as a duration until VSYNC.
n = data.readInt32();
- mScheduler->setDuration(mSfConnectionHandle, std::chrono::nanoseconds(n), 0ns);
+ mScheduler->setDuration(scheduler::Cycle::LastComposite,
+ std::chrono::nanoseconds(n), 0ns);
return NO_ERROR;
}
case 1020: { // Unused
@@ -7326,7 +7327,7 @@
auto inUid = static_cast<uid_t>(data.readInt32());
const auto refreshRate = data.readFloat();
mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{inUid, refreshRate});
- mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
+ mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
return NO_ERROR;
}
// Toggle caching feature
@@ -8466,10 +8467,10 @@
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
// be depending in this callback.
if (const auto activeMode = selector.getActiveMode(); displayId == mActiveDisplayId) {
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ mScheduler->onPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode);
toggleKernelIdleTimer();
} else {
- mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ mScheduler->onNonPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode);
}
auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode);
@@ -8657,7 +8658,7 @@
}();
mScheduler->setGameModeFrameRateForUid(FrameRateOverride{static_cast<uid_t>(uid), frameRate});
- mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
+ mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
return NO_ERROR;
}
@@ -8919,7 +8920,8 @@
Mutex::Autolock lock(mStateLock);
display->setSecure(connectedLevel >= 2 /* HDCP_V1 */);
}
- mScheduler->onHdcpLevelsChanged(mAppConnectionHandle, displayId, connectedLevel, maxLevel);
+ mScheduler->onHdcpLevelsChanged(scheduler::Cycle::Render, displayId, connectedLevel,
+ maxLevel);
}));
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index be05797..b01d1aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1356,12 +1356,7 @@
const std::string mHwcServiceName;
- /*
- * Scheduler
- */
std::unique_ptr<scheduler::Scheduler> mScheduler;
- scheduler::ConnectionHandle mAppConnectionHandle;
- scheduler::ConnectionHandle mSfConnectionHandle;
scheduler::PresentLatencyTracker mPresentLatencyTracker GUARDED_BY(kMainThreadContext);
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index b059525..10e2220 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -99,7 +99,6 @@
TestableScheduler* mScheduler = new TestableScheduler{mSelector, mFlinger, mSchedulerCallback};
surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
- ConnectionHandle mConnectionHandle;
MockEventThread* mEventThread;
sp<MockEventThreadConnection> mEventThreadConnection;
};
@@ -116,54 +115,13 @@
EXPECT_CALL(*mEventThread, createEventConnection(_, _))
.WillRepeatedly(Return(mEventThreadConnection));
- mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
- EXPECT_TRUE(mConnectionHandle);
+ mScheduler->setEventThread(Cycle::Render, std::move(eventThread));
mFlinger.resetScheduler(mScheduler);
}
} // namespace
-TEST_F(SchedulerTest, invalidConnectionHandle) {
- ConnectionHandle handle;
-
- const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
-
- EXPECT_FALSE(connection);
- EXPECT_FALSE(mScheduler->getEventConnection(handle));
-
- // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
- EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
- mScheduler->onHotplugReceived(handle, kDisplayId1, false);
-
- std::string output;
- EXPECT_CALL(*mEventThread, dump(_)).Times(0);
- mScheduler->dump(handle, output);
- EXPECT_TRUE(output.empty());
-
- EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
- mScheduler->setDuration(handle, 10ns, 20ns);
-}
-
-TEST_F(SchedulerTest, validConnectionHandle) {
- const sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle);
-
- ASSERT_EQ(mEventThreadConnection, connection);
- EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
-
- EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
- mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
-
- std::string output("dump");
- EXPECT_CALL(*mEventThread, dump(output)).Times(1);
- mScheduler->dump(mConnectionHandle, output);
- EXPECT_FALSE(output.empty());
-
- EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
- mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
-}
-
TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
// Hardware VSYNC should not change if the display is already registered.
EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
@@ -235,22 +193,6 @@
EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
}
-TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
- const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
- .setId(DisplayModeId(111))
- .setPhysicalDisplayId(kDisplayId1)
- .setVsyncPeriod(111111)
- .build();
-
- // If the handle is incorrect, the function should return before
- // onModeChange is called.
- ConnectionHandle invalidHandle = {.id = 123};
- EXPECT_NO_FATAL_FAILURE(
- mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
- {90_Hz, ftl::as_non_null(mode)}));
- EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
-}
-
TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
@@ -753,7 +695,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
const sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
@@ -782,9 +724,9 @@
.WillOnce(Return(mockConnection2));
const sp<IDisplayEventConnection> connection1 =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
const sp<IDisplayEventConnection> connection2 =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
@@ -802,9 +744,9 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
const sp<IDisplayEventConnection> connection1 =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer1->getHandle());
const sp<IDisplayEventConnection> connection2 =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer2->getHandle());
EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
@@ -831,7 +773,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
EXPECT_EQ(1u,
@@ -861,7 +803,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
const sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
layer.clear();
mFlinger.mutableLayersPendingRemoval().clear();
@@ -875,7 +817,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
LayerHierarchy hierarchy(&layerState);
@@ -935,7 +877,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
LayerHierarchy parentHierarchy(&parentState);
@@ -962,7 +904,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
LayerHierarchy parentHierarchy(&parentState);
@@ -997,7 +939,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
LayerHierarchy parentHierarchy(&parentState);
@@ -1031,7 +973,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
LayerHierarchy parentHierarchy(&parentState);
@@ -1057,7 +999,7 @@
EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
sp<IDisplayEventConnection> connection =
- mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
+ mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
LayerHierarchy parentHierarchy(&parentState);
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 25a85df..1472ebf 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -71,9 +71,14 @@
Scheduler::onFrameSignal(compositor, vsyncId, TimePoint());
}
- // Used to inject mock event thread.
- ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) {
- return Scheduler::createConnection(std::move(eventThread));
+ void setEventThread(Cycle cycle, std::unique_ptr<EventThread> eventThreadPtr) {
+ if (cycle == Cycle::Render) {
+ mRenderEventThread = std::move(eventThreadPtr);
+ mRenderEventConnection = mRenderEventThread->createEventConnection();
+ } else {
+ mLastCompositeEventThread = std::move(eventThreadPtr);
+ mLastCompositeEventConnection = mLastCompositeEventThread->createEventConnection();
+ }
}
auto refreshRateSelector() { return pacesetterSelectorPtr(); }
@@ -124,7 +129,6 @@
using Scheduler::resyncAllToHardwareVsync;
- auto& mutableAppConnectionHandle() { return mAppConnectionHandle; }
auto& mutableLayerHistory() { return mLayerHistory; }
auto& mutableAttachedChoreographers() { return mAttachedChoreographers; }
@@ -180,10 +184,6 @@
mPolicy.cachedModeChangedParams.reset();
}
- void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
- Scheduler::onNonPrimaryDisplayModeChanged(handle, mode);
- }
-
void setInitialHwVsyncEnabled(PhysicalDisplayId id, bool enabled) {
auto schedule = getVsyncSchedule(id);
std::lock_guard<std::mutex> lock(schedule->mHwVsyncLock);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 46a079c..bce7729 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -258,11 +258,9 @@
mScheduler->initVsync(*mTokenManager, 0ms);
- mScheduler->mutableAppConnectionHandle() =
- mScheduler->createConnection(std::move(appEventThread));
+ mScheduler->setEventThread(scheduler::Cycle::Render, std::move(appEventThread));
+ mScheduler->setEventThread(scheduler::Cycle::LastComposite, std::move(sfEventThread));
- mFlinger->mAppConnectionHandle = mScheduler->mutableAppConnectionHandle();
- mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));
resetScheduler(mScheduler);
}