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.cpp59
1 files changed, 44 insertions, 15 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 871f06a1c3..a4aa6904e3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1540,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) {
@@ -1553,7 +1553,6 @@ void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) {
return;
}
-
if (isFpsDeferNeeded(info)) {
return;
}
@@ -1563,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
@@ -4603,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;
}
@@ -5470,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,
@@ -5479,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);
}
@@ -6225,7 +6231,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);
@@ -8532,8 +8538,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();
}
@@ -8794,9 +8802,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
@@ -8824,7 +8842,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());
@@ -9630,14 +9648,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);
@@ -9646,9 +9673,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(