Create hint session asynchronously
Sends createHintSession asynchronously inside worker thread
Consistency is maintained by returning the session with a std::future
which we only check when we try to do hint session operations within
renderthread, to avoid races or mutexes necessary with a callback fn.
Bug: 272002264
Test: manual
Change-Id: I9b64f20f1abdac91993742b9f9aea7824288fdd3
diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp
index 8c9f65f..597cbf7 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.cpp
+++ b/libs/hwui/renderthread/HintSessionWrapper.cpp
@@ -20,11 +20,14 @@
#include <private/performance_hint_private.h>
#include <utils/Log.h>
+#include <chrono>
#include <vector>
#include "../Properties.h"
#include "thread/CommonPool.h"
+using namespace std::chrono_literals;
+
namespace android {
namespace uirenderer {
namespace renderthread {
@@ -96,10 +99,25 @@
}
bool HintSessionWrapper::init() {
- // If it already exists, broke last time we tried this, shouldn't be running, or
+ if (mHintSession != nullptr) return true;
+
+ // If we're waiting for the session
+ if (mHintSessionFuture.valid()) {
+ // If the session is here
+ if (mHintSessionFuture.wait_for(0s) == std::future_status::ready) {
+ mHintSession = mHintSessionFuture.get();
+ if (mHintSession != nullptr) {
+ mSessionValid = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // If it broke last time we tried this, shouldn't be running, or
// has bad argument values, don't even bother
- if (mHintSession != nullptr || !mSessionValid || !Properties::useHintManager ||
- !Properties::isDrawingEnabled() || mUiThreadId < 0 || mRenderThreadId < 0) {
+ if (!mSessionValid || !Properties::useHintManager || !Properties::isDrawingEnabled() ||
+ mUiThreadId < 0 || mRenderThreadId < 0) {
return false;
}
@@ -118,15 +136,14 @@
// Use a placeholder target value to initialize,
// this will always be replaced elsewhere before it gets used
int64_t defaultTargetDurationNanos = 16666667;
- mHintSession =
- gAPH_createSessionFn(manager, tids.data(), tids.size(), defaultTargetDurationNanos);
-
- mSessionValid = !!mHintSession;
- return mSessionValid;
+ mHintSessionFuture = CommonPool::async([=, tids = std::move(tids)] {
+ return gAPH_createSessionFn(manager, tids.data(), tids.size(), defaultTargetDurationNanos);
+ });
+ return false;
}
void HintSessionWrapper::updateTargetWorkDuration(long targetWorkDurationNanos) {
- if (mHintSession == nullptr) return;
+ if (!init()) return;
targetWorkDurationNanos = targetWorkDurationNanos * Properties::targetCpuTimePercentage / 100;
if (targetWorkDurationNanos != mLastTargetWorkDuration &&
targetWorkDurationNanos > kSanityCheckLowerBound &&
@@ -138,7 +155,7 @@
}
void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) {
- if (mHintSession == nullptr) return;
+ if (!init()) return;
if (actualDurationNanos > kSanityCheckLowerBound &&
actualDurationNanos < kSanityCheckUpperBound) {
gAPH_reportActualWorkDurationFn(mHintSession, actualDurationNanos);
@@ -146,7 +163,7 @@
}
void HintSessionWrapper::sendLoadResetHint() {
- if (mHintSession == nullptr) return;
+ if (!init()) return;
nsecs_t now = systemTime();
if (now - mLastFrameNotification > kResetHintTimeout) {
gAPH_sendHintFn(mHintSession, static_cast<int>(SessionHint::CPU_LOAD_RESET));
@@ -155,7 +172,7 @@
}
void HintSessionWrapper::sendLoadIncreaseHint() {
- if (mHintSession == nullptr) return;
+ if (!init()) return;
gAPH_sendHintFn(mHintSession, static_cast<int>(SessionHint::CPU_LOAD_UP));
}
diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h
index f2f1298..b7a433f 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.h
+++ b/libs/hwui/renderthread/HintSessionWrapper.h
@@ -18,6 +18,8 @@
#include <android/performance_hint.h>
+#include <future>
+
#include "utils/TimeUtils.h"
namespace android {
@@ -38,6 +40,7 @@
private:
APerformanceHintSession* mHintSession = nullptr;
+ std::future<APerformanceHintSession*> mHintSessionFuture;
nsecs_t mLastFrameNotification = 0;
nsecs_t mLastTargetWorkDuration = 0;