summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp227
1 files changed, 141 insertions, 86 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1751b16233..ebb202f1b7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -715,6 +715,11 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI
}
mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
+
+ // Power hint session mode, representing which hint(s) to send: early, late, or both)
+ mPowerHintSessionMode =
+ {.late = base::GetBoolProperty("debug.sf.send_late_power_session_hint"s, true),
+ .early = base::GetBoolProperty("debug.sf.send_early_power_session_hint"s, false)};
}
LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
@@ -1535,7 +1540,7 @@ bool SurfaceFlinger::isFpsDeferNeeded(const ActiveModeInfo& info) {
return false;
}
-void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
+void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info, bool force) {
ATRACE_CALL();
if (!info.mode) {
@@ -1548,7 +1553,6 @@ void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
return;
}
-
if (isFpsDeferNeeded(info)) {
return;
}
@@ -1558,7 +1562,7 @@ void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
mDolphinWrapper.dolphinSetVsyncPeriod(mVsyncPeriod);
}
- if (display->setDesiredActiveMode(info)) {
+ if (display->setDesiredActiveMode(info, force)) {
scheduleComposite(FrameHint::kNone);
// Start receiving vsync samples now, so that we can detect a period
@@ -2436,21 +2440,10 @@ nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const {
return 0;
}
-sp<DisplayDevice> SurfaceFlinger::getCurrentVsyncSource() {
- std::lock_guard<std::recursive_mutex> lockVsync(mVsyncLock);
-
- if (mNextVsyncSource) {
- return mNextVsyncSource;
- } else if (mActiveVsyncSource) {
- return mActiveVsyncSource;
- }
-
- return getDefaultDisplayDeviceLocked();
-}
-
nsecs_t SurfaceFlinger::getVsyncPeriodFromHWCcb() {
- std::lock_guard<std::recursive_mutex> lockVsync(mVsyncLock);
+ Mutex::Autolock lock(mStateLock);
+ std::lock_guard<std::recursive_mutex> lockVsync(mVsyncLock);
auto display = getDefaultDisplayDeviceLocked();
if (mNextVsyncSource) {
display = mNextVsyncSource;
@@ -2717,12 +2710,6 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
}
}
- // we set this once at the beginning of commit to ensure consistency throughout the whole frame
- mPowerHintSessionData.sessionEnabled = mPowerAdvisor->usePowerHintSession();
- if (mPowerHintSessionData.sessionEnabled) {
- mPowerHintSessionData.commitStart = systemTime();
- }
-
// calculate the expected present time once and use the cached
// value throughout this frame to make sure all layers are
// seeing this same value.
@@ -2738,10 +2725,6 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
updateFrameScheduler();
syncToDisplayHardware();
- if (mPowerHintSessionData.sessionEnabled) {
- mPowerAdvisor->setTargetWorkDuration(mExpectedPresentTime -
- mPowerHintSessionData.commitStart);
- }
const auto vsyncIn = [&] {
if (!ATRACE_ENABLED()) return 0.f;
return (mExpectedPresentTime - systemTime()) / 1e6f;
@@ -2820,6 +2803,32 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
}
}
+ // Save this once per commit + composite to ensure consistency
+ // TODO (b/240619471): consider removing active display check once AOD is fixed
+ const auto activeDisplay =
+ FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayToken));
+ mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession() && activeDisplay &&
+ activeDisplay->getPowerMode() == hal::PowerMode::ON;
+ if (mPowerHintSessionEnabled) {
+ const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
+ // get stable vsync period from display mode
+ const nsecs_t vsyncPeriod = display->getActiveMode()->getVsyncPeriod();
+ mPowerAdvisor->setCommitStart(frameTime);
+ mPowerAdvisor->setExpectedPresentTime(mExpectedPresentTime);
+ const nsecs_t idealSfWorkDuration =
+ mVsyncModulator->getVsyncConfig().sfWorkDuration.count();
+ // Frame delay is how long we should have minus how long we actually have
+ mPowerAdvisor->setFrameDelay(idealSfWorkDuration - (mExpectedPresentTime - frameTime));
+ mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration);
+ mPowerAdvisor->setTargetWorkDuration(vsyncPeriod);
+
+ // Send early hint here to make sure there's not another frame pending
+ if (mPowerHintSessionMode.early) {
+ // Send a rough prediction for this frame based on last frame's timing info
+ mPowerAdvisor->sendPredictedWorkDuration();
+ }
+ }
+
if (mTracingEnabledChanged) {
mLayerTracingEnabled = mLayerTracing.isEnabled();
mTracingEnabledChanged = false;
@@ -2909,10 +2918,6 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
FTL_FAKE_GUARD(kMainThreadContext) {
ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId);
- if (mPowerHintSessionData.sessionEnabled) {
- mPowerHintSessionData.compositeStart = systemTime();
- }
-
{
std::lock_guard lock(mEarlyWakeUpMutex);
mSendEarlyWakeUp = false;
@@ -2921,9 +2926,12 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
compositionengine::CompositionRefreshArgs refreshArgs;
const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
refreshArgs.outputs.reserve(displays.size());
+ std::vector<DisplayId> displayIds;
for (const auto& [_, display] : displays) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
+ displayIds.push_back(display->getId());
}
+ mPowerAdvisor->setDisplays(displayIds);
mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
if (auto layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layers.push_back(layerFE);
@@ -2977,12 +2985,17 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
}
mCompositionEngine->present(refreshArgs);
- if (mPowerHintSessionData.sessionEnabled) {
- mPowerHintSessionData.presentEnd = systemTime();
- }
-
mTimeStats->recordFrameDuration(frameTime, systemTime());
+ // Send a power hint hint after presentation is finished
+ if (mPowerHintSessionEnabled) {
+ mPowerAdvisor->setSfPresentTiming(mPreviousPresentFences[0].fenceTime->getSignalTime(),
+ systemTime());
+ if (mPowerHintSessionMode.late) {
+ mPowerAdvisor->sendActualWorkDuration();
+ }
+ }
+
if (mScheduler->onPostComposition(presentTime)) {
scheduleComposite(FrameHint::kNone);
}
@@ -3027,11 +3040,8 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
scheduleCommit(FrameHint::kNone);
}
- // calculate total render time for performance hinting if adpf cpu hint is enabled,
- if (mPowerHintSessionData.sessionEnabled) {
- const nsecs_t flingerDuration =
- (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart);
- mPowerAdvisor->sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd);
+ if (mPowerHintSessionEnabled) {
+ mPowerAdvisor->setCompositeEnd(systemTime());
}
}
@@ -3618,7 +3628,7 @@ sp<DisplayDevice> SurfaceFlinger::getVsyncSource() {
// order of priority is Pluggables followed by Primary and Secondary built-ins.
for (const auto& display : mDisplaysList) {
- hal::PowerMode mode = display->getPowerMode();
+ std::optional<hal::PowerMode> mode = display->getPowerMode();
if (display->isVirtual() || (mode == hal::PowerMode::OFF) ||
(mode == hal::PowerMode::DOZE_SUSPEND)) {
continue;
@@ -3639,7 +3649,7 @@ sp<DisplayDevice> SurfaceFlinger::getVsyncSource() {
// in the same order of display priority as above.
if (!mVsyncSourceReliableOnDoze) {
for (const auto& display : mDisplaysList) {
- hal::PowerMode mode = display->getPowerMode();
+ std::optional<hal::PowerMode> mode = display->getPowerMode();
if (display->isVirtual()) {
continue;
}
@@ -3952,7 +3962,8 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
// virtual displays are always considered enabled
- creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
+ creationArgs.initialPowerMode =
+ state.isVirtual() ? std::make_optional(hal::PowerMode::ON) : std::nullopt;
sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
@@ -4244,7 +4255,6 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay) {
mVsyncConfiguration->reset();
const Fps refreshRate = activeDisplay->refreshRateConfigs().getActiveMode()->getFps();
- updatePhaseConfiguration(refreshRate);
mRefreshRateStats->setRefreshRate(refreshRate);
if (mUseAdvanceSfOffset && mComposerExtnIntf) {
const auto& supportedModes = getDefaultDisplayDeviceLocked()->getSupportedModes();
@@ -4265,6 +4275,7 @@ void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& a
mVsyncConfiguration->UpdateSfOffsets(&mAdvancedSfOffsets);
}
}
+ updatePhaseConfiguration(refreshRate);
}
void SurfaceFlinger::setFrameBufferSizeForScaling(sp<DisplayDevice> displayDevice,
@@ -4552,11 +4563,11 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (!layer->needsInputInfo()) return;
- // Do not create WindowInfos for windows on displays that cannot receive input.
- if (const auto opt = displayInputInfos.get(layer->getLayerStack())) {
- const auto& info = opt->get();
- outWindowInfos.push_back(layer->fillInputInfo(info.transform, info.isSecure));
- }
+ const auto opt = displayInputInfos.get(layer->getLayerStack(),
+ [](const auto& info) -> Layer::InputDisplayArgs {
+ return {&info.transform, info.isSecure};
+ });
+ outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
});
sNumWindowInfos = outWindowInfos.size();
@@ -4591,8 +4602,14 @@ void SurfaceFlinger::requestDisplayMode(DisplayModePtr mode, DisplayModeEvent ev
}
ATRACE_CALL();
+ if (display->isInternal() && !isDisplayActiveLocked(display)) {
+ ALOGV("%s(%s): Inactive display", __func__, to_string(display->getId()).c_str());
+ return;
+ }
+
if (!display->refreshRateConfigs().isModeAllowed(mode->getId())) {
- ALOGV("Skipping disallowed mode %d", mode->getId().value());
+ ALOGV("%s(%s): Disallowed mode %d", __func__, to_string(display->getId()).c_str(),
+ mode->getId().value());
return;
}
@@ -5458,7 +5475,7 @@ status_t SurfaceFlinger::setTransactionState(
bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
Vector<ComposerState>& states,
- const Vector<DisplayState>& displays, uint32_t flags,
+ Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& uncacheBuffer,
@@ -5467,7 +5484,8 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin
const std::vector<ListenerCallbacks>& listenerCallbacks,
int originPid, int originUid, uint64_t transactionId) {
uint32_t transactionFlags = 0;
- for (const DisplayState& display : displays) {
+ for (DisplayState& display : displays) {
+ display.sanitize(permissions);
transactionFlags |= setDisplayStateLocked(display);
}
@@ -5540,6 +5558,7 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin
}
void SurfaceFlinger::checkVirtualDisplayHint(const Vector<DisplayState>& displays) {
+ Mutex::Autolock lock(mStateLock);
for (const DisplayState& s : displays) {
const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
if (index < 0)
@@ -6186,8 +6205,8 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
const auto displayId = display->getPhysicalId();
ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
- const hal::PowerMode currentMode = display->getPowerMode();
- if (mode == currentMode) {
+ std::optional<hal::PowerMode> currentMode = display->getPowerMode();
+ if (currentMode.has_value() && mode == *currentMode) {
return;
}
@@ -6213,7 +6232,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
const auto refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
- if (currentMode == hal::PowerMode::OFF) {
+ if (!currentMode || *currentMode == hal::PowerMode::OFF) {
// Turn on the display
if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) {
onActiveDisplayChangedLocked(display);
@@ -6303,7 +6322,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
if (isDummyDisplay) {
- if (isDisplayActiveLocked(display) && currentMode == hal::PowerMode::DOZE_SUSPEND) {
+ if (isDisplayActiveLocked(display) && *currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, refreshRate);
}
@@ -6354,7 +6373,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
if (isDisplayActiveLocked(display)) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
- mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
+ mScheduler->setDisplayPowerMode(mode);
}
setEarlyWakeUpConfig(display, mode);
@@ -6405,7 +6424,7 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
return;
}
const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*physicalDisplayId);
- const hal::PowerMode currentDisplayPowerMode = display->getPowerMode();
+ std::optional<hal::PowerMode>currentDisplayPowerMode = display->getPowerMode();
const hal::PowerMode newDisplayPowerMode = static_cast<hal::PowerMode>(mode);
// Fallback to default power state behavior as HWC does not support power mode override.
if (!display->getPowerModeOverrideConfig() ||
@@ -6479,6 +6498,25 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
const auto flag = args.empty() ? ""s : std::string(String8(args[0]));
+ // Traversal of drawing state must happen on the main thread.
+ // Otherwise, SortedVector may have shared ownership during concurrent
+ // traversals, which can result in use-after-frees.
+ std::string compositionLayers;
+ mScheduler
+ ->schedule([&] {
+ StringAppendF(&compositionLayers, "Composition layers\n");
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ auto* compositionState = layer->getCompositionState();
+ if (!compositionState || !compositionState->isVisible) return;
+
+ android::base::StringAppendF(&compositionLayers, "* Layer %p (%s)\n", layer,
+ layer->getDebugName() ? layer->getDebugName()
+ : "<unknown>");
+ compositionState->dump(compositionLayers);
+ });
+ })
+ .get();
+
bool dumpLayers = true;
{
TimedLock lock(mStateLock, s2ns(1), __func__);
@@ -6499,7 +6537,7 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
dumpMini(result);
dumpLayers = false;
} else {
- dumpAllLocked(args, result);
+ dumpAllLocked(args, compositionLayers, result);
}
}
}
@@ -6583,12 +6621,13 @@ void SurfaceFlinger::dumpDrawCycle(bool prePrepare) {
if (!mFileDump.running && !mFileDump.replaceAfterCommit) {
return;
}
- Vector<String16> args;
+ DumpArgs args;
std::string dumpsys;
+ std::string result;
{
Mutex::Autolock lock(mStateLock);
if (mFileDump.fullDump) {
- dumpAllLocked(args, dumpsys);
+ dumpAllLocked(args, dumpsys, result);
} else {
dumpMini(dumpsys);
}
@@ -6959,7 +6998,8 @@ void SurfaceFlinger::dumpMini(std::string& result) const {
getHwComposer().dump(result);
}
-void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) const {
+void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, const std::string& compositionLayers,
+ std::string& result) const {
const bool colorize = !args.empty() && args[0] == String16("--color");
Colorizer colorizer(colorize);
@@ -7010,18 +7050,7 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co
StringAppendF(&result, "Visible layers (count = %zu)\n", mNumLayers.load());
colorizer.reset(result);
- {
- StringAppendF(&result, "Composition layers\n");
- mDrawingState.traverseInZOrder([&](Layer* layer) {
- auto* compositionState = layer->getCompositionState();
- if (!compositionState || !compositionState->isVisible) return;
-
- android::base::StringAppendF(&result, "* Layer %p (%s)\n", layer,
- layer->getDebugName() ? layer->getDebugName()
- : "<unknown>");
- compositionState->dump(result);
- });
- }
+ result.append(compositionLayers);
colorizer.bold(result);
StringAppendF(&result, "Displays (%zu entries)\n", mDisplays.size());
@@ -8481,8 +8510,13 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
1 /* layerCount */, usage, "screenshot");
const status_t bufferStatus = buffer->initCheck();
- LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
- bufferStatus);
+ if (bufferStatus != OK) {
+ // Animations may end up being really janky, but don't crash here.
+ // Otherwise an irreponsible process may cause an SF crash by allocating
+ // too much.
+ ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
+ return ftl::yield<FenceResult>(base::unexpected(bufferStatus)).share();
+ }
const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
renderengine::impl::ExternalTexture::Usage::
@@ -8505,8 +8539,10 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get();
if (!renderArea) {
ALOGW("Skipping screen capture because of invalid render area.");
- captureResults.result = NO_MEMORY;
- captureListener->onScreenCaptureCompleted(captureResults);
+ if (captureListener) {
+ captureResults.result = NO_MEMORY;
+ captureListener->onScreenCaptureCompleted(captureResults);
+ }
return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share();
}
@@ -8759,9 +8795,7 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
return NO_ERROR;
}
- status_t setPolicyResult = overridePolicy
- ? display->refreshRateConfigs().setOverridePolicy(policy)
- : display->refreshRateConfigs().setDisplayManagerPolicy(*policy);
+ const status_t setPolicyResult = display->setRefreshRatePolicy(policy, overridePolicy);
if (setPolicyResult < 0) {
return BAD_VALUE;
}
@@ -8769,9 +8803,19 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
return NO_ERROR;
}
- scheduler::RefreshRateConfigs::Policy currentPolicy =
- display->refreshRateConfigs().getCurrentPolicy();
+ if (display->isInternal() && !isDisplayActiveLocked(display)) {
+ // The policy will be be applied when the display becomes active.
+ ALOGV("%s(%s): Inactive display", __func__, to_string(display->getId()).c_str());
+ return NO_ERROR;
+ }
+ return applyRefreshRateConfigsPolicy(display);
+}
+
+status_t SurfaceFlinger::applyRefreshRateConfigsPolicy(const sp<DisplayDevice>& display,
+ bool force) {
+ const scheduler::RefreshRateConfigs::Policy currentPolicy =
+ display->refreshRateConfigs().getCurrentPolicy();
ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
@@ -8799,7 +8843,7 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
if (display->refreshRateConfigs().isModeAllowed(preferredDisplayMode->getId())) {
ALOGV("switching to Scheduler preferred display mode %d",
preferredDisplayMode->getId().value());
- setDesiredActiveMode({preferredDisplayMode, DisplayModeEvent::Changed});
+ setDesiredActiveMode({preferredDisplayMode, DisplayModeEvent::Changed}, force);
uint32_t hwcDisplayId;
if (isDisplayExtnEnabled() && getHwcDisplayId(display, &hwcDisplayId)) {
setDisplayExtnActiveConfig(hwcDisplayId, preferredDisplayMode->getId().value());
@@ -9605,14 +9649,23 @@ void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeD
void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
ATRACE_CALL();
+ // During boot, SF powers on the primary display, which is the first display to be active. In
+ // that case, there is no need to force setDesiredActiveMode, because DM is about to send its
+ // policy via setDesiredDisplayModeSpecs.
+ bool forceApplyPolicy = false;
+
if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
display->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
+ forceApplyPolicy = true;
}
if (!activeDisplay) {
ALOGE("%s: activeDisplay is null", __func__);
return;
}
+
+ ALOGI("Active display is %s", to_string(activeDisplay->getPhysicalId()).c_str());
+
mActiveDisplayToken = activeDisplay->getDisplayToken();
activeDisplay->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);
updateInternalDisplayVsyncLocked(activeDisplay);
@@ -9621,9 +9674,11 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activ
onActiveDisplaySizeChanged(activeDisplay);
mActiveDisplayTransformHint = activeDisplay->getTransformHint();
- // Update the kernel timer for the current active display, since the policy
- // for this display might have changed when it was not the active display.
- toggleKernelIdleTimer();
+ // The policy of the new active/leader display may have changed while it was inactive. In that
+ // case, its preferred mode has not been propagated to HWC (via setDesiredActiveMode). In either
+ // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode,
+ // and the kernel idle timer of the newly active display must be toggled.
+ applyRefreshRateConfigsPolicy(activeDisplay, forceApplyPolicy);
}
status_t SurfaceFlinger::addWindowInfosListener(