Initial attempt at jank-tracking stat collection
Is a bit naive, perhaps overly aggressive, but sorta works
Change-Id: I01a774e00dbe681439c02557d9728ae43c45ce50
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index ad4a048..df0838f 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,8 +16,7 @@
package android.view;
-import com.android.internal.R;
-
+import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -27,16 +26,18 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.os.Trace;
import android.util.Log;
import android.util.LongSparseArray;
-import android.util.TimeUtils;
import android.view.Surface.OutOfResourcesException;
import android.view.View.AttachInfo;
+import com.android.internal.R;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashSet;
@@ -74,6 +75,14 @@
PROFILE_PROPERTY_VISUALIZE_BARS,
};
+ private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
+ private static final int FLAG_DUMP_RESET = 1 << 1;
+
+ @IntDef(flag = true, value = {
+ FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DumpFlags {}
+
// Size of the rendered content.
private int mWidth, mHeight;
@@ -93,12 +102,12 @@
private final float mLightRadius;
private final int mAmbientShadowAlpha;
private final int mSpotShadowAlpha;
+ private final float mDensity;
private long mNativeProxy;
private boolean mInitialized = false;
private RenderNode mRootNode;
private Choreographer mChoreographer;
- private boolean mProfilingEnabled;
private boolean mRootNodeNeedsUpdate;
ThreadedRenderer(Context context, boolean translucent) {
@@ -110,6 +119,7 @@
(int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
a.recycle();
+ mDensity = context.getResources().getDisplayMetrics().density;
long rootNodePtr = nCreateRootRenderNode();
mRootNode = RenderNode.adopt(rootNodePtr);
@@ -214,7 +224,7 @@
mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight,
lightX, mLightY, mLightZ, mLightRadius,
- mAmbientShadowAlpha, mSpotShadowAlpha);
+ mAmbientShadowAlpha, mSpotShadowAlpha, mDensity);
}
@Override
@@ -233,32 +243,25 @@
}
@Override
- void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
+ void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
pw.flush();
- nDumpProfileInfo(mNativeProxy, fd);
- }
-
- private static int search(String[] values, String value) {
- for (int i = 0; i < values.length; i++) {
- if (values[i].equals(value)) return i;
+ int flags = 0;
+ for (int i = 0; i < args.length; i++) {
+ switch (args[i]) {
+ case "framestats":
+ flags |= FLAG_DUMP_FRAMESTATS;
+ break;
+ case "reset":
+ flags |= FLAG_DUMP_RESET;
+ break;
+ }
}
- return -1;
- }
-
- private static boolean checkIfProfilingRequested() {
- String profiling = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
- int graphType = search(VISUALIZERS, profiling);
- return (graphType >= 0) || Boolean.parseBoolean(profiling);
+ nDumpProfileInfo(mNativeProxy, fd, flags);
}
@Override
boolean loadSystemProperties() {
boolean changed = nLoadSystemProperties(mNativeProxy);
- boolean wantProfiling = checkIfProfilingRequested();
- if (wantProfiling != mProfilingEnabled) {
- mProfilingEnabled = wantProfiling;
- changed = true;
- }
if (changed) {
invalidateRoot();
}
@@ -307,20 +310,12 @@
@Override
void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
attachInfo.mIgnoreDirtyState = true;
- long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
- long recordDuration = 0;
- if (mProfilingEnabled) {
- recordDuration = System.nanoTime();
- }
+ final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
+ choreographer.mFrameInfo.markDrawStart();
updateRootDisplayList(view, callbacks);
- if (mProfilingEnabled) {
- recordDuration = System.nanoTime() - recordDuration;
- }
-
attachInfo.mIgnoreDirtyState = false;
// register animating rendernodes which started animating prior to renderer
@@ -337,8 +332,8 @@
attachInfo.mPendingAnimatingRenderNodes = null;
}
- int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,
- recordDuration, view.getResources().getDisplayMetrics().density);
+ final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
+ int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
setEnabled(false);
attachInfo.mViewRootImpl.mSurface.release();
@@ -500,10 +495,9 @@
private static native boolean nPauseSurface(long nativeProxy, Surface window);
private static native void nSetup(long nativeProxy, int width, int height,
float lightX, float lightY, float lightZ, float lightRadius,
- int ambientShadowAlpha, int spotShadowAlpha);
+ int ambientShadowAlpha, int spotShadowAlpha, float density);
private static native void nSetOpaque(long nativeProxy, boolean opaque);
- private static native int nSyncAndDrawFrame(long nativeProxy,
- long frameTimeNanos, long recordDuration, float density);
+ private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy);
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
@@ -523,5 +517,6 @@
private static native void nStopDrawing(long nativeProxy);
private static native void nNotifyFramePending(long nativeProxy);
- private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd);
+ private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
+ @DumpFlags int dumpFlags);
}