diff options
author | 2022-12-19 22:03:27 +0000 | |
---|---|---|
committer | 2023-01-03 20:40:02 +0000 | |
commit | ac5f755472e02f039f947ccfd5f5282e0ac80fe3 (patch) | |
tree | 295052e4c68b11a04e493c41f9dc5f9447853cfc | |
parent | effd5af692656644f07c0f818a85d2f84928cd68 (diff) |
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
-rw-r--r-- | core/java/android/view/LayoutInflater.java | 8 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 7 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 12 | ||||
-rw-r--r-- | graphics/java/android/graphics/HardwareRenderer.java | 11 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/HintSessionWrapper.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/renderthread/HintSessionWrapper.h | 1 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 1 |
11 files changed, 62 insertions, 0 deletions
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index df78827534a6..99a7fe598936 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 164a49464051..9c6e823b549e 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 ea7a64ef5c24..30e98a4e64f7 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 c7c97e0b82b9..0892a9b14738 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -992,6 +992,15 @@ public class HardwareRenderer { } /** + * Notifies the hardware renderer about upcoming expensive frames. + * + * @hide + */ + public void notifyExpensiveFrame() { + nNotifyExpensiveFrame(mNativeProxy); + } + + /** * b/68769804, b/66945974: For low FPS experiments. * * @hide @@ -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 0663121a4027..e457c311f689 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<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; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 64839d0147f8..b92c90edd1ca 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 e875c42e9eba..d29e12c38d9f 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 94c9d94a7c26..dece548e9dc1 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<int>(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 fcbc10185255..c0f7a57bed75 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 07f5a78fc1ec..04a6cbd1a577 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 a21faa86ed0f..1064225b69ae 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 |