Change SF power hints to use early frame predictions
Currently we issue hints at the end of the frame reporting what happened
that frame. However, this is often too late anyway and lacks critical
information not known until after the frame completes, like gpu timing.
By waiting until the next frame start and using those timings along with
information about gpu duration, the new expected present time, and the
new wakeup time, we can instead use those timings to predict the
duration of the upcoming frame and signal in advance of a frame drop.
This patch also changes how and where frame timing is done and measures
gpu duration so we can predict if a cpu speedup can help gpu composition
happen earlier, preventing a drop that way.
Bug: b/195990840
Test: manual
Change-Id: I5f0ae796198631fced503dce8e6c495885fb256a
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 0e5a7b6..344fea3 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -169,6 +169,7 @@
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mPowerAdvisor, usePowerHintSession()).WillRepeatedly(Return(false));
}
DisplayCreationArgs getDisplayCreationArgsForPhysicalDisplay() {
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index ff2aa15..9b2b91c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -137,6 +137,7 @@
MOCK_METHOD(bool, hasDisplayIdleTimerCapability, (PhysicalDisplayId), (const, override));
MOCK_METHOD(Hwc2::AidlTransform, getPhysicalDisplayOrientation, (PhysicalDisplayId),
(const, override));
+ MOCK_METHOD(bool, getValidateSkipped, (HalDisplayId), (const, override));
};
} // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index 50adcfb..c8b6d44 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -38,11 +38,31 @@
MOCK_METHOD(bool, usePowerHintSession, (), (override));
MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
- MOCK_METHOD(void, setTargetWorkDuration, (int64_t targetDurationNanos), (override));
- MOCK_METHOD(void, sendActualWorkDuration, (int64_t actualDurationNanos, nsecs_t timestamp),
- (override));
+ MOCK_METHOD(void, setTargetWorkDuration, (int64_t targetDuration), (override));
+ MOCK_METHOD(void, sendActualWorkDuration, (), (override));
+ MOCK_METHOD(void, sendPredictedWorkDuration, (), (override));
MOCK_METHOD(void, enablePowerHint, (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));
+ MOCK_METHOD(void, setValidateTiming,
+ (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
+ (override));
+ MOCK_METHOD(void, setPresentTiming,
+ (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
+ (override));
+ MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
+ MOCK_METHOD(void, setRequiresClientComposition,
+ (DisplayId displayId, bool requiresClientComposition), (override));
+ MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
+ MOCK_METHOD(void, setPresentDelayedTime,
+ (DisplayId displayId,
+ std::chrono::steady_clock::time_point earliestFrameStartTime));
+ MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));
+ MOCK_METHOD(void, setCommitStart, (nsecs_t commitStartTime), (override));
+ MOCK_METHOD(void, setCompositeEnd, (nsecs_t compositeEndtime), (override));
+ MOCK_METHOD(void, setDisplays, (std::vector<DisplayId> & displayIds), (override));
+ MOCK_METHOD(void, setTotalFrameTargetWorkDuration, (int64_t targetDuration), (override));
};
} // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 3a3c91e..d7f5d60 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3304,6 +3304,9 @@
MOCK_METHOD2(appendRegionFlashRequests,
void(const Region&, std::vector<LayerFE::LayerSettings>&));
MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
+ MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
+ (override));
+ MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
};
OutputComposeSurfacesTest() {