summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Matt Buckley <mattbuckley@google.com> 2023-10-16 22:00:11 +0000
committer Matt Buckley <mattbuckley@google.com> 2023-10-19 19:18:31 +0000
commitcef0bca744357fa0449c446f7aba35e3075a7274 (patch)
tree5e0dd9fa6cd653804e82db8535c56cbe50c7dde4
parent2a0f9e1103520cd4df2316e5fc8164ef8d671e9e (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.cpp1
-rw-r--r--libs/hwui/renderthread/HintSessionWrapper.cpp1
-rw-r--r--libs/hwui/tests/unit/HintSessionWrapperTests.cpp59
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