SF: Move desired active mode management to DisplayDevice
SF would set the desired active mode on the specific DisplayDevice the
mode was requested and use it to swicth the active display mode.
Change-Id: Ib4f01ec63b2087ab2a81490051d1e029afc71854
Test: SF unit tests
Test: refresh rate switching is working on device with
more than one display
Bug: 187539899
Change-Id: Ie0e5ffe364f81775c2101ffd0cf2c596051947fa
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 2321e2d..2bdcaf6 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -118,12 +118,12 @@
return event;
}
-DisplayEventReceiver::Event makeModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+DisplayEventReceiver::Event makeModeChanged(DisplayModePtr mode) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, displayId, systemTime()};
- event.modeChange.modeId = modeId.value();
- event.modeChange.vsyncPeriod = vsyncPeriod;
+ event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, mode->getPhysicalDisplayId(),
+ systemTime()};
+ event.modeChange.modeId = mode->getId().value();
+ event.modeChange.vsyncPeriod = mode->getVsyncPeriod();
return event;
}
@@ -375,11 +375,10 @@
mCondition.notify_all();
}
-void EventThread::onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+void EventThread::onModeChanged(DisplayModePtr mode) {
std::lock_guard<std::mutex> lock(mMutex);
- mPendingEvents.push_back(makeModeChanged(displayId, modeId, vsyncPeriod));
+ mPendingEvents.push_back(makeModeChanged(mode));
mCondition.notify_all();
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 1e6793f..9265a25 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -124,8 +124,7 @@
virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;
// called when SF changes the active mode and apps needs to be notified about the change
- virtual void onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) = 0;
+ virtual void onModeChanged(DisplayModePtr) = 0;
// called when SF updates the Frame Rate Override list
virtual void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
@@ -174,8 +173,7 @@
void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;
- void onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) override;
+ void onModeChanged(DisplayModePtr) override;
void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
std::vector<FrameRateOverride> overrides) override;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 5fc19da..4a9a1fd 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -71,6 +71,7 @@
int32_t getModeGroup() const { return mode->getGroup(); }
std::string getName() const { return to_string(getFps()); }
Fps getFps() const { return mode->getFps(); }
+ DisplayModePtr getMode() const { return mode; }
// Checks whether the fps of this RefreshRate struct is within a given min and max refresh
// rate passed in. Margin of error is applied to the boundaries for approximation.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 861f3ac..f808981 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -371,23 +371,22 @@
thread->onFrameRateOverridesChanged(displayId, std::move(overrides));
}
-void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
- DisplayModeId modeId, nsecs_t vsyncPeriod) {
+void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
{
std::lock_guard<std::mutex> lock(mFeatureStateLock);
// Cache the last reported modes for primary display.
- mFeatures.cachedModeChangedParams = {handle, displayId, modeId, vsyncPeriod};
+ mFeatures.cachedModeChangedParams = {handle, mode};
// Invalidate content based refresh rate selection so it could be calculated
// again for the new refresh rate.
mFeatures.contentRequirements.clear();
}
- onNonPrimaryDisplayModeChanged(handle, displayId, modeId, vsyncPeriod);
+ onNonPrimaryDisplayModeChanged(handle, mode);
}
void Scheduler::dispatchCachedReportedMode() {
// Check optional fields first.
- if (!mFeatures.modeId.has_value()) {
+ if (!mFeatures.mode) {
ALOGW("No mode ID found, not dispatching cached mode.");
return;
}
@@ -396,35 +395,24 @@
return;
}
- const auto modeId = *mFeatures.modeId;
- const auto vsyncPeriod = [&] {
- std::scoped_lock lock(mRefreshRateConfigsLock);
- return mRefreshRateConfigs->getRefreshRateFromModeId(modeId).getVsyncPeriod();
- }();
-
// If there is no change from cached mode, there is no need to dispatch an event
- if (modeId == mFeatures.cachedModeChangedParams->modeId &&
- vsyncPeriod == mFeatures.cachedModeChangedParams->vsyncPeriod) {
+ if (mFeatures.mode == mFeatures.cachedModeChangedParams->mode) {
return;
}
- mFeatures.cachedModeChangedParams->modeId = modeId;
- mFeatures.cachedModeChangedParams->vsyncPeriod = vsyncPeriod;
+ mFeatures.cachedModeChangedParams->mode = mFeatures.mode;
onNonPrimaryDisplayModeChanged(mFeatures.cachedModeChangedParams->handle,
- mFeatures.cachedModeChangedParams->displayId,
- mFeatures.cachedModeChangedParams->modeId,
- mFeatures.cachedModeChangedParams->vsyncPeriod);
+ mFeatures.cachedModeChangedParams->mode);
}
-void Scheduler::onNonPrimaryDisplayModeChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
- DisplayModeId modeId, nsecs_t vsyncPeriod) {
+void Scheduler::onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
android::EventThread* thread;
{
std::lock_guard<std::mutex> lock(mConnectionsLock);
RETURN_IF_INVALID_HANDLE(handle);
thread = mConnections[handle].thread.get();
}
- thread->onModeChanged(displayId, modeId, vsyncPeriod);
+ thread->onModeChanged(mode);
}
size_t Scheduler::getEventThreadConnectionCount(ConnectionHandle handle) {
@@ -642,19 +630,17 @@
scheduler::LayerHistory::Summary summary =
mLayerHistory->summarize(*refreshRateConfigs, systemTime());
scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
- DisplayModeId newModeId;
+ DisplayModePtr newMode;
bool frameRateChanged;
bool frameRateOverridesChanged;
{
std::lock_guard<std::mutex> lock(mFeatureStateLock);
mFeatures.contentRequirements = summary;
- newModeId = calculateRefreshRateModeId(&consideredSignals);
- auto newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newModeId);
- frameRateOverridesChanged =
- updateFrameRateOverrides(consideredSignals, newRefreshRate.getFps());
+ newMode = calculateRefreshRateModeId(&consideredSignals);
+ frameRateOverridesChanged = updateFrameRateOverrides(consideredSignals, newMode->getFps());
- if (mFeatures.modeId == newModeId) {
+ if (mFeatures.mode == newMode) {
// We don't need to change the display mode, but we might need to send an event
// about a mode change, since it was suppressed due to a previous idleConsidered
if (!consideredSignals.idle) {
@@ -662,12 +648,12 @@
}
frameRateChanged = false;
} else {
- mFeatures.modeId = newModeId;
+ mFeatures.mode = newMode;
frameRateChanged = true;
}
}
if (frameRateChanged) {
- auto newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newModeId);
+ auto newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newMode->getId());
mSchedulerCallback.changeRefreshRate(newRefreshRate,
consideredSignals.idle ? ModeEvent::None
: ModeEvent::Changed);
@@ -820,7 +806,7 @@
template <class T>
bool Scheduler::handleTimerStateChanged(T* currentState, T newState) {
- DisplayModeId newModeId;
+ DisplayModePtr newMode;
bool refreshRateChanged = false;
bool frameRateOverridesChanged;
scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
@@ -831,23 +817,22 @@
return false;
}
*currentState = newState;
- newModeId = calculateRefreshRateModeId(&consideredSignals);
- const RefreshRate& newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newModeId);
- frameRateOverridesChanged =
- updateFrameRateOverrides(consideredSignals, newRefreshRate.getFps());
- if (mFeatures.modeId == newModeId) {
+ newMode = calculateRefreshRateModeId(&consideredSignals);
+ frameRateOverridesChanged = updateFrameRateOverrides(consideredSignals, newMode->getFps());
+ if (mFeatures.mode == newMode) {
// We don't need to change the display mode, but we might need to send an event
// about a mode change, since it was suppressed due to a previous idleConsidered
if (!consideredSignals.idle) {
dispatchCachedReportedMode();
}
} else {
- mFeatures.modeId = newModeId;
+ mFeatures.mode = newMode;
refreshRateChanged = true;
}
}
if (refreshRateChanged) {
- const RefreshRate& newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newModeId);
+ const RefreshRate& newRefreshRate =
+ refreshRateConfigs->getRefreshRateFromModeId(newMode->getId());
mSchedulerCallback.changeRefreshRate(newRefreshRate,
consideredSignals.idle ? ModeEvent::None
@@ -859,7 +844,7 @@
return consideredSignals.touch;
}
-DisplayModeId Scheduler::calculateRefreshRateModeId(
+DisplayModePtr Scheduler::calculateRefreshRateModeId(
scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals) {
ATRACE_CALL();
if (consideredSignals) *consideredSignals = {};
@@ -870,7 +855,7 @@
if (mDisplayPowerTimer &&
(!mFeatures.isDisplayPowerStateNormal ||
mFeatures.displayPowerTimer == TimerState::Reset)) {
- return refreshRateConfigs->getMaxRefreshRateByPolicy().getModeId();
+ return refreshRateConfigs->getMaxRefreshRateByPolicy().getMode();
}
const bool touchActive = mTouchTimer && mFeatures.touch == TouchState::Active;
@@ -879,16 +864,16 @@
return refreshRateConfigs
->getBestRefreshRate(mFeatures.contentRequirements,
{.touch = touchActive, .idle = idle}, consideredSignals)
- .getModeId();
+ .getMode();
}
-std::optional<DisplayModeId> Scheduler::getPreferredModeId() {
+DisplayModePtr Scheduler::getPreferredDisplayMode() {
std::lock_guard<std::mutex> lock(mFeatureStateLock);
// Make sure that the default mode ID is first updated, before returned.
- if (mFeatures.modeId.has_value()) {
- mFeatures.modeId = calculateRefreshRateModeId();
+ if (mFeatures.mode) {
+ mFeatures.mode = calculateRefreshRateModeId();
}
- return mFeatures.modeId;
+ return mFeatures.mode;
}
void Scheduler::onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index dc17f90..4b6905b 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -87,10 +87,8 @@
sp<EventThreadConnection> getEventConnection(ConnectionHandle);
void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
- void onPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId,
- nsecs_t vsyncPeriod) EXCLUDES(mFeatureStateLock);
- void onNonPrimaryDisplayModeChanged(ConnectionHandle, PhysicalDisplayId, DisplayModeId,
- nsecs_t vsyncPeriod);
+ void onPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr) EXCLUDES(mFeatureStateLock);
+ void onNonPrimaryDisplayModeChanged(ConnectionHandle, DisplayModePtr);
void onScreenAcquired(ConnectionHandle);
void onScreenReleased(ConnectionHandle);
@@ -157,7 +155,7 @@
void dumpVsync(std::string&) const;
// Get the appropriate refresh for current conditions.
- std::optional<DisplayModeId> getPreferredModeId();
+ DisplayModePtr getPreferredDisplayMode();
// Notifies the scheduler about a refresh rate timeline change.
void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
@@ -245,7 +243,7 @@
// This function checks whether individual features that are affecting the refresh rate
// selection were initialized, prioritizes them, and calculates the DisplayModeId
// for the suggested refresh rate.
- DisplayModeId calculateRefreshRateModeId(
+ DisplayModePtr calculateRefreshRateModeId(
scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr)
REQUIRES(mFeatureStateLock);
@@ -308,7 +306,7 @@
TouchState touch = TouchState::Inactive;
TimerState displayPowerTimer = TimerState::Expired;
- std::optional<DisplayModeId> modeId;
+ DisplayModePtr mode;
LayerHistory::Summary contentRequirements;
bool isDisplayPowerStateNormal = true;
@@ -316,9 +314,7 @@
// Used to cache the last parameters of onPrimaryDisplayModeChanged
struct ModeChangedParams {
ConnectionHandle handle;
- PhysicalDisplayId displayId;
- DisplayModeId modeId;
- nsecs_t vsyncPeriod;
+ DisplayModePtr mode;
};
std::optional<ModeChangedParams> cachedModeChangedParams;