summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Marcin Oczeretko <marcinoc@google.com> 2023-07-04 14:56:47 +0000
committer Marcin Oczeretko <marcinoc@google.com> 2023-07-20 12:48:32 +0000
commit695483c7ebd0f05a269ce8e194bb33c1515b9635 (patch)
tree49aeee80d82f6db2dfcdb065af5f396ce86392fb
parent24008f68a4bacb7460d9d7d519f04399b8eb5111 (diff)
Reduce memory churn from main thread looper tracing
Implement getTraceName() on two top Handlers on the main thread Looper to avoid calls to getClass().getName() Also avoids posting to main thread handler from the same thread in FrameTracker callback Bug: 285737625 Test: Manual - collect a trace and confirm main thread slice names Change-Id: I7dbbd7702e339e8cf3e7c42d4df3762250e5aca5
-rw-r--r--core/java/android/view/Choreographer.java11
-rw-r--r--core/java/android/view/ViewRootImpl.java9
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java50
3 files changed, 44 insertions, 26 deletions
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index d80001def875..eeb86e99d1b3 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -34,6 +34,7 @@ import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
+import android.os.TraceNameSupplier;
import android.util.Log;
import android.util.TimeUtils;
import android.view.animation.AnimationUtils;
@@ -1300,7 +1301,7 @@ public final class Choreographer {
}
private final class FrameDisplayEventReceiver extends DisplayEventReceiver
- implements Runnable {
+ implements Runnable, TraceNameSupplier {
private boolean mHavePendingVsync;
private long mTimestampNanos;
private int mFrame;
@@ -1358,6 +1359,14 @@ public final class Choreographer {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
}
+
+ @androidx.annotation.NonNull
+ @Override
+ public String getTraceName() {
+ // Returning just a simple name.
+ // More detailed logging happens in onVsync() for TRACE_TAG_VIEW.
+ return "FrameDisplayEventReceiver";
+ }
}
private static final class CallbackRecord {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fe25fd20a5b9..6c0059635834 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5787,6 +5787,15 @@ public final class ViewRootImpl implements ViewParent,
private static final int MSG_PAUSED_FOR_SYNC_TIMEOUT = 37;
final class ViewRootHandler extends Handler {
+ @androidx.annotation.NonNull
+ @Override
+ public String getTraceName(@androidx.annotation.NonNull Message message) {
+ if (message.getCallback() == null) {
+ return getMessageName(message);
+ }
+ return super.getTraceName(message);
+ }
+
@Override
public String getMessageName(Message message) {
switch (message.what) {
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 506f19f7719a..b53be9aceebf 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -502,35 +502,35 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
return vsyncId >= mBeginVsyncId;
}
+ // This will be executed in the HardwareRendererObserver handler, which is the FrameTracker
+ // handler by construction.
@Override
public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) {
- postCallback(() -> {
- if (mCancelled || mMetricsFinalized) {
- return;
- }
+ if (mCancelled || mMetricsFinalized) {
+ return;
+ }
- // Since this callback might come a little bit late after the end() call.
- // We should keep tracking the begin / end timestamp that we can compare with
- // vsync timestamp to check if the frame is in the duration of the CUJ.
- long totalDurationNanos = mMetricsWrapper.getMetric(FrameMetrics.TOTAL_DURATION);
- boolean isFirstFrame = mMetricsWrapper.getMetric(FrameMetrics.FIRST_DRAW_FRAME) == 1;
- long frameVsyncId =
- mMetricsWrapper.getTiming()[FrameMetrics.Index.FRAME_TIMELINE_VSYNC_ID];
+ // Since this callback might come a little bit late after the end() call.
+ // We should keep tracking the begin / end timestamp that we can compare with
+ // vsync timestamp to check if the frame is in the duration of the CUJ.
+ long totalDurationNanos = mMetricsWrapper.getMetric(FrameMetrics.TOTAL_DURATION);
+ boolean isFirstFrame = mMetricsWrapper.getMetric(FrameMetrics.FIRST_DRAW_FRAME) == 1;
+ long frameVsyncId =
+ mMetricsWrapper.getTiming()[FrameMetrics.Index.FRAME_TIMELINE_VSYNC_ID];
- if (!isInRange(frameVsyncId)) {
- return;
- }
- JankInfo info = findJankInfo(frameVsyncId);
- if (info != null) {
- info.hwuiCallbackFired = true;
- info.totalDurationNanos = totalDurationNanos;
- info.isFirstFrame = isFirstFrame;
- } else {
- mJankInfos.put((int) frameVsyncId, JankInfo.createFromHwuiCallback(
- frameVsyncId, totalDurationNanos, isFirstFrame));
- }
- processJankInfos();
- });
+ if (!isInRange(frameVsyncId)) {
+ return;
+ }
+ JankInfo info = findJankInfo(frameVsyncId);
+ if (info != null) {
+ info.hwuiCallbackFired = true;
+ info.totalDurationNanos = totalDurationNanos;
+ info.isFirstFrame = isFirstFrame;
+ } else {
+ mJankInfos.put((int) frameVsyncId, JankInfo.createFromHwuiCallback(
+ frameVsyncId, totalDurationNanos, isFirstFrame));
+ }
+ processJankInfos();
}
@UiThread