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

Commit adc914cc authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: acquire/release screen for active display only

SurfaceFlinger assumes that there is at most a single internal display
powered on at a given time, and mark it as the active display. However,
in order to be robust against rare race conditions where displays might
be on together for a short period of time, we add a check to make sure
that we tell the scheduler that the screen was acquired/released only
for the active display.

Bug: 201605862
Test: SF unit tests
Change-Id: I25b3f807d9f5d93ae88ac8a6026cee76cb69f493
parent 4f960d16
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -4611,7 +4611,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
            ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
        }
        getHwComposer().setPowerMode(displayId, mode);
        if (display->isInternal() && mode != hal::PowerMode::DOZE_SUSPEND) {
        if (isDisplayActiveLocked(display) && mode != hal::PowerMode::DOZE_SUSPEND) {
            setHWCVsyncEnabled(displayId, mHWCVsyncPendingState);
            mScheduler->onScreenAcquired(mAppConnectionHandle);
            mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4628,7 +4628,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
        if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
            ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
        }
        if (display->isInternal() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
        if (isDisplayActiveLocked(display) && currentMode != hal::PowerMode::DOZE_SUSPEND) {
            mScheduler->disableHardwareVsync(true);
            mScheduler->onScreenReleased(mAppConnectionHandle);
        }
@@ -4642,13 +4642,13 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
    } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
        // Update display while dozing
        getHwComposer().setPowerMode(displayId, mode);
        if (display->isInternal() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
        if (isDisplayActiveLocked(display) && 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->isInternal()) {
        if (isDisplayActiveLocked(display)) {
            mScheduler->disableHardwareVsync(true);
            mScheduler->onScreenReleased(mAppConnectionHandle);
        }
@@ -4658,7 +4658,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
        getHwComposer().setPowerMode(displayId, mode);
    }

    if (display->isInternal()) {
    if (isDisplayActiveLocked(display)) {
        mTimeStats->setPowerMode(mode);
        mRefreshRateStats->setPowerMode(mode);
        mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
+5 −0
Original line number Diff line number Diff line
@@ -260,6 +260,11 @@ struct DisplayPowerCase {
        auto display = Display::makeFakeExistingDisplayInjector(test);
        display.inject();
        display.mutableDisplayDevice()->setPowerMode(mode);
        if (display.mutableDisplayDevice()->isInternal()) {
            test->mFlinger.mutableActiveDisplayToken() =
                    display.mutableDisplayDevice()->getDisplayToken();
        }

        return display;
    }

+1 −0
Original line number Diff line number Diff line
@@ -442,6 +442,7 @@ public:
    auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
    auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
    auto& mutableUseFrameRateApi() { return mFlinger->useFrameRateApi; }
    auto& mutableActiveDisplayToken() { return mFlinger->mActiveDisplayToken; }

    auto fromHandle(const sp<IBinder>& handle) {
        return mFlinger->fromHandle(handle);