summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Matt Buckley <mattbuckley@google.com> 2022-10-21 22:13:23 +0000
committer Matt Buckley <mattbuckley@google.com> 2022-11-17 20:37:08 +0000
commitd98e8054f30fa9d140062281e6e5b89d57a5359e (patch)
tree68a70f0d9143ce3a99af515fe6697f8241b809b1
parent5358d473cb0233492f8bba6b2e484d31c7089d88 (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.java7
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java11
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp7
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp22
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.h7
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp4
-rw-r--r--libs/hwui/renderthread/RenderProxy.h1
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