Integrate HWUI with PerformanceHintManager

PerformanceHintManager.Session is in java, so add JNI and a HintSessionWrapper
class in HardwareRenderer. Then pass the two calls as two std::functions
into DrawFrameTask.

Note Session is created per HardwareRenderer, not global (per
RenderThread).

Session includes UI thread, render thread, and the thread pool.
Desired duration is from the intended start duration to the frame
deadline. Add an actual frame start time to compute

Add system properties:
debug.hwui.use_hint_manager to enable PerformanceHintManager
debug.hwui.target_cpu_time_percent to control percentage of frame time
  to be used for target cpu duration.

Test: Manual test that there are no crashes and values make sense.
Bug: 158791282
Change-Id: I83f25433c10daa20033803fb7c4ae45eab34f1d3
This commit is contained in:
Bo Liu
2021-03-18 16:50:38 -04:00
committed by Wei Wang
parent 25318b7316
commit 027b218847
15 changed files with 278 additions and 48 deletions

View File

@@ -21,6 +21,7 @@
#include "../DeferredLayerUpdater.h"
#include "../DisplayList.h"
#include "../Properties.h"
#include "../RenderNode.h"
#include "CanvasContext.h"
#include "RenderThread.h"
@@ -44,6 +45,12 @@ void DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context,
mTargetNode = targetNode;
}
void DrawFrameTask::setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
std::function<void(int64_t)> reportActualWorkDuration) {
mUpdateTargetWorkDuration = std::move(updateTargetWorkDuration);
mReportActualWorkDuration = std::move(reportActualWorkDuration);
}
void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) {
LOG_ALWAYS_FATAL_IF(!mContext,
"Lifecycle violation, there's no context to pushLayerUpdate with!");
@@ -102,6 +109,9 @@ void DrawFrameTask::run() {
CanvasContext* context = mContext;
std::function<void(int64_t)> callback = std::move(mFrameCallback);
mFrameCallback = nullptr;
int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)];
int64_t frameStartTime = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameStartTime)];
// From this point on anything in "this" is *UNSAFE TO ACCESS*
if (canUnblockUiThread) {
@@ -124,6 +134,25 @@ void DrawFrameTask::run() {
if (!canUnblockUiThread) {
unblockUiThread();
}
// These member callbacks are effectively const as they are set once during init, so it's safe
// to use these directly instead of making local copies.
if (mUpdateTargetWorkDuration && mReportActualWorkDuration) {
constexpr int64_t kSanityCheckLowerBound = 100000; // 0.1ms
constexpr int64_t kSanityCheckUpperBound = 10000000000; // 10s
int64_t targetWorkDuration = frameDeadline - intendedVsync;
targetWorkDuration = targetWorkDuration * Properties::targetCpuTimePercentage / 100;
if (targetWorkDuration > kSanityCheckLowerBound &&
targetWorkDuration < kSanityCheckUpperBound &&
targetWorkDuration != mLastTargetWorkDuration) {
mLastTargetWorkDuration = targetWorkDuration;
mUpdateTargetWorkDuration(targetWorkDuration);
}
int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime;
if (frameDuration > kSanityCheckLowerBound && frameDuration < kSanityCheckUpperBound) {
mReportActualWorkDuration(frameDuration);
}
}
}
bool DrawFrameTask::syncFrameState(TreeInfo& info) {