Rewrite the PowerAdvisor using standard power wrappers and clean up
* Replace custom AIDL/HIDL wrappers with libpowermanager
* Remove early hint code as it is deprecated for load change hints
Bug: b/245975645
Bug: b/244358432
Test: atest libsurfaceflinger_unittest
Change-Id: I2a11779ce1f78bcf29ea0e7978cb8933e74e9f7b
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index c4cfdc3..7a0d426 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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,9 +237,32 @@
// Updated list of display IDs
std::vector<DisplayId> mDisplayIds;
- std::optional<bool> mPowerHintEnabled;
- std::optional<bool> mSupportsPowerHint;
- bool mPowerHintSessionRunning = false;
+ // Ensure powerhal connection is initialized
+ power::PowerHalController& getPowerHal();
+
+ std::optional<bool> mHintSessionEnabled;
+ std::optional<bool> mSupportsHintSession;
+ bool mHintSessionRunning = false;
+
+ std::mutex mHintSessionMutex;
+ sp<hardware::power::IPowerHintSession> mHintSession GUARDED_BY(mHintSessionMutex) = 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> 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> mHintSessionThreadIds;
+ Duration mLastTargetDurationSent = kDefaultTargetDuration;
+ // Whether we should emit ATRACE_INT data for hint sessions
+ static const bool sTraceHintSessionData;
+
+ // 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
@@ -282,56 +274,6 @@
static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
};
-class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
-public:
- explicit AidlPowerHalWrapper(sp<hardware::power::IPower> powerHal);
- ~AidlPowerHalWrapper() override;
-
- static std::unique_ptr<HalWrapper> connect();
-
- 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;
-
- 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;
- // Queue of actual durations saved to report
- std::vector<hardware::power::WorkDuration> mPowerHintQueue;
- // 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;
- Duration mLastTargetDurationSent = kDefaultTargetDuration;
- // Whether we should emit ATRACE_INT data for hint sessions
- static const bool sTraceHintSessionData;
- static constexpr Duration kDefaultTargetDuration{16ms};
-};
-
} // namespace impl
} // namespace Hwc2
} // namespace android