From ac5f755472e02f039f947ccfd5f5282e0ac80fe3 Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Mon, 19 Dec 2022 22:03:27 +0000 Subject: [PATCH] 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 --- core/java/android/view/LayoutInflater.java | 8 ++++++++ core/java/android/view/ThreadedRenderer.java | 7 +++++++ core/java/android/view/ViewRootImpl.java | 12 ++++++++++++ graphics/java/android/graphics/HardwareRenderer.java | 11 +++++++++++ libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 7 +++++++ libs/hwui/renderthread/CanvasContext.cpp | 4 ++++ libs/hwui/renderthread/CanvasContext.h | 2 ++ libs/hwui/renderthread/HintSessionWrapper.cpp | 5 +++++ libs/hwui/renderthread/HintSessionWrapper.h | 1 + libs/hwui/renderthread/RenderProxy.cpp | 4 ++++ libs/hwui/renderthread/RenderProxy.h | 1 + 11 files changed, 62 insertions(+) diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index df78827534a61..99a7fe5989369 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -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) { diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 164a49464051a..9c6e823b549e4 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -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. * diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ea7a64ef5c24a..30e98a4e64f7d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -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) { diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index c7c97e0b82b9d..0892a9b14738c 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -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); } diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 0663121a40277..e457c311f6899 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -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(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; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 64839d0147f8e..b92c90edd1ca4 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -1006,6 +1006,10 @@ void CanvasContext::sendLoadResetHint() { mHintSessionWrapper.sendLoadResetHint(); } +void CanvasContext::sendLoadIncreaseHint() { + mHintSessionWrapper.sendLoadIncreaseHint(); +} + void CanvasContext::setSyncDelayDuration(nsecs_t duration) { mSyncDelayDuration = duration; } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index e875c42e9ebad..d29e12c38d9f8 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -218,6 +218,8 @@ public: void sendLoadResetHint(); + void sendLoadIncreaseHint(); + void setSyncDelayDuration(nsecs_t duration); private: diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp index 94c9d94a7c261..dece548e9dc19 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.cpp +++ b/libs/hwui/renderthread/HintSessionWrapper.cpp @@ -158,6 +158,11 @@ void HintSessionWrapper::sendLoadResetHint() { mLastFrameNotification = now; } +void HintSessionWrapper::sendLoadIncreaseHint() { + if (!useHintSession()) return; + gAPH_sendHintFn(mHintSession, static_cast(SessionHint::CPU_LOAD_UP)); +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h index fcbc10185255b..c0f7a57bed754 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.h +++ b/libs/hwui/renderthread/HintSessionWrapper.h @@ -33,6 +33,7 @@ public: void updateTargetWorkDuration(long targetDurationNanos); void reportActualWorkDuration(long actualDurationNanos); void sendLoadResetHint(); + void sendLoadIncreaseHint(); private: bool useHintSession(); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 07f5a78fc1ec9..04a6cbd1a5775 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -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()); diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index a21faa86ed0fe..1064225b69aed 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -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