Send HWUI load reset hint when Choreographer registers a callback

Send a load reset hint hint to DrawFrameTask through ThreadedRenderer
from ViewRootImpl whenever Choreographer registers a callback. This
allows the PowerHAL to allocate more resources for HWUI in response to
upcoming work, helping prevent frame drop.

Bug: b/243938267
Test: manual

Change-Id: Ie2cf809cf85530af04f4d0db3407853d4da03d62
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index dc7676c..cb30614 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -42,6 +42,7 @@
                                                       size_t, int64_t);
 typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t);
 typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t);
+typedef void (*APH_sendHint)(APerformanceHintSession* session, int32_t);
 typedef void (*APH_closeSession)(APerformanceHintSession* session);
 
 bool gAPerformanceHintBindingInitialized = false;
@@ -49,6 +50,7 @@
 APH_createSession gAPH_createSessionFn = nullptr;
 APH_updateTargetWorkDuration gAPH_updateTargetWorkDurationFn = nullptr;
 APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr;
+APH_sendHint gAPH_sendHintFn = nullptr;
 APH_closeSession gAPH_closeSessionFn = nullptr;
 
 void ensureAPerformanceHintBindingInitialized() {
@@ -77,6 +79,10 @@
             gAPH_reportActualWorkDurationFn == nullptr,
             "Failed to find required symbol APerformanceHint_reportActualWorkDuration!");
 
+    gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint");
+    LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr,
+                        "Failed to find required symbol APerformanceHint_sendHint!");
+
     gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSession");
     LOG_ALWAYS_FATAL_IF(gAPH_closeSessionFn == nullptr,
                         "Failed to find required symbol APerformanceHint_closeSession!");
@@ -239,6 +245,16 @@
     mLastDequeueBufferDuration = dequeueBufferDuration;
 }
 
+void DrawFrameTask::sendLoadResetHint() {
+    if (!(Properties::useHintManager && Properties::isDrawingEnabled())) return;
+    if (!mHintSessionWrapper) mHintSessionWrapper.emplace(mUiThreadId, mRenderThreadId);
+    nsecs_t now = systemTime();
+    if (now - mLastFrameNotification > kResetHintTimeout) {
+        mHintSessionWrapper->sendHint(SessionHint::CPU_LOAD_RESET);
+    }
+    mLastFrameNotification = now;
+}
+
 bool DrawFrameTask::syncFrameState(TreeInfo& info) {
     ATRACE_CALL();
     int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
@@ -327,6 +343,12 @@
     }
 }
 
+void DrawFrameTask::HintSessionWrapper::sendHint(SessionHint hint) {
+    if (mHintSession && Properties::isDrawingEnabled()) {
+        gAPH_sendHintFn(mHintSession, static_cast<int>(hint));
+    }
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */