diff options
author | 2022-10-21 22:13:23 +0000 | |
---|---|---|
committer | 2022-11-17 20:37:08 +0000 | |
commit | d98e8054f30fa9d140062281e6e5b89d57a5359e (patch) | |
tree | 68a70f0d9143ce3a99af515fe6697f8241b809b1 | |
parent | 5358d473cb0233492f8bba6b2e484d31c7089d88 (diff) |
Send HWUI load reset hint when Choreographer registers a callback
Send a load reset hint hint to DrawFrameTask through ThreadedRenderer
from ViewRootImpl whenever Choreographer registers a callback. This
allows the PowerHAL to allocate more resources for HWUI in response to
upcoming work, helping prevent frame drop.
Bug: b/243938267
Test: manual
Change-Id: Ie2cf809cf85530af04f4d0db3407853d4da03d62
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 7 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 10 | ||||
-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/DrawFrameTask.cpp | 22 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 1 |
8 files changed, 69 insertions, 0 deletions
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index d77e8825e462..164a49464051 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -587,6 +587,13 @@ public final class ThreadedRenderer extends HardwareRenderer { updateWebViewOverlayCallbacks(); } + @Override + public void notifyCallbackPending() { + if (isEnabled()) { + super.notifyCallbackPending(); + } + } + /** * 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 7e8ebd7fe076..a28a86acaf8d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2308,6 +2308,7 @@ public final class ViewRootImpl implements ViewParent, */ void notifyRendererOfFramePending() { if (mAttachInfo.mThreadedRenderer != null) { + mAttachInfo.mThreadedRenderer.notifyCallbackPending(); mAttachInfo.mThreadedRenderer.notifyFramePending(); } } @@ -9125,6 +9126,9 @@ public final class ViewRootImpl implements ViewParent, mConsumeBatchedInputScheduled = true; mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, mConsumedBatchedInputRunnable, null); + if (mAttachInfo.mThreadedRenderer != null) { + mAttachInfo.mThreadedRenderer.notifyCallbackPending(); + } } } @@ -9318,6 +9322,9 @@ public final class ViewRootImpl implements ViewParent, mViews.add(view); postIfNeededLocked(); } + if (mAttachInfo.mThreadedRenderer != null) { + mAttachInfo.mThreadedRenderer.notifyCallbackPending(); + } } public void addViewRect(AttachInfo.InvalidateInfo info) { @@ -9325,6 +9332,9 @@ public final class ViewRootImpl implements ViewParent, mViewRects.add(info); postIfNeededLocked(); } + if (mAttachInfo.mThreadedRenderer != null) { + mAttachInfo.mThreadedRenderer.notifyCallbackPending(); + } } public void removeView(View view) { diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 48dd3e6c451b..a7fb7428bc98 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -982,6 +982,15 @@ public class HardwareRenderer { } /** + * Notifies the hardware renderer about pending choreographer callbacks. + * + * @hide + */ + public void notifyCallbackPending() { + nNotifyCallbackPending(mNativeProxy); + } + + /** * b/68769804, b/66945974: For low FPS experiments. * * @hide @@ -1536,4 +1545,6 @@ public class HardwareRenderer { private static native boolean nIsDrawingEnabled(); private static native void nSetRtAnimationsEnabled(boolean rtAnimationsEnabled); + + private static native void nNotifyCallbackPending(long nativeProxy); } diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index f603e231e49b..0663121a4027 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -860,6 +860,11 @@ static void android_view_ThreadedRenderer_setRtAnimationsEnabled(JNIEnv* env, jo RenderProxy::setRtAnimationsEnabled(enabled); } +static void android_view_ThreadedRenderer_notifyCallbackPending(JNIEnv*, jclass, jlong proxyPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); + proxy->notifyCallbackPending(); +} + // Plumbs the display density down to DeviceInfo. static void android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv*, jclass, jint densityDpi) { // Convert from dpi to density-independent pixels. @@ -1037,6 +1042,8 @@ static const JNINativeMethod gMethods[] = { {"nIsDrawingEnabled", "()Z", (void*)android_view_ThreadedRenderer_isDrawingEnabled}, {"nSetRtAnimationsEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setRtAnimationsEnabled}, + {"nNotifyCallbackPending", "(J)V", + (void*)android_view_ThreadedRenderer_notifyCallbackPending}, }; static JavaVM* mJvm = nullptr; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index dc7676c08bd7..cb306144ffd6 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -42,6 +42,7 @@ typedef APerformanceHintSession* (*APH_createSession)(APerformanceHintManager*, size_t, int64_t); typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); +typedef void (*APH_sendHint)(APerformanceHintSession* session, int32_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); bool gAPerformanceHintBindingInitialized = false; @@ -49,6 +50,7 @@ APH_getManager gAPH_getManagerFn = nullptr; APH_createSession gAPH_createSessionFn = nullptr; APH_updateTargetWorkDuration gAPH_updateTargetWorkDurationFn = nullptr; APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr; +APH_sendHint gAPH_sendHintFn = nullptr; APH_closeSession gAPH_closeSessionFn = nullptr; void ensureAPerformanceHintBindingInitialized() { @@ -77,6 +79,10 @@ void ensureAPerformanceHintBindingInitialized() { gAPH_reportActualWorkDurationFn == nullptr, "Failed to find required symbol APerformanceHint_reportActualWorkDuration!"); + gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint"); + LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr, + "Failed to find required symbol APerformanceHint_sendHint!"); + gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSession"); LOG_ALWAYS_FATAL_IF(gAPH_closeSessionFn == nullptr, "Failed to find required symbol APerformanceHint_closeSession!"); @@ -239,6 +245,16 @@ void DrawFrameTask::run() { mLastDequeueBufferDuration = dequeueBufferDuration; } +void DrawFrameTask::sendLoadResetHint() { + if (!(Properties::useHintManager && Properties::isDrawingEnabled())) return; + if (!mHintSessionWrapper) mHintSessionWrapper.emplace(mUiThreadId, mRenderThreadId); + nsecs_t now = systemTime(); + if (now - mLastFrameNotification > kResetHintTimeout) { + mHintSessionWrapper->sendHint(SessionHint::CPU_LOAD_RESET); + } + mLastFrameNotification = now; +} + bool DrawFrameTask::syncFrameState(TreeInfo& info) { ATRACE_CALL(); int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)]; @@ -327,6 +343,12 @@ void DrawFrameTask::HintSessionWrapper::reportActualWorkDuration(long actualDura } } +void DrawFrameTask::HintSessionWrapper::sendHint(SessionHint hint) { + if (mHintSession && Properties::isDrawingEnabled()) { + gAPH_sendHintFn(mHintSession, static_cast<int>(hint)); + } +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index d6fc292d5900..7eae41c07e64 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -28,6 +28,7 @@ #include "../Rect.h" #include "../TreeInfo.h" #include "RenderTask.h" +#include "utils/TimeUtils.h" namespace android { namespace uirenderer { @@ -90,6 +91,8 @@ public: void forceDrawNextFrame() { mForceDrawFrame = true; } + void sendLoadResetHint(); + private: class HintSessionWrapper { public: @@ -98,6 +101,7 @@ private: void updateTargetWorkDuration(long targetDurationNanos); void reportActualWorkDuration(long actualDurationNanos); + void sendHint(SessionHint hint); private: APerformanceHintSession* mHintSession = nullptr; @@ -135,6 +139,9 @@ private: nsecs_t mLastTargetWorkDuration = 0; std::optional<HintSessionWrapper> mHintSessionWrapper; + nsecs_t mLastFrameNotification = 0; + nsecs_t kResetHintTimeout = 100_ms; + bool mForceDrawFrame = false; }; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 332471545f82..03a2bc9f7e51 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -236,6 +236,10 @@ void RenderProxy::notifyFramePending() { mRenderThread.queue().post([this]() { mContext->notifyFramePending(); }); } +void RenderProxy::notifyCallbackPending() { + mDrawFrameTask.sendLoadResetHint(); +} + 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 2a99a736180f..a21faa86ed0f 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -109,6 +109,7 @@ public: static int maxTextureSize(); void stopDrawing(); void notifyFramePending(); + void notifyCallbackPending(); void dumpProfileInfo(int fd, int dumpFlags); // Not exported, only used for testing |