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

Commit 2c710c3d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use power mode of all independent displays to control power optimisations." into main

parents 89366b4e 00a764ee
Loading
Loading
Loading
Loading
+82 −13
Original line number Original line Diff line number Diff line
@@ -4075,6 +4075,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
        incRefreshableDisplays();
        incRefreshableDisplays();
    }
    }


    if (FlagManager::getInstance().correct_virtual_display_power_state()) {
        applyOptimizationPolicy(__func__);
    }

    mDisplays.try_emplace(displayToken, std::move(display));
    mDisplays.try_emplace(displayToken, std::move(display));


    // For an external display, loadDisplayModes already attempted to select the same mode
    // For an external display, loadDisplayModes already attempted to select the same mode
@@ -4131,6 +4135,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
            // not be accessible.
            // not be accessible.
        }));
        }));
    }
    }

    if (FlagManager::getInstance().correct_virtual_display_power_state()) {
        applyOptimizationPolicy(__func__);
    }
}
}


void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
@@ -5680,7 +5688,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
    }
    }


    const auto displayId = display->getPhysicalId();
    const auto displayId = display->getPhysicalId();
    ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
    ALOGD("Setting power mode %d on physical display %s", mode, to_string(displayId).c_str());


    const auto currentMode = display->getPowerMode();
    const auto currentMode = display->getPowerMode();
    if (currentMode == mode) {
    if (currentMode == mode) {
@@ -5723,11 +5731,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
        }
        }


        if (displayId == mActiveDisplayId) {
        if (displayId == mActiveDisplayId) {
            // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
            if (FlagManager::getInstance().correct_virtual_display_power_state()) {
            // and set it before SCHED_FIFO due to b/190237315.
                applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)");
            constexpr const char* kWhence = "setPowerMode(ON)";
            } else {
            setSchedAttr(true, kWhence);
                disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)");
            setSchedFifo(true, kWhence);
            }
        }
        }


        getHwComposer().setPowerMode(displayId, mode);
        getHwComposer().setPowerMode(displayId, mode);
@@ -5754,9 +5762,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
            if (const auto display = getActivatableDisplay()) {
            if (const auto display = getActivatableDisplay()) {
                onActiveDisplayChangedLocked(activeDisplay.get(), *display);
                onActiveDisplayChangedLocked(activeDisplay.get(), *display);
            } else {
            } else {
                constexpr const char* kWhence = "setPowerMode(OFF)";
                if (FlagManager::getInstance().correct_virtual_display_power_state()) {
                setSchedFifo(false, kWhence);
                    applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)");
                setSchedAttr(false, kWhence);
                } else {
                    enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)");
                }


                if (currentModeNotDozeSuspend) {
                if (currentModeNotDozeSuspend) {
                    if (!FlagManager::getInstance().multithreaded_present()) {
                    if (!FlagManager::getInstance().multithreaded_present()) {
@@ -5817,7 +5827,67 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa


    mScheduler->setDisplayPowerMode(displayId, mode);
    mScheduler->setDisplayPowerMode(displayId, mode);


    ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
    ALOGD("Finished setting power mode %d on physical display %s", mode,
          to_string(displayId).c_str());
}

void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display,
                                                hal::PowerMode mode) {
    if (!display->isVirtual()) {
        ALOGE("%s: Invalid operation on physical display", __func__);
        return;
    }

    const auto displayId = display->getVirtualId();
    ALOGD("Setting power mode %d on virtual display %s %s", mode, to_string(displayId).c_str(),
          display->getDisplayName().c_str());

    display->setPowerMode(static_cast<hal::PowerMode>(mode));

    applyOptimizationPolicy(__func__);

    ALOGD("Finished setting power mode %d on virtual display %s", mode,
          to_string(displayId).c_str());
}

bool SurfaceFlinger::shouldOptimizeForPerformance() {
    for (const auto& [_, display] : mDisplays) {
        // Displays that are optimized for power are always powered on and should not influence
        // whether there is an active display for the purpose of power optimization, etc. If these
        // displays are being shown somewhere, a different (physical or virtual) display that is
        // optimized for performance will be powered on in addition. Displays optimized for
        // performance will change power mode, so if they are off then they are not active.
        if (display->isPoweredOn() &&
            display->getOptimizationPolicy() ==
                    gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
            return true;
        }
    }
    return false;
}

void SurfaceFlinger::enablePowerOptimizations(const char* whence) {
    ALOGD("%s: Enabling power optimizations", whence);

    setSchedAttr(false, whence);
    setSchedFifo(false, whence);
}

void SurfaceFlinger::disablePowerOptimizations(const char* whence) {
    ALOGD("%s: Disabling power optimizations", whence);

    // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
    // and set it before SCHED_FIFO due to b/190237315.
    setSchedAttr(true, whence);
    setSchedFifo(true, whence);
}

void SurfaceFlinger::applyOptimizationPolicy(const char* whence) {
    if (shouldOptimizeForPerformance()) {
        disablePowerOptimizations(whence);
    } else {
        enablePowerOptimizations(whence);
    }
}
}


void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
@@ -5839,9 +5909,8 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
            ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get());
            ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get());
        } else if (display->isVirtual()) {
        } else if (display->isVirtual()) {
            if (FlagManager::getInstance().correct_virtual_display_power_state()) {
            if (FlagManager::getInstance().correct_virtual_display_power_state()) {
                ALOGD("Setting power mode %d on virtual display %s", mode,
                ftl::FakeGuard guard(mStateLock);
                      display->getDisplayName().c_str());
                setVirtualDisplayPowerMode(display, static_cast<hal::PowerMode>(mode));
                display->setPowerMode(static_cast<hal::PowerMode>(mode));
            } else {
            } else {
                ALOGW("Attempt to set power mode %d for virtual display", mode);
                ALOGW("Attempt to set power mode %d for virtual display", mode);
            }
            }
+16 −0
Original line number Original line Diff line number Diff line
@@ -735,6 +735,22 @@ private:
    // Called on the main thread in response to setPowerMode()
    // Called on the main thread in response to setPowerMode()
    void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
    void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
            REQUIRES(mStateLock, kMainThreadContext);
            REQUIRES(mStateLock, kMainThreadContext);
    void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
            REQUIRES(mStateLock, kMainThreadContext);

    // Returns whether to optimize globally for performance instead of power.
    bool shouldOptimizeForPerformance() REQUIRES(mStateLock);

    // Turns on power optimizations, for example when there are no displays to be optimized for
    // performance.
    static void enablePowerOptimizations(const char* whence);

    // Turns off power optimizations.
    static void disablePowerOptimizations(const char* whence);

    // Enables or disables power optimizations depending on whether there are displays that should
    // be optimized for performance.
    void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock);


    // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that
    // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that
    // display. Falls back to the display's defaultModeId otherwise.
    // display. Falls back to the display's defaultModeId otherwise.