Send load up hint on view inflation

In order for HWUI to keep up with sudden changes in workload, it
needs to send hints in advance of view inflation in order to compensate
for these increases. This patch allows HWUI to inform PowerHAL about
upcoming spikes in workload.

Bug: b/261130508
Test: manual
Change-Id: Ie0bb80d021dee13067d1960276065f6f2e0af34d
This commit is contained in:
Matt Buckley
2022-12-19 22:03:27 +00:00
parent effd5af692
commit ac5f755472
11 changed files with 62 additions and 0 deletions

View File

@@ -640,6 +640,10 @@ public abstract class LayoutInflater {
mConstructorArgs[0] = inflaterContext;
View result = root;
if (root != null && root.getViewRootImpl() != null) {
root.getViewRootImpl().notifyRendererOfExpensiveFrame();
}
try {
advanceToRootNode(parser);
final String name = parser.getName();
@@ -662,6 +666,10 @@ public abstract class LayoutInflater {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
if (root == null && temp != null && temp.getViewRootImpl() != null) {
temp.getViewRootImpl().notifyRendererOfExpensiveFrame();
}
ViewGroup.LayoutParams params = null;
if (root != null) {

View File

@@ -594,6 +594,13 @@ public final class ThreadedRenderer extends HardwareRenderer {
}
}
@Override
public void notifyExpensiveFrame() {
if (isEnabled()) {
super.notifyExpensiveFrame();
}
}
/**
* Updates the light position based on the position of the window.
*

View File

@@ -2334,6 +2334,18 @@ public final class ViewRootImpl implements ViewParent,
}
}
/**
* Notifies the HardwareRenderer of an expensive upcoming frame, to
* allow better handling of power and scheduling requirements.
*
* @hide
*/
void notifyRendererOfExpensiveFrame() {
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.notifyExpensiveFrame();
}
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
void scheduleTraversals() {
if (!mTraversalScheduled) {

View File

@@ -991,6 +991,15 @@ public class HardwareRenderer {
nNotifyCallbackPending(mNativeProxy);
}
/**
* Notifies the hardware renderer about upcoming expensive frames.
*
* @hide
*/
public void notifyExpensiveFrame() {
nNotifyExpensiveFrame(mNativeProxy);
}
/**
* b/68769804, b/66945974: For low FPS experiments.
*
@@ -1551,4 +1560,6 @@ public class HardwareRenderer {
private static native void nSetRtAnimationsEnabled(boolean rtAnimationsEnabled);
private static native void nNotifyCallbackPending(long nativeProxy);
private static native void nNotifyExpensiveFrame(long nativeProxy);
}

View File

@@ -865,6 +865,11 @@ static void android_view_ThreadedRenderer_notifyCallbackPending(JNIEnv*, jclass,
proxy->notifyCallbackPending();
}
static void android_view_ThreadedRenderer_notifyExpensiveFrame(JNIEnv*, jclass, jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
proxy->notifyExpensiveFrame();
}
// Plumbs the display density down to DeviceInfo.
static void android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv*, jclass, jint densityDpi) {
// Convert from dpi to density-independent pixels.
@@ -1044,6 +1049,8 @@ static const JNINativeMethod gMethods[] = {
(void*)android_view_ThreadedRenderer_setRtAnimationsEnabled},
{"nNotifyCallbackPending", "(J)V",
(void*)android_view_ThreadedRenderer_notifyCallbackPending},
{"nNotifyExpensiveFrame", "(J)V",
(void*)android_view_ThreadedRenderer_notifyExpensiveFrame},
};
static JavaVM* mJvm = nullptr;

View File

@@ -1006,6 +1006,10 @@ void CanvasContext::sendLoadResetHint() {
mHintSessionWrapper.sendLoadResetHint();
}
void CanvasContext::sendLoadIncreaseHint() {
mHintSessionWrapper.sendLoadIncreaseHint();
}
void CanvasContext::setSyncDelayDuration(nsecs_t duration) {
mSyncDelayDuration = duration;
}

View File

@@ -218,6 +218,8 @@ public:
void sendLoadResetHint();
void sendLoadIncreaseHint();
void setSyncDelayDuration(nsecs_t duration);
private:

View File

@@ -158,6 +158,11 @@ void HintSessionWrapper::sendLoadResetHint() {
mLastFrameNotification = now;
}
void HintSessionWrapper::sendLoadIncreaseHint() {
if (!useHintSession()) return;
gAPH_sendHintFn(mHintSession, static_cast<int>(SessionHint::CPU_LOAD_UP));
}
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */

View File

@@ -33,6 +33,7 @@ public:
void updateTargetWorkDuration(long targetDurationNanos);
void reportActualWorkDuration(long actualDurationNanos);
void sendLoadResetHint();
void sendLoadIncreaseHint();
private:
bool useHintSession();

View File

@@ -242,6 +242,10 @@ void RenderProxy::notifyCallbackPending() {
mRenderThread.queue().post([this]() { mContext->sendLoadResetHint(); });
}
void RenderProxy::notifyExpensiveFrame() {
mRenderThread.queue().post([this]() { mContext->sendLoadIncreaseHint(); });
}
void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
mRenderThread.queue().runSync([&]() {
std::lock_guard lock(mRenderThread.getJankDataMutex());

View File

@@ -110,6 +110,7 @@ public:
void stopDrawing();
void notifyFramePending();
void notifyCallbackPending();
void notifyExpensiveFrame();
void dumpProfileInfo(int fd, int dumpFlags);
// Not exported, only used for testing