Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0006974 authored by Ady Abraham's avatar Ady Abraham Committed by Ana Krulec
Browse files

SurfaceFlinger: always turn HWVsync off when display is off

Maintain a state in SF about what is the latest HWVsync state in HWC
and what it should be. Apply the desired state when screen turns on and
always disabled HWVsync when the display is off.

Test: display power on/off
Bug: 134965007
Change-Id: I9c23d09ea2e32efa0b1f30a3999a08d15d7f35a6
(cherry picked from commit 27c70212)
Merged-In: I9c23d09ea2e32efa0b1f30a3999a08d15d7f35a6
parent 7849f2a0
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -1546,14 +1546,12 @@ void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) {
void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) {
    ATRACE_CALL();

    mHWCVsyncPendingState = enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable;

    if (const auto displayId = getInternalDisplayIdLocked()) {
        sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
        if (display && display->isPoweredOn()) {
            getHwComposer().setVsyncEnabled(*displayId,
                                            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
        } else {
            // Cache the latest vsync state and apply it when screen is on again
            mEnableHWVsyncScreenOn = enabled;
            setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
        }
    }
}
@@ -4444,6 +4442,13 @@ void SurfaceFlinger::initializeDisplays() {
            new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); }));
}

void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled) {
    if (mHWCVsyncState != enabled) {
        getHwComposer().setVsyncEnabled(displayId, enabled);
        mHWCVsyncState = enabled;
    }
}

void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int mode) {
    if (display->isVirtual()) {
        ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
@@ -4470,11 +4475,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
        // Turn on the display
        getHwComposer().setPowerMode(*displayId, mode);
        if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
            if (mEnableHWVsyncScreenOn) {
                setPrimaryVsyncEnabledInternal(mEnableHWVsyncScreenOn);
                mEnableHWVsyncScreenOn = false;
            }

            setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
            mScheduler->onScreenAcquired(mAppConnectionHandle);
            mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
        }
@@ -4500,6 +4501,9 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
            mScheduler->onScreenReleased(mAppConnectionHandle);
        }

        // Make sure HWVsync is disabled before turning off the display
        setVsyncEnabledInHWC(*displayId, HWC2::Vsync::Disable);

        getHwComposer().setPowerMode(*displayId, mode);
        mVisibleRegionsDirty = true;
        // from this point on, SF will stop drawing on this display
+4 −2
Original line number Diff line number Diff line
@@ -845,6 +845,7 @@ private:
    }

    bool previousFrameMissed();
    void setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled);

    /*
     * Debugging & dumpsys
@@ -1180,8 +1181,9 @@ private:
    // be any issues with a raw pointer referencing an invalid object.
    std::unordered_set<Layer*> mOffscreenLayers;

    // Flag to indicate whether to re-enable HWVsync when screen is on
    bool mEnableHWVsyncScreenOn = false;
    // Flags to capture the state of Vsync in HWC
    HWC2::Vsync mHWCVsyncState = HWC2::Vsync::Disable;
    HWC2::Vsync mHWCVsyncPendingState = HWC2::Vsync::Disable;
};

} // namespace android