diff options
author | 2023-10-16 22:00:11 +0000 | |
---|---|---|
committer | 2023-10-19 19:18:31 +0000 | |
commit | cef0bca744357fa0449c446f7aba35e3075a7274 (patch) | |
tree | 5e0dd9fa6cd653804e82db8535c56cbe50c7dde4 | |
parent | 2a0f9e1103520cd4df2316e5fc8164ef8d671e9e (diff) |
Optimize HWUI ADPF for sysui and ensure correct closure
This patch prevents the HintSessionWrapper from setting the
timestamp on load_up hints, to avoid edge cases in systemui
where load_up hints were being sent before reset had a chance
to be checked, making ADPF think work was still ongoing.
This patch also ensures the session closes when a
CanvasContext is destructed, as previously it would wait until
the delayed destroy was evaluated before closing the session.
Bug: 302620048
Test: hwuiunit
Change-Id: I15172382665934acc28c80ff06937475481ba62b
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/renderthread/HintSessionWrapper.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/tests/unit/HintSessionWrapperTests.cpp | 59 |
3 files changed, 58 insertions, 3 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index b00fc699e515..14602ef926d3 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -139,6 +139,7 @@ CanvasContext::~CanvasContext() { mRenderNodes.clear(); mRenderThread.cacheManager().unregisterCanvasContext(this); mRenderThread.renderState().removeContextCallback(this); + mHintSessionWrapper->destroy(); } void CanvasContext::addRenderNode(RenderNode* node, bool placeFront) { diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp index 1c3399a6650d..2362331aca26 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.cpp +++ b/libs/hwui/renderthread/HintSessionWrapper.cpp @@ -158,7 +158,6 @@ void HintSessionWrapper::sendLoadResetHint() { void HintSessionWrapper::sendLoadIncreaseHint() { if (!init()) return; mBinding->sendHint(mHintSession, static_cast<int32_t>(SessionHint::CPU_LOAD_UP)); - mLastFrameNotification = systemTime(); } bool HintSessionWrapper::alive() { diff --git a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp index a14ae1cc46ec..10a740a1f803 100644 --- a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp +++ b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp @@ -259,6 +259,31 @@ TEST_F(HintSessionWrapperTests, delayedDeletionResolvesAfterAsyncCreationFinishe TEST_F(HintSessionWrapperTests, delayedDeletionDoesNotKillReusedSession) { EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(0); + EXPECT_CALL(*sMockBinding, fakeReportActualWorkDuration(sessionPtr, 5_ms)).Times(1); + + mWrapper->init(); + waitForWrapperReady(); + // Init a second time just to grab the wrapper from the promise + mWrapper->init(); + EXPECT_EQ(mWrapper->alive(), true); + + // First schedule the deletion + scheduleDelayedDestroyManaged(); + + // Then, report an actual duration + mWrapper->reportActualWorkDuration(5_ms); + + // Then, run the delayed deletion after sending the update + allowDelayedDestructionToStart(); + waitForDelayedDestructionToFinish(); + + // Ensure it didn't close within the timeframe of the test + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), true); +} + +TEST_F(HintSessionWrapperTests, loadUpDoesNotResetDeletionTimer) { + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1); EXPECT_CALL(*sMockBinding, fakeSendHint(sessionPtr, static_cast<int32_t>(SessionHint::CPU_LOAD_UP))) .Times(1); @@ -272,16 +297,46 @@ TEST_F(HintSessionWrapperTests, delayedDeletionDoesNotKillReusedSession) { // First schedule the deletion scheduleDelayedDestroyManaged(); - // Then, send a hint to update the timestamp + // Then, send a load_up hint mWrapper->sendLoadIncreaseHint(); // Then, run the delayed deletion after sending the update allowDelayedDestructionToStart(); waitForDelayedDestructionToFinish(); - // Ensure it didn't close within the timeframe of the test + // Ensure it closed within the timeframe of the test Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); +} + +TEST_F(HintSessionWrapperTests, manualSessionDestroyPlaysNiceWithDelayedDestruct) { + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1); + + mWrapper->init(); + waitForWrapperReady(); + // Init a second time just to grab the wrapper from the promise + mWrapper->init(); EXPECT_EQ(mWrapper->alive(), true); + + // First schedule the deletion + scheduleDelayedDestroyManaged(); + + // Then, kill the session + mWrapper->destroy(); + + // Verify it died + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); + + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(0); + + // Then, run the delayed deletion after manually killing the session + allowDelayedDestructionToStart(); + waitForDelayedDestructionToFinish(); + + // Ensure it didn't close again and is still dead + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); } } // namespace android::uirenderer::renderthread
\ No newline at end of file |