diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 59 |
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( |