SF: Move hotplug dispatch to Scheduler
Hide the Render/LastComposite details in Scheduler.
Also, dispatch hotplug errors to both EventThreads for consistency.
Bug: 241285191
Bug: 241285945
Test: Hotplug still works.
Change-Id: I425d997274c0272a2bfa352c138750d65d008da5
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e6c58a3..3f91682 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -154,9 +154,13 @@
if (isNew) {
onHardwareVsyncRequest(displayId, false);
}
+
+ dispatchHotplug(displayId, Hotplug::Connected);
}
void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
+ dispatchHotplug(displayId, Hotplug::Disconnected);
+
demotePacesetterDisplay();
std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
@@ -375,15 +379,18 @@
return connection;
}
-void Scheduler::onHotplugReceived(Cycle cycle, PhysicalDisplayId displayId, bool connected) {
+void Scheduler::dispatchHotplug(PhysicalDisplayId displayId, Hotplug hotplug) {
if (hasEventThreads()) {
- eventThreadFor(cycle).onHotplugReceived(displayId, connected);
+ const bool connected = hotplug == Hotplug::Connected;
+ eventThreadFor(Cycle::Render).onHotplugReceived(displayId, connected);
+ eventThreadFor(Cycle::LastComposite).onHotplugReceived(displayId, connected);
}
}
-void Scheduler::onHotplugConnectionError(Cycle cycle, int32_t errorCode) {
+void Scheduler::dispatchHotplugError(int32_t errorCode) {
if (hasEventThreads()) {
- eventThreadFor(cycle).onHotplugConnectionError(errorCode);
+ eventThreadFor(Cycle::Render).onHotplugConnectionError(errorCode);
+ eventThreadFor(Cycle::LastComposite).onHotplugConnectionError(errorCode);
}
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 71df507..2cc6b34 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -142,8 +142,10 @@
return cycle == Cycle::Render ? mRenderEventConnection : mLastCompositeEventConnection;
}
- void onHotplugReceived(Cycle, PhysicalDisplayId, bool connected);
- void onHotplugConnectionError(Cycle, int32_t errorCode);
+ enum class Hotplug { Connected, Disconnected };
+ void dispatchHotplug(PhysicalDisplayId, Hotplug);
+
+ void dispatchHotplugError(int32_t errorCode);
void onPrimaryDisplayModeChanged(Cycle, const FrameRateMode&) EXCLUDES(mPolicyLock);
void onNonPrimaryDisplayModeChanged(Cycle, const FrameRateMode&);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ecb266d..582a999 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -886,7 +886,6 @@
// the DisplayDevice, hence the above commit of the primary display. Remove that special case by
// initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
initScheduler(display);
- dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
mLayerTracing.setTakeLayersSnapshotProtoFunction([&](uint32_t traceFlags) {
auto snapshot = perfetto::protos::LayersSnapshotProto{};
@@ -1756,7 +1755,7 @@
}
display->overrideHdrTypes(hdrTypes);
- dispatchDisplayHotplugEvent(display->getPhysicalId(), true /* connected */);
+ mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
return NO_ERROR;
}
@@ -2128,10 +2127,9 @@
vsyncPeriod.has_value()) {
// use ~0 instead of -1 as AidlComposerHal.cpp passes the param as unsigned int32
if (mIsHotplugErrViaNegVsync && vsyncPeriod.value() == ~0) {
- const int32_t hotplugErrorCode = static_cast<int32_t>(-timestamp);
- ALOGD("SurfaceFlinger got hotplugErrorCode=%d for display %" PRIu64, hotplugErrorCode,
- hwcDisplayId);
- mScheduler->onHotplugConnectionError(scheduler::Cycle::Render, hotplugErrorCode);
+ const auto errorCode = static_cast<int32_t>(-timestamp);
+ ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId);
+ mScheduler->dispatchHotplugError(errorCode);
return;
}
@@ -2140,8 +2138,7 @@
// one byte is good enough to encode android.hardware.drm.HdcpLevel
const int32_t maxLevel = (value >> 8) & 0xFF;
const int32_t connectedLevel = value & 0xFF;
- ALOGD("SurfaceFlinger got HDCP level changed: connected=%d, max=%d for "
- "display=%" PRIu64,
+ ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for display %" PRIu64, __func__,
connectedLevel, maxLevel, hwcDisplayId);
updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
return;
@@ -2180,9 +2177,10 @@
}
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(scheduler::Cycle::Render, static_cast<int32_t>(event));
+ const auto errorCode = static_cast<int32_t>(event);
+ ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId);
+ mScheduler->dispatchHotplugError(errorCode);
}
}
@@ -3472,9 +3470,8 @@
if (!activeMode) {
ALOGE("Failed to hotplug display %s", to_string(displayId).c_str());
if (FlagManager::getInstance().hotplug2()) {
- mScheduler->onHotplugConnectionError(scheduler::Cycle::Render,
- static_cast<int32_t>(
- DisplayHotplugEvent::ERROR_UNKNOWN));
+ mScheduler->dispatchHotplugError(
+ static_cast<int32_t>(DisplayHotplugEvent::ERROR_UNKNOWN));
}
getHwComposer().disconnectDisplay(displayId);
return nullptr;
@@ -3524,11 +3521,6 @@
return "Connecting";
}
-void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
- mScheduler->onHotplugReceived(scheduler::Cycle::Render, displayId, connected);
- mScheduler->onHotplugReceived(scheduler::Cycle::LastComposite, displayId, connected);
-}
-
void SurfaceFlinger::dispatchDisplayModeChangeEvent(PhysicalDisplayId displayId,
const scheduler::FrameRateMode& mode) {
// TODO(b/255635821): Merge code paths and move to Scheduler.
@@ -3717,16 +3709,11 @@
displaySurface, producer);
if (mScheduler && !display->isVirtual()) {
- const auto displayId = display->getPhysicalId();
- {
- // TODO(b/241285876): Annotate `processDisplayAdded` instead.
- ftl::FakeGuard guard(kMainThreadContext);
+ // TODO(b/241285876): Annotate `processDisplayAdded` instead.
+ ftl::FakeGuard guard(kMainThreadContext);
- // For hotplug reconnect, renew the registration since display modes have been reloaded.
- mScheduler->registerDisplay(displayId, display->holdRefreshRateSelector());
- }
-
- dispatchDisplayHotplugEvent(displayId, true);
+ // For hotplug reconnect, renew the registration since display modes have been reloaded.
+ mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
}
if (display->isVirtual()) {
@@ -3765,7 +3752,6 @@
if (display->isVirtual()) {
releaseVirtualDisplay(display->getVirtualId());
} else {
- dispatchDisplayHotplugEvent(display->getPhysicalId(), false);
mScheduler->unregisterDisplay(display->getPhysicalId());
}
}
@@ -4370,6 +4356,9 @@
/* workDuration */ activeRefreshRate.getPeriod(),
/* readyDuration */ configs.late.sfWorkDuration);
+ // Dispatch after EventThread creation, since registerDisplay above skipped dispatch.
+ mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);
+
mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
mRegionSamplingThread =
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b01d1aa..7da352f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1050,7 +1050,6 @@
const DisplayDeviceState& drawingState)
REQUIRES(mStateLock, kMainThreadContext);
- void dispatchDisplayHotplugEvent(PhysicalDisplayId, bool connected);
void dispatchDisplayModeChangeEvent(PhysicalDisplayId, const scheduler::FrameRateMode&)
REQUIRES(mStateLock);