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

Commit 0eea6f5c authored by Matt Buckley's avatar Matt Buckley Committed by Android (Google) Code Review
Browse files

Merge "Rewrite the PowerAdvisor using standard power wrappers and clean up"

parents 7923d433 cbfe23c9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -43,6 +43,14 @@ cc_library_shared {
        "android.hardware.power-V4-cpp",
    ],

    export_shared_lib_headers: [
        "android.hardware.power@1.0",
        "android.hardware.power@1.1",
        "android.hardware.power@1.2",
        "android.hardware.power@1.3",
        "android.hardware.power-V4-cpp",
    ],

    cflags: [
        "-Wall",
        "-Werror",
+2 −3
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@ cc_defaults {
        "android.hardware.graphics.composer@2.2",
        "android.hardware.graphics.composer@2.3",
        "android.hardware.graphics.composer@2.4",
        "android.hardware.power@1.0",
        "android.hardware.power@1.3",
        "android.hardware.power-V4-cpp",
        "libbase",
        "libbinder",
@@ -63,6 +61,7 @@ cc_defaults {
        "liblayers_proto",
        "liblog",
        "libnativewindow",
        "libpowermanager",
        "libprocessgroup",
        "libprotobuf-cpp-lite",
        "libsync",
@@ -105,7 +104,7 @@ cc_defaults {
        "android.hardware.graphics.composer@2.2",
        "android.hardware.graphics.composer@2.3",
        "android.hardware.graphics.composer@2.4",
        "android.hardware.power@1.3",
        "libpowermanager",
        "libhidlbase",
        "libtimestats",
    ],
+4 −5
Original line number Diff line number Diff line
@@ -37,11 +37,10 @@ public:
    MOCK_METHOD(void, notifyDisplayUpdateImminentAndCpuReset, (), (override));
    MOCK_METHOD(bool, usePowerHintSession, (), (override));
    MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
    MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
    MOCK_METHOD(void, setTargetWorkDuration, (Duration targetDuration), (override));
    MOCK_METHOD(void, sendActualWorkDuration, (), (override));
    MOCK_METHOD(void, sendPredictedWorkDuration, (), (override));
    MOCK_METHOD(void, enablePowerHint, (bool enabled), (override));
    MOCK_METHOD(bool, ensurePowerHintSessionRunning, (), (override));
    MOCK_METHOD(void, updateTargetWorkDuration, (Duration targetDuration), (override));
    MOCK_METHOD(void, reportActualWorkDuration, (), (override));
    MOCK_METHOD(void, enablePowerHintSession, (bool enabled), (override));
    MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
    MOCK_METHOD(void, setGpuFenceTime,
                (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
+131 −438

File changed.

Preview size limit exceeded, changes collapsed.

+36 −94
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <android/hardware/power/IPower.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <powermanager/PowerHalController.h>
#include <scheduler/Time.h>
#include <ui/DisplayIdentification.h>
#include "../Scheduler/OneShotTimer.h"
@@ -52,15 +53,14 @@ public:
    // Checks both if it supports and if it's enabled
    virtual bool usePowerHintSession() = 0;
    virtual bool supportsPowerHintSession() = 0;
    virtual bool isPowerHintSessionRunning() = 0;

    virtual bool ensurePowerHintSessionRunning() = 0;
    // Sends a power hint that updates to the target work duration for the frame
    virtual void setTargetWorkDuration(Duration targetDuration) = 0;
    virtual void updateTargetWorkDuration(Duration targetDuration) = 0;
    // Sends a power hint for the actual known work duration at the end of the frame
    virtual void sendActualWorkDuration() = 0;
    // Sends a power hint for the upcoming frame predicted from previous frame timing
    virtual void sendPredictedWorkDuration() = 0;
    virtual void reportActualWorkDuration() = 0;
    // Sets whether the power hint session is enabled
    virtual void enablePowerHint(bool enabled) = 0;
    virtual void enablePowerHintSession(bool enabled) = 0;
    // Initializes the power hint session
    virtual bool startPowerHintSession(const std::vector<int32_t>& threadIds) = 0;
    // Provides PowerAdvisor with a copy of the gpu fence so it can determine the gpu end time
@@ -101,24 +101,6 @@ namespace impl {
// full state of the system when sending out power hints to things like the GPU.
class PowerAdvisor final : public Hwc2::PowerAdvisor {
public:
    class HalWrapper {
    public:
        virtual ~HalWrapper() = default;

        virtual bool setExpensiveRendering(bool enabled) = 0;
        virtual bool notifyDisplayUpdateImminentAndCpuReset() = 0;
        virtual bool supportsPowerHintSession() = 0;
        virtual bool isPowerHintSessionRunning() = 0;
        virtual void restartPowerHintSession() = 0;
        virtual void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) = 0;
        virtual bool startPowerHintSession() = 0;
        virtual void setTargetWorkDuration(Duration targetDuration) = 0;
        virtual void sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) = 0;
        virtual bool shouldReconnectHAL() = 0;
        virtual std::vector<int32_t> getPowerHintSessionThreadIds() = 0;
        virtual std::optional<Duration> getTargetWorkDuration() = 0;
    };

    PowerAdvisor(SurfaceFlinger& flinger);
    ~PowerAdvisor() override;

@@ -129,11 +111,10 @@ public:
    void notifyDisplayUpdateImminentAndCpuReset() override;
    bool usePowerHintSession() override;
    bool supportsPowerHintSession() override;
    bool isPowerHintSessionRunning() override;
    void setTargetWorkDuration(Duration targetDuration) override;
    void sendActualWorkDuration() override;
    void sendPredictedWorkDuration() override;
    void enablePowerHint(bool enabled) override;
    bool ensurePowerHintSessionRunning() override;
    void updateTargetWorkDuration(Duration targetDuration) override;
    void reportActualWorkDuration() override;
    void enablePowerHintSession(bool enabled) override;
    bool startPowerHintSession(const std::vector<int32_t>& threadIds) override;
    void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime);
    void setHwcValidateTiming(DisplayId displayId, TimePoint validateStartTime,
@@ -155,15 +136,7 @@ public:
private:
    friend class PowerAdvisorTest;

    // Tracks if powerhal exists
    bool mHasHal = true;
    // Holds the hal wrapper for getPowerHal
    std::unique_ptr<HalWrapper> mHalWrapper GUARDED_BY(mPowerHalMutex) = nullptr;

    HalWrapper* getPowerHal() REQUIRES(mPowerHalMutex);
    bool mReconnectPowerHal GUARDED_BY(mPowerHalMutex) = false;
    std::mutex mPowerHalMutex;

    std::unique_ptr<power::PowerHalController> mPowerHal;
    std::atomic_bool mBootFinished = false;

    std::unordered_set<DisplayId> mExpensiveDisplays;
@@ -189,9 +162,6 @@ private:
        Duration postPresentFenceHwcPresentDuration{0ns};
        // Are we likely to have waited for the present fence during composition
        bool probablyWaitsForPresentFence = false;
        // Estimate one frame's timeline from that of a previous frame
        DisplayTimeline estimateTimelineFromReference(TimePoint fenceTime,
                                                      TimePoint displayStartTime);
    };

    struct GpuTimeline {
@@ -243,8 +213,7 @@ private:
    std::vector<DisplayId> getOrderedDisplayIds(
            std::optional<TimePoint> DisplayTimingData::*sortBy);
    // Estimates a frame's total work duration including gpu time.
    // Runs either at the beginning or end of a frame, using the most recent data available
    std::optional<Duration> estimateWorkDuration(bool earlyHint);
    std::optional<Duration> estimateWorkDuration();
    // There are two different targets and actual work durations we care about,
    // this normalizes them together and takes the max of the two
    Duration combineTimingEstimates(Duration totalDuration, Duration flingerDuration);
@@ -268,68 +237,41 @@ private:
    // Updated list of display IDs
    std::vector<DisplayId> mDisplayIds;

    std::optional<bool> mPowerHintEnabled;
    std::optional<bool> mSupportsPowerHint;
    bool mPowerHintSessionRunning = false;

    // An adjustable safety margin which pads the "actual" value sent to PowerHAL,
    // encouraging more aggressive boosting to give SurfaceFlinger a larger margin for error
    static const Duration sTargetSafetyMargin;
    static constexpr const Duration kDefaultTargetSafetyMargin{1ms};

    // How long we expect hwc to run after the present call until it waits for the fence
    static constexpr const Duration kFenceWaitStartDelayValidated{150us};
    static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
};

class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
public:
    explicit AidlPowerHalWrapper(sp<hardware::power::IPower> powerHal);
    ~AidlPowerHalWrapper() override;
    // Ensure powerhal connection is initialized
    power::PowerHalController& getPowerHal();

    static std::unique_ptr<HalWrapper> connect();
    std::optional<bool> mHintSessionEnabled;
    std::optional<bool> mSupportsHintSession;
    bool mHintSessionRunning = false;

    bool setExpensiveRendering(bool enabled) override;
    bool notifyDisplayUpdateImminentAndCpuReset() override;
    bool supportsPowerHintSession() override;
    bool isPowerHintSessionRunning() override;
    void restartPowerHintSession() override;
    void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) override;
    bool startPowerHintSession() override;
    void setTargetWorkDuration(Duration targetDuration) override;
    void sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) override;
    bool shouldReconnectHAL() override;
    std::vector<int32_t> getPowerHintSessionThreadIds() override;
    std::optional<Duration> getTargetWorkDuration() override;

private:
    friend class AidlPowerHalWrapperTest;
    std::mutex mHintSessionMutex;
    sp<hardware::power::IPowerHintSession> mHintSession GUARDED_BY(mHintSessionMutex) = nullptr;

    bool checkPowerHintSessionSupported();
    void closePowerHintSession();

    const sp<hardware::power::IPower> mPowerHal = nullptr;
    bool mHasExpensiveRendering = false;
    bool mHasDisplayUpdateImminent = false;
    // Used to indicate an error state and need for reconstruction
    bool mShouldReconnectHal = false;

    // Power hint session data

    // Concurrent access for this is protected by mPowerHalMutex
    sp<hardware::power::IPowerHintSession> mPowerHintSession = nullptr;
    // Initialize to true so we try to call, to check if it's supported
    bool mHasExpensiveRendering = true;
    bool mHasDisplayUpdateImminent = true;
    // Queue of actual durations saved to report
    std::vector<hardware::power::WorkDuration> mPowerHintQueue;
    std::vector<hardware::power::WorkDuration> mHintSessionQueue;
    // The latest values we have received for target and actual
    Duration mTargetDuration = kDefaultTargetDuration;
    std::optional<Duration> mActualDuration;
    // The list of thread ids, stored so we can restart the session from this class if needed
    std::vector<int32_t> mPowerHintThreadIds;
    bool mSupportsPowerHint = false;
    std::vector<int32_t> mHintSessionThreadIds;
    Duration mLastTargetDurationSent = kDefaultTargetDuration;
    // Whether we should emit ATRACE_INT data for hint sessions
    static const bool sTraceHintSessionData;
    static constexpr Duration kDefaultTargetDuration{16ms};

    // Default target duration for the hint session
    static constexpr const Duration kDefaultTargetDuration{16ms};

    // An adjustable safety margin which pads the "actual" value sent to PowerHAL,
    // encouraging more aggressive boosting to give SurfaceFlinger a larger margin for error
    static const Duration sTargetSafetyMargin;
    static constexpr const Duration kDefaultTargetSafetyMargin{1ms};

    // How long we expect hwc to run after the present call until it waits for the fence
    static constexpr const Duration kFenceWaitStartDelayValidated{150us};
    static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
};

} // namespace impl
Loading