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
This commit is contained in:
Matt Buckley
2023-03-30 20:58:22 +00:00
parent 9b65137e97
commit 191f5cc501
2 changed files with 32 additions and 12 deletions

View File

@@ -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 @@ HintSessionWrapper::~HintSessionWrapper() {
}
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 @@ bool HintSessionWrapper::init() {
// 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::updateTargetWorkDuration(long targetWorkDurationNanos)
}
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::reportActualWorkDuration(long actualDurationNanos) {
}
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::sendLoadResetHint() {
}
void HintSessionWrapper::sendLoadIncreaseHint() {
if (mHintSession == nullptr) return;
if (!init()) return;
gAPH_sendHintFn(mHintSession, static_cast<int>(SessionHint::CPU_LOAD_UP));
}

View File

@@ -18,6 +18,8 @@
#include <android/performance_hint.h>
#include <future>
#include "utils/TimeUtils.h"
namespace android {
@@ -38,6 +40,7 @@ public:
private:
APerformanceHintSession* mHintSession = nullptr;
std::future<APerformanceHintSession*> mHintSessionFuture;
nsecs_t mLastFrameNotification = 0;
nsecs_t mLastTargetWorkDuration = 0;