SF: default display is active display

For devices with multiple internal displays, choose the internal
display the is powered on (if any) to be the default display that
would be used mainly for vsync tracking.

Bug: 187539899
Test: SF unit tests
Change-Id: Icc305cdeec1c8a04729f00ff795dfbb806d8f72c
Merged-In: Icc305cdeec1c8a04729f00ff795dfbb806d8f72c
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 194e698..18cb0c2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -632,9 +632,7 @@
     mVirtualDisplayIdGenerators.gpu.releaseId(*id);
 }
 
-std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIds() const {
-    Mutex::Autolock lock(mStateLock);
-
+std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIdsLocked() const {
     const auto internalDisplayId = getInternalDisplayIdLocked();
     if (!internalDisplayId) {
         return {};
@@ -837,7 +835,7 @@
         }
     }
 
-    getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
+    onActiveDisplaySizeChanged(display);
 
     // Inform native graphics APIs whether the present timestamp is supported:
 
@@ -2335,7 +2333,7 @@
     mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence);
     mTransactionCallbackInvoker.sendCallbacks();
 
-    if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON &&
+    if (display && display->isInternal() && display->getPowerMode() == hal::PowerMode::ON &&
         mPreviousPresentFences[0].fenceTime->isValid()) {
         mScheduler->addPresentFence(mPreviousPresentFences[0].fenceTime);
     }
@@ -2785,11 +2783,6 @@
     if (!state.isVirtual()) {
         dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
     }
-
-    if (display->isPrimary()) {
-        mScheduler->onPrimaryDisplayAreaChanged(display->getWidth() * display->getHeight());
-        getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
-    }
 }
 
 void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
@@ -2854,16 +2847,8 @@
 
             // TODO(b/175678251) Call a listener instead.
             if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
-                mRefreshRateConfigs->updateDisplayModes(currentState.physical->supportedModes,
-                                                        currentState.physical->activeMode->getId());
-                mVsyncConfiguration->reset();
-                const Fps refreshRate = currentState.physical->activeMode->getFps();
-                updatePhaseConfiguration(refreshRate);
-                mRefreshRateStats->setRefreshRate(refreshRate);
-
-                if (mRefreshRateOverlay) {
-                    mRefreshRateOverlay->reset();
-                }
+                updateInternalDisplayVsyncLocked(currentState.physical->supportedModes,
+                                                 currentState.physical->activeMode->getId());
             }
         }
         return;
@@ -2889,8 +2874,8 @@
             currentState.height != drawingState.height) {
             display->setDisplaySize(currentState.width, currentState.height);
 
-            if (display->isPrimary()) {
-                mScheduler->onPrimaryDisplayAreaChanged(currentState.width * currentState.height);
+            if (isDisplayActiveLocked(display)) {
+                onActiveDisplaySizeChanged(display);
             }
 
             if (mRefreshRateOverlay) {
@@ -2899,6 +2884,17 @@
         }
     }
 }
+void SurfaceFlinger::updateInternalDisplayVsyncLocked(const DisplayModes& modes,
+                                                      DisplayModeId currentModeId) {
+    mRefreshRateConfigs->updateDisplayModes(modes, currentModeId);
+    mVsyncConfiguration->reset();
+    const Fps refreshRate = mRefreshRateConfigs->getCurrentRefreshRate().getFps();
+    updatePhaseConfiguration(refreshRate);
+    mRefreshRateStats->setRefreshRate(refreshRate);
+    if (mRefreshRateOverlay) {
+        mRefreshRateOverlay->reset();
+    }
+}
 
 void SurfaceFlinger::processDisplayChangesLocked() {
     // here we take advantage of Vector's copy-on-write semantics to
@@ -4555,6 +4551,11 @@
     }
     const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
     if (currentMode == hal::PowerMode::OFF) {
+        const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayToken);
+        if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) {
+            mActiveDisplayToken = display->getDisplayToken();
+            onActiveDisplayChangedLocked(getDisplayDeviceLocked(mActiveDisplayToken));
+        }
         // Keep uclamp in a separate syscall and set it before changing to RT due to b/190237315.
         // We can merge the syscall later.
         if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
@@ -4564,7 +4565,7 @@
             ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
         }
         getHwComposer().setPowerMode(displayId, mode);
-        if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
+        if (display->isInternal() && mode != hal::PowerMode::DOZE_SUSPEND) {
             getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
             mScheduler->onScreenAcquired(mAppConnectionHandle);
             mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4581,7 +4582,7 @@
         if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
             ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
         }
-        if (display->isPrimary() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
+        if (display->isInternal() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
             mScheduler->disableHardwareVsync(true);
             mScheduler->onScreenReleased(mAppConnectionHandle);
         }
@@ -4595,13 +4596,13 @@
     } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
         // Update display while dozing
         getHwComposer().setPowerMode(displayId, mode);
-        if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
+        if (display->isInternal() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
             mScheduler->onScreenAcquired(mAppConnectionHandle);
             mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
         }
     } else if (mode == hal::PowerMode::DOZE_SUSPEND) {
         // Leave display going to doze
-        if (display->isPrimary()) {
+        if (display->isInternal()) {
             mScheduler->disableHardwareVsync(true);
             mScheduler->onScreenReleased(mAppConnectionHandle);
         }
@@ -4611,7 +4612,7 @@
         getHwComposer().setPowerMode(displayId, mode);
     }
 
-    if (display->isPrimary()) {
+    if (display->isInternal()) {
         mTimeStats->setPowerMode(mode);
         mRefreshRateStats->setPowerMode(mode);
         mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
@@ -5686,7 +5687,7 @@
                         return std::make_optional<PhysicalDisplayId>(inputDisplayId);
                     }
 
-                    return getInternalDisplayId();
+                    return getDefaultDisplayDevice()->getPhysicalId();
                 }();
 
                 if (!displayId) {
@@ -6459,8 +6460,10 @@
         const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
     Mutex::Autolock lock(mStateLock);
 
-    LOG_ALWAYS_FATAL_IF(!display->isPrimary() && overridePolicy,
-                        "Can only set override policy on the primary display");
+    const bool isDefaultDisplay = display == getDefaultDisplayDeviceLocked();
+
+    LOG_ALWAYS_FATAL_IF(!isDefaultDisplay && overridePolicy,
+                        "Can only set override policy on the default display");
     LOG_ALWAYS_FATAL_IF(!policy && !overridePolicy, "Can only clear the override policy");
 
     if (mDebugDisplayModeSetByBackdoor) {
@@ -6468,11 +6471,11 @@
         return NO_ERROR;
     }
 
-    if (!display->isPrimary()) {
-        // TODO(b/144711714): For non-primary displays we should be able to set an active mode
+    if (!isDefaultDisplay) {
+        // TODO(b/144711714): For non-default displays we should be able to set an active mode
         // as well. For now, just call directly to initiateModeChange but ideally
         // it should go thru setDesiredActiveMode, similar to primary display.
-        ALOGV("%s for non-primary display", __func__);
+        ALOGV("%s for non-default display", __func__);
         const auto displayId = display->getPhysicalId();
 
         hal::VsyncPeriodChangeConstraints constraints;
@@ -6590,7 +6593,7 @@
         return NAME_NOT_FOUND;
     }
 
-    if (display->isPrimary()) {
+    if (display == getDefaultDisplayDeviceLocked()) {
         scheduler::RefreshRateConfigs::Policy policy =
                 mRefreshRateConfigs->getDisplayManagerPolicy();
         *outDefaultMode = policy.defaultMode.value();
@@ -6984,6 +6987,27 @@
     mRegionSamplingThread->onCompositionComplete(mEventQueue->nextExpectedInvalidate());
 }
 
+void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay) {
+    mScheduler->onActiveDisplayAreaChanged(activeDisplay->getWidth() * activeDisplay->getHeight());
+    getRenderEngine().onActiveDisplaySizeChanged(activeDisplay->getSize());
+}
+
+void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
+    ATRACE_CALL();
+
+    if (!activeDisplay) {
+        ALOGE("%s: activeDisplay is null", __func__);
+        return;
+    }
+    updateInternalDisplayVsyncLocked(activeDisplay->getSupportedModes(),
+                                     activeDisplay->getActiveMode()->getId());
+    onActiveDisplaySizeChanged(activeDisplay);
+    if (mRefreshRateOverlay) {
+        mRefreshRateOverlay->setViewport(activeDisplay->getSize());
+        mRefreshRateOverlay->changeRefreshRate(activeDisplay->getActiveMode()->getFps());
+    }
+}
+
 } // namespace android
 
 #if defined(__gl_h_)