diff options
-rw-r--r-- | api/current.txt | 21 | ||||
-rw-r--r-- | api/system-current.txt | 21 | ||||
-rw-r--r-- | api/test-current.txt | 21 | ||||
-rw-r--r-- | core/java/android/view/FrameMetrics.java | 281 | ||||
-rw-r--r-- | core/java/android/view/FrameMetricsObserver.java | 75 | ||||
-rw-r--r-- | core/java/android/view/FrameStatsObserver.java | 122 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 34 | ||||
-rw-r--r-- | core/java/android/view/View.java | 61 | ||||
-rw-r--r-- | core/java/android/view/Window.java | 48 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 127 | ||||
-rw-r--r-- | libs/hwui/FrameMetricsObserver.h (renamed from libs/hwui/FrameStatsObserver.h) | 4 | ||||
-rw-r--r-- | libs/hwui/FrameMetricsReporter.h (renamed from libs/hwui/FrameStatsReporter.h) | 17 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 26 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 30 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 6 |
16 files changed, 614 insertions, 284 deletions
diff --git a/api/current.txt b/api/current.txt index ae343cdc5e8b..c1e1d7d720f8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -40660,6 +40660,21 @@ package android.view { method public static android.view.FocusFinder getInstance(); } + public final class FrameMetrics { + ctor public FrameMetrics(android.view.FrameMetrics); + method public long getMetric(int); + field public static final int ANIMATION_DURATION = 2; // 0x2 + field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6 + field public static final int DRAW_DURATION = 4; // 0x4 + field public static final int FIRST_DRAW_FRAME = 9; // 0x9 + field public static final int INPUT_HANDLING_DURATION = 1; // 0x1 + field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3 + field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7 + field public static final int SYNC_DURATION = 5; // 0x5 + field public static final int TOTAL_DURATION = 8; // 0x8 + field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0 + } + public abstract class FrameStats { ctor public FrameStats(); method public final long getEndTimeNano(); @@ -43163,6 +43178,7 @@ package android.view { ctor public Window(android.content.Context); method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void addFlags(int); + method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler); method public void clearFlags(int); method public abstract void closeAllPanels(); method public abstract void closePanel(int); @@ -43214,6 +43230,7 @@ package android.view { method public abstract boolean performContextMenuIdentifierAction(int, int); method public abstract boolean performPanelIdentifierAction(int, int, int); method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int); + method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener); method public boolean requestFeature(int); method public abstract void restoreHierarchyState(android.os.Bundle); method public abstract android.os.Bundle saveHierarchyState(); @@ -43339,6 +43356,10 @@ package android.view { method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int); } + public static abstract interface Window.FrameMetricsListener { + method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int); + } + public static abstract interface Window.OnRestrictedCaptionAreaChangedListener { method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect); } diff --git a/api/system-current.txt b/api/system-current.txt index bcd39fe3272e..51128263e56f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -43339,6 +43339,21 @@ package android.view { method public static android.view.FocusFinder getInstance(); } + public final class FrameMetrics { + ctor public FrameMetrics(android.view.FrameMetrics); + method public long getMetric(int); + field public static final int ANIMATION_DURATION = 2; // 0x2 + field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6 + field public static final int DRAW_DURATION = 4; // 0x4 + field public static final int FIRST_DRAW_FRAME = 9; // 0x9 + field public static final int INPUT_HANDLING_DURATION = 1; // 0x1 + field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3 + field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7 + field public static final int SYNC_DURATION = 5; // 0x5 + field public static final int TOTAL_DURATION = 8; // 0x8 + field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0 + } + public abstract class FrameStats { ctor public FrameStats(); method public final long getEndTimeNano(); @@ -45842,6 +45857,7 @@ package android.view { ctor public Window(android.content.Context); method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void addFlags(int); + method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler); method public void clearFlags(int); method public abstract void closeAllPanels(); method public abstract void closePanel(int); @@ -45893,6 +45909,7 @@ package android.view { method public abstract boolean performContextMenuIdentifierAction(int, int); method public abstract boolean performPanelIdentifierAction(int, int, int); method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int); + method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener); method public boolean requestFeature(int); method public abstract void restoreHierarchyState(android.os.Bundle); method public abstract android.os.Bundle saveHierarchyState(); @@ -46019,6 +46036,10 @@ package android.view { method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int); } + public static abstract interface Window.FrameMetricsListener { + method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int); + } + public static abstract interface Window.OnRestrictedCaptionAreaChangedListener { method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect); } diff --git a/api/test-current.txt b/api/test-current.txt index c1cd2750424e..c52c56fe7eba 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -40677,6 +40677,21 @@ package android.view { method public static android.view.FocusFinder getInstance(); } + public final class FrameMetrics { + ctor public FrameMetrics(android.view.FrameMetrics); + method public long getMetric(int); + field public static final int ANIMATION_DURATION = 2; // 0x2 + field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6 + field public static final int DRAW_DURATION = 4; // 0x4 + field public static final int FIRST_DRAW_FRAME = 9; // 0x9 + field public static final int INPUT_HANDLING_DURATION = 1; // 0x1 + field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3 + field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7 + field public static final int SYNC_DURATION = 5; // 0x5 + field public static final int TOTAL_DURATION = 8; // 0x8 + field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0 + } + public abstract class FrameStats { ctor public FrameStats(); method public final long getEndTimeNano(); @@ -43180,6 +43195,7 @@ package android.view { ctor public Window(android.content.Context); method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void addFlags(int); + method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler); method public void clearFlags(int); method public abstract void closeAllPanels(); method public abstract void closePanel(int); @@ -43231,6 +43247,7 @@ package android.view { method public abstract boolean performContextMenuIdentifierAction(int, int); method public abstract boolean performPanelIdentifierAction(int, int, int); method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int); + method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener); method public boolean requestFeature(int); method public abstract void restoreHierarchyState(android.os.Bundle); method public abstract android.os.Bundle saveHierarchyState(); @@ -43356,6 +43373,10 @@ package android.view { method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int); } + public static abstract interface Window.FrameMetricsListener { + method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int); + } + public static abstract interface Window.OnRestrictedCaptionAreaChangedListener { method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect); } diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java new file mode 100644 index 000000000000..8e66f86f421e --- /dev/null +++ b/core/java/android/view/FrameMetrics.java @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.annotation.IntDef; +import android.view.Window; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Class containing timing data for various milestones in a frame + * lifecycle reported by the rendering subsystem. + * <p> + * Supported metrics can be queried via their corresponding identifier. + * </p> + */ +public final class FrameMetrics { + + /** + * Metric identifier for unknown delay. + * <p> + * Represents the number of nanoseconds elapsed waiting for the + * UI thread to become responsive and process the frame. This + * should be 0 most of the time. + * </p> + */ + public static final int UNKNOWN_DELAY_DURATION = 0; + + /** + * Metric identifier for input handling duration. + * <p> + * Represents the number of nanoseconds elapsed issuing + * input handling callbacks. + * </p> + */ + public static final int INPUT_HANDLING_DURATION = 1; + + /** + * Metric identifier for animation callback duration. + * <p> + * Represents the number of nanoseconds elapsed issuing + * animation callbacks. + * </p> + */ + public static final int ANIMATION_DURATION = 2; + + /** + * Metric identifier for layout/measure duration. + * <p> + * Represents the number of nanoseconds elapsed measuring + * and laying out the invalidated pieces of the view hierarchy. + * </p> + */ + public static final int LAYOUT_MEASURE_DURATION = 3; + /** + * Metric identifier for draw duration. + * <p> + * Represents the number of nanoseconds elapsed computing + * DisplayLists for transformations applied to the view + * hierarchy. + * </p> + */ + public static final int DRAW_DURATION = 4; + + /** + * Metric identifier for sync duration. + * <p> + * Represents the number of nanoseconds elapsed + * synchronizing the computed display lists with the render + * thread. + * </p> + */ + public static final int SYNC_DURATION = 5; + + /** + * Metric identifier for command issue duration. + * <p> + * Represents the number of nanoseconds elapsed + * issuing draw commands to the GPU. + * </p> + */ + public static final int COMMAND_ISSUE_DURATION = 6; + + /** + * Metric identifier for swap buffers duration. + * <p> + * Represents the number of nanoseconds elapsed issuing + * the frame buffer for this frame to the display + * subsystem. + * </p> + */ + public static final int SWAP_BUFFERS_DURATION = 7; + + /** + * Metric identifier for total frame duration. + * <p> + * Represents the total time in nanoseconds this frame took to render + * and be issued to the display subsystem. + * </p> + * <p> + * Equal to the sum of the values of all other time-valued metric + * identifiers. + * </p> + */ + public static final int TOTAL_DURATION = 8; + + /** + * Metric identifier for a boolean value determining whether this frame was + * the first to draw in a new Window layout. + * <p> + * {@link #getMetric(int)} will return 0 for false, 1 for true. + * </p> + * <p> + * First draw frames are expected to be slow and should usually be exempt + * from display jank calculations as they do not cause skips in animations + * and are usually hidden by window animations or other tricks. + * </p> + */ + public static final int FIRST_DRAW_FRAME = 9; + + private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0; + + /** + * Identifiers for metrics available for each frame. + * + * {@see {@link #getMetric(int)}} + * @hide + */ + @IntDef({ + UNKNOWN_DELAY_DURATION, + INPUT_HANDLING_DURATION, + ANIMATION_DURATION, + LAYOUT_MEASURE_DURATION, + DRAW_DURATION, + SYNC_DURATION, + COMMAND_ISSUE_DURATION, + SWAP_BUFFERS_DURATION, + TOTAL_DURATION, + FIRST_DRAW_FRAME, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Metric {} + + /** + * Timestamp indices for frame milestones. + * + * May change from release to release. + * + * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h. + * + * @hide + */ + @IntDef ({ + Index.FLAGS, + Index.INTENDED_VSYNC, + Index.VSYNC, + Index.OLDEST_INPUT_EVENT, + Index.NEWEST_INPUT_EVENT, + Index.HANDLE_INPUT_START, + Index.ANIMATION_START, + Index.PERFORM_TRAVERSALS_START, + Index.DRAW_START, + Index.SYNC_QUEUED, + Index.SYNC_START, + Index.ISSUE_DRAW_COMMANDS_START, + Index.SWAP_BUFFERS, + Index.FRAME_COMPLETED, + }) + @Retention(RetentionPolicy.SOURCE) + private @interface Index { + int FLAGS = 0; + int INTENDED_VSYNC = 1; + int VSYNC = 2; + int OLDEST_INPUT_EVENT = 3; + int NEWEST_INPUT_EVENT = 4; + int HANDLE_INPUT_START = 5; + int ANIMATION_START = 6; + int PERFORM_TRAVERSALS_START = 7; + int DRAW_START = 8; + int SYNC_QUEUED = 9; + int SYNC_START = 10; + int ISSUE_DRAW_COMMANDS_START = 11; + int SWAP_BUFFERS = 12; + int FRAME_COMPLETED = 13; + + int FRAME_STATS_COUNT = 14; // must always be last + } + + /* + * Bucket endpoints for each Metric defined above. + * + * Each defined metric *must* have a corresponding entry + * in this list. + */ + private static final int[] DURATIONS = new int[] { + // UNKNOWN_DELAY + Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START, + // INPUT_HANDLING + Index.HANDLE_INPUT_START, Index.ANIMATION_START, + // ANIMATION + Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START, + // LAYOUT_MEASURE + Index.PERFORM_TRAVERSALS_START, Index.DRAW_START, + // DRAW + Index.DRAW_START, Index.SYNC_QUEUED, + // SYNC + Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START, + // COMMAND_ISSUE + Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS, + // SWAP_BUFFERS + Index.SWAP_BUFFERS, Index.FRAME_COMPLETED, + // TOTAL_DURATION + Index.INTENDED_VSYNC, Index.FRAME_COMPLETED, + }; + + /* package */ final long[] mTimingData; + + /** + * Constructs a FrameMetrics object as a copy. + * <p> + * Use this method to copy out metrics reported by + * {@link Window.FrameMetricsListener#onMetricsAvailable(Window, FrameMetrics, int)} + * </p> + * @param other the FrameMetrics object to copy. + */ + public FrameMetrics(FrameMetrics other) { + mTimingData = new long[Index.FRAME_STATS_COUNT]; + System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length); + } + + /** + * @hide + */ + FrameMetrics() { + mTimingData = new long[Index.FRAME_STATS_COUNT]; + } + + /** + * Retrieves the value associated with Metric identifier {@code id} + * for this frame. + * <p> + * Boolean metrics are represented in [0,1], with 0 corresponding to + * false, and 1 corresponding to true. + * </p> + * @param id the metric to retrieve + * @return the value of the metric or -1 if it is not available. + */ + public long getMetric(@Metric int id) { + if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) { + return -1; + } + + if (mTimingData == null) { + return -1; + } + + if (id == FIRST_DRAW_FRAME) { + return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0; + } + + int durationsIdx = 2 * id; + return mTimingData[DURATIONS[durationsIdx + 1]] + - mTimingData[DURATIONS[durationsIdx]]; + } +} + diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java new file mode 100644 index 000000000000..f38f8b76a191 --- /dev/null +++ b/core/java/android/view/FrameMetricsObserver.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.annotation.NonNull; +import android.util.Log; +import android.os.Looper; +import android.os.MessageQueue; + +import com.android.internal.util.VirtualRefBasePtr; + +import java.lang.NullPointerException; +import java.lang.ref.WeakReference; +import java.lang.SuppressWarnings; + +/** + * Provides streaming access to frame stats information from the rendering + * subsystem to apps. + * + * @hide + */ +public class FrameMetricsObserver { + private MessageQueue mMessageQueue; + + private WeakReference<Window> mWindow; + + private FrameMetrics mFrameMetrics; + + /* package */ Window.FrameMetricsListener mListener; + /* package */ VirtualRefBasePtr mNative; + + /** + * Creates a FrameMetricsObserver + * + * @param looper the looper to use when invoking callbacks + */ + FrameMetricsObserver(@NonNull Window window, @NonNull Looper looper, + @NonNull Window.FrameMetricsListener listener) { + if (looper == null) { + throw new NullPointerException("looper cannot be null"); + } + + mMessageQueue = looper.getQueue(); + if (mMessageQueue == null) { + throw new IllegalStateException("invalid looper, null message queue\n"); + } + + mFrameMetrics = new FrameMetrics(); + mWindow = new WeakReference<>(window); + mListener = listener; + } + + // Called by native on the provided Handler + @SuppressWarnings("unused") + private void notifyDataAvailable(int dropCount) { + final Window window = mWindow.get(); + if (window != null) { + mListener.onMetricsAvailable(window, mFrameMetrics, dropCount); + } + } +} diff --git a/core/java/android/view/FrameStatsObserver.java b/core/java/android/view/FrameStatsObserver.java deleted file mode 100644 index 0add6072e827..000000000000 --- a/core/java/android/view/FrameStatsObserver.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view; - -import android.annotation.NonNull; -import android.util.Log; -import android.os.Looper; -import android.os.MessageQueue; - -import com.android.internal.util.VirtualRefBasePtr; - -import java.lang.NullPointerException; -import java.lang.ref.WeakReference; -import java.lang.SuppressWarnings; - -/** - * Provides streaming access to frame stats information from the rendering - * subsystem to apps. - * - * @hide - */ -public abstract class FrameStatsObserver { - private static final String TAG = "FrameStatsObserver"; - - private MessageQueue mMessageQueue; - private long[] mBuffer; - - private FrameStats mFrameStats; - - /* package */ ThreadedRenderer mRenderer; - /* package */ VirtualRefBasePtr mNative; - - /** - * Containing class for frame statistics reported - * by the rendering subsystem. - */ - public static class FrameStats { - /** - * Precise timing data for various milestones in a frame - * lifecycle. - * - * This data is exactly the same as what is returned by - * `adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats` - * - * The fields reported may change from release to release. - * - * @see {@link http://developer.android.com/training/testing/performance.html} - * for a description of the fields present. - */ - public long[] mTimingData; - } - - /** - * Creates a FrameStatsObserver - * - * @param looper the looper to use when invoking callbacks - */ - public FrameStatsObserver(@NonNull Looper looper) { - if (looper == null) { - throw new NullPointerException("looper cannot be null"); - } - - mMessageQueue = looper.getQueue(); - if (mMessageQueue == null) { - throw new IllegalStateException("invalid looper, null message queue\n"); - } - - mFrameStats = new FrameStats(); - } - - /** - * Called on provided looper when frame stats data is available - * for the previous frame. - * - * Clients of this class must do as little work as possible within - * this callback, as the buffer is shared between the producer and consumer. - * - * If the consumer is still executing within this method when there is new - * data available that data will be dropped. The producer cannot - * wait on the consumer. - * - * @param data the newly available data - */ - public abstract void onDataAvailable(FrameStats data); - - /** - * Returns the number of reports dropped as a result of a slow - * consumer. - */ - public long getDroppedReportCount() { - if (mRenderer == null) { - return 0; - } - - return mRenderer.getDroppedFrameReportCount(); - } - - public boolean isRegistered() { - return mRenderer != null && mNative != null; - } - - // === called by native === // - @SuppressWarnings("unused") - private void notifyDataAvailable() { - mFrameStats.mTimingData = mBuffer; - onDataAvailable(mFrameStats); - } -} diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 8b06ecf3bc8b..ca41d7867feb 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -354,8 +354,6 @@ public final class ThreadedRenderer { private boolean mEnabled; private boolean mRequested = true; - private HashSet<FrameStatsObserver> mFrameStatsObservers; - ThreadedRenderer(Context context, boolean translucent) { final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0); mLightY = a.getDimension(R.styleable.Lighting_lightY, 0); @@ -964,29 +962,14 @@ public final class ThreadedRenderer { } } - void addFrameStatsObserver(FrameStatsObserver fso) { - if (mFrameStatsObservers == null) { - mFrameStatsObservers = new HashSet<>(); - } - - long nativeFso = nAddFrameStatsObserver(mNativeProxy, fso); - fso.mRenderer = this; - fso.mNative = new VirtualRefBasePtr(nativeFso); - mFrameStatsObservers.add(fso); - } - - void removeFrameStatsObserver(FrameStatsObserver fso) { - if (!mFrameStatsObservers.remove(fso)) { - throw new IllegalArgumentException("attempt to remove FrameStatsObserver that was never added"); - } - - nRemoveFrameStatsObserver(mNativeProxy, fso.mNative.get()); - fso.mRenderer = null; - fso.mNative = null; + void addFrameMetricsObserver(FrameMetricsObserver observer) { + long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer); + observer.mNative = new VirtualRefBasePtr(nativeObserver); } - long getDroppedFrameReportCount() { - return nGetDroppedFrameReportCount(mNativeProxy); + void removeFrameMetricsObserver(FrameMetricsObserver observer) { + nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get()); + observer.mNative = null; } static native void setupShadersDiskCache(String cacheFile); @@ -1044,7 +1027,6 @@ public final class ThreadedRenderer { private static native void nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom); - private static native long nAddFrameStatsObserver(long nativeProxy, FrameStatsObserver fso); - private static native void nRemoveFrameStatsObserver(long nativeProxy, long nativeFso); - private static native long nGetDroppedFrameReportCount(long nativeProxy); + private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer); + private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 127157b11a91..c41618c42a26 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3703,9 +3703,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private ViewPropertyAnimator mAnimator = null; /** - * List of FrameStatsObservers pending registration when mAttachInfo is null. + * List of registered FrameMetricsObservers. */ - private ArrayList<FrameStatsObserver> mPendingFrameStatsObservers; + private ArrayList<FrameMetricsObserver> mFrameMetricsObservers; /** * Flag indicating that a drag can cross window boundaries. When @@ -5479,19 +5479,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - public void addFrameStatsObserver(FrameStatsObserver fso) { + public void addFrameMetricsListener(Window window, Window.FrameMetricsListener listener, + Handler handler) { if (mAttachInfo != null) { if (mAttachInfo.mHardwareRenderer != null) { - mAttachInfo.mHardwareRenderer.addFrameStatsObserver(fso); + if (mFrameMetricsObservers == null) { + mFrameMetricsObservers = new ArrayList<>(); + } + + FrameMetricsObserver fmo = new FrameMetricsObserver(window, + handler.getLooper(), listener); + mFrameMetricsObservers.add(fmo); + mAttachInfo.mHardwareRenderer.addFrameMetricsObserver(fmo); } else { Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats"); } } else { - if (mPendingFrameStatsObservers == null) { - mPendingFrameStatsObservers = new ArrayList<>(); + if (mFrameMetricsObservers == null) { + mFrameMetricsObservers = new ArrayList<>(); } - mPendingFrameStatsObservers.add(fso); + FrameMetricsObserver fmo = new FrameMetricsObserver(window, + handler.getLooper(), listener); + mFrameMetricsObservers.add(fmo); } } @@ -5500,32 +5510,45 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - public void removeFrameStatsObserver(FrameStatsObserver fso) { + public void removeFrameMetricsListener(Window.FrameMetricsListener listener) { ThreadedRenderer renderer = getHardwareRenderer(); - - if (mPendingFrameStatsObservers != null) { - mPendingFrameStatsObservers.remove(fso); + FrameMetricsObserver fmo = findFrameMetricsObserver(listener); + if (fmo == null) { + throw new IllegalArgumentException("attempt to remove FrameMetricsListener that was never added"); } - if (renderer != null) { - renderer.removeFrameStatsObserver(fso); + if (mFrameMetricsObservers != null) { + mFrameMetricsObservers.remove(fmo); + if (renderer != null) { + renderer.removeFrameMetricsObserver(fmo); + } } } - private void registerPendingFrameStatsObservers() { - if (mPendingFrameStatsObservers != null) { + private void registerPendingFrameMetricsObservers() { + if (mFrameMetricsObservers != null) { ThreadedRenderer renderer = getHardwareRenderer(); if (renderer != null) { - for (FrameStatsObserver fso : mPendingFrameStatsObservers) { - renderer.addFrameStatsObserver(fso); + for (FrameMetricsObserver fmo : mFrameMetricsObservers) { + renderer.addFrameMetricsObserver(fmo); } } else { Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats"); } - mPendingFrameStatsObservers = null; } } + private FrameMetricsObserver findFrameMetricsObserver(Window.FrameMetricsListener listener) { + for (int i = 0; i < mFrameMetricsObservers.size(); i++) { + FrameMetricsObserver observer = mFrameMetricsObservers.get(i); + if (observer.mListener == listener) { + return observer; + } + } + + return null; + } + /** * Call this view's OnClickListener, if it is defined. Performs all normal * actions associated with clicking: reporting accessibility event, playing @@ -15160,7 +15183,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mFloatingTreeObserver = null; } - registerPendingFrameStatsObservers(); + registerPendingFrameMetricsObservers(); if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) { mAttachInfo.mScrollContainers.add(this); diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index c68a740b29a5..9f05990fd781 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable; import android.media.session.MediaController; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; @@ -604,6 +605,34 @@ public abstract class Window { void onRestrictedCaptionAreaChanged(Rect rect); } + /** + * Callback for clients that want frame timing information for each + * frame rendered by the Window. + */ + public interface FrameMetricsListener { + /** + * Called when information is available for the previously rendered frame. + * + * Reports can be dropped if this callback takes too + * long to execute, as the report producer cannot wait for the consumer to + * complete. + * + * It is highly recommended that clients copy the passed in FrameMetrics + * via {@link FrameMetrics#FrameMetrics(FrameMetrics)} within this method and defer + * additional computation or storage to another thread to avoid unnecessarily + * dropping reports. + * + * @param window The {@link Window} on which the frame was displayed. + * @param frameMetrics the available metrics. This object is reused on every call + * and thus <strong>this reference is not valid outside the scope of this method</strong>. + * @param dropCountSinceLastInvocation the number of reports dropped since the last time + * this callback was invoked. + */ + void onMetricsAvailable(Window window, FrameMetrics frameMetrics, + int dropCountSinceLastInvocation); + } + + public Window(Context context) { mContext = context; mFeatures = mLocalFeatures = getDefaultFeatures(context); @@ -798,33 +827,28 @@ public abstract class Window { * Set an observer to collect frame stats for each frame rendererd in this window. * * Must be in hardware rendering mode. - * @hide */ - public final void addFrameStatsObserver(@NonNull FrameStatsObserver fso) { + public final void addFrameMetricsListener(@NonNull FrameMetricsListener listener, + Handler handler) { final View decorView = getDecorView(); if (decorView == null) { throw new IllegalStateException("can't observe a Window without an attached view"); } - if (fso == null) { - throw new NullPointerException("FrameStatsObserver cannot be null"); + if (listener == null) { + throw new NullPointerException("listener cannot be null"); } - if (fso.isRegistered()) { - throw new IllegalStateException("FrameStatsObserver already registered on a Window."); - } - - decorView.addFrameStatsObserver(fso); + decorView.addFrameMetricsListener(this, listener, handler); } /** * Remove observer and stop listening to frame stats for this window. - * @hide */ - public final void removeFrameStatsObserver(FrameStatsObserver fso) { + public final void removeFrameMetricsListener(FrameMetricsListener listener) { final View decorView = getDecorView(); if (decorView != null) { - getDecorView().removeFrameStatsObserver(fso); + getDecorView().removeFrameMetricsListener(listener); } } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index acd0501362b5..dd0e45636ee7 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -41,6 +41,7 @@ #include <Animator.h> #include <AnimationContext.h> #include <FrameInfo.h> +#include <FrameMetricsObserver.h> #include <IContextFactory.h> #include <JankTracker.h> #include <RenderNode.h> @@ -56,10 +57,11 @@ using namespace android::uirenderer; using namespace android::uirenderer::renderthread; struct { - jfieldID buffer; + jfieldID frameMetrics; + jfieldID timingDataBuffer; jfieldID messageQueue; - jmethodID notifyData; -} gFrameStatsObserverClassInfo; + jmethodID callback; +} gFrameMetricsObserverClassInfo; static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; @@ -239,31 +241,46 @@ public: mBuffer = buffer; } + void setDropCount(int dropCount) { + mDropCount = dropCount; + } + virtual void handleMessage(const Message& message); private: JavaVM* mVm; sp<ObserverProxy> mObserver; - BufferPool::Buffer* mBuffer; + BufferPool::Buffer* mBuffer = nullptr; + int mDropCount = 0; }; -class ObserverProxy : public FrameStatsObserver { +static jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) { + jobject frameMetrics = env->GetObjectField( + observer, gFrameMetricsObserverClassInfo.frameMetrics); + LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object"); + jobject buffer = env->GetObjectField( + frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer); + LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer"); + return reinterpret_cast<jlongArray>(buffer); +} + +class ObserverProxy : public FrameMetricsObserver { public: - ObserverProxy(JavaVM *vm, jobject fso) : mVm(vm) { + ObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) { JNIEnv* env = getenv(mVm); - jlongArray longArrayLocal = env->NewLongArray(kBufferSize); - LOG_ALWAYS_FATAL_IF(longArrayLocal == nullptr, - "OOM: can't allocate frame stats buffer"); - env->SetObjectField(fso, gFrameStatsObserverClassInfo.buffer, longArrayLocal); - - mFsoWeak = env->NewWeakGlobalRef(fso); - LOG_ALWAYS_FATAL_IF(mFsoWeak == nullptr, + mObserverWeak = env->NewWeakGlobalRef(observer); + LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr, "unable to create frame stats observer reference"); - jobject messageQueueLocal = - env->GetObjectField(fso, gFrameStatsObserverClassInfo.messageQueue); + jlongArray buffer = get_metrics_buffer(env, observer); + jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer)); + LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize, + "Mismatched Java/Native FrameMetrics data format."); + + jobject messageQueueLocal = env->GetObjectField( + observer, gFrameMetricsObserverClassInfo.messageQueue); mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal); LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available"); @@ -274,17 +291,18 @@ public: ~ObserverProxy() { JNIEnv* env = getenv(mVm); - env->DeleteWeakGlobalRef(mFsoWeak); + env->DeleteWeakGlobalRef(mObserverWeak); } - jweak getJavaObjectRef() { - return mFsoWeak; + jweak getObserverReference() { + return mObserverWeak; } - virtual void notify(BufferPool::Buffer* buffer) { + virtual void notify(BufferPool::Buffer* buffer, int dropCount) { buffer->incRef(); mMessageHandler->setBuffer(buffer); mMessageHandler->setObserver(this); + mMessageHandler->setDropCount(dropCount); mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage); } @@ -292,26 +310,27 @@ private: static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes); JavaVM* mVm; - jweak mFsoWeak; + jweak mObserverWeak; + jobject mJavaBufferGlobal; sp<MessageQueue> mMessageQueue; sp<NotifyHandler> mMessageHandler; Message mMessage; + }; void NotifyHandler::handleMessage(const Message& message) { JNIEnv* env = getenv(mVm); - jobject target = env->NewLocalRef(mObserver->getJavaObjectRef()); + jobject target = env->NewLocalRef(mObserver->getObserverReference()); if (target != nullptr) { - jobject javaBuffer = env->GetObjectField(target, gFrameStatsObserverClassInfo.buffer); - if (javaBuffer != nullptr) { - env->SetLongArrayRegion(reinterpret_cast<jlongArray>(javaBuffer), - 0, mBuffer->getSize(), mBuffer->getBuffer()); - env->CallVoidMethod(target, gFrameStatsObserverClassInfo.notifyData); - env->DeleteLocalRef(target); - } + jlongArray javaBuffer = get_metrics_buffer(env, target); + env->SetLongArrayRegion(javaBuffer, + 0, mBuffer->getSize(), mBuffer->getBuffer()); + env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, + mDropCount); + env->DeleteLocalRef(target); } mBuffer->release(); @@ -579,10 +598,10 @@ static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env, } // ---------------------------------------------------------------------------- -// FrameStatsObserver +// FrameMetricsObserver // ---------------------------------------------------------------------------- -static jlong android_view_ThreadedRenderer_addFrameStatsObserver(JNIEnv* env, +static jlong android_view_ThreadedRenderer_addFrameMetricsObserver(JNIEnv* env, jclass clazz, jlong proxyPtr, jobject fso) { JavaVM* vm = nullptr; if (env->GetJavaVM(&vm) != JNI_OK) { @@ -593,25 +612,18 @@ static jlong android_view_ThreadedRenderer_addFrameStatsObserver(JNIEnv* env, renderthread::RenderProxy* renderProxy = reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); - FrameStatsObserver* observer = new ObserverProxy(vm, fso); - renderProxy->addFrameStatsObserver(observer); + FrameMetricsObserver* observer = new ObserverProxy(vm, fso); + renderProxy->addFrameMetricsObserver(observer); return reinterpret_cast<jlong>(observer); } -static void android_view_ThreadedRenderer_removeFrameStatsObserver(JNIEnv* env, jclass clazz, +static void android_view_ThreadedRenderer_removeFrameMetricsObserver(JNIEnv* env, jclass clazz, jlong proxyPtr, jlong observerPtr) { - FrameStatsObserver* observer = reinterpret_cast<FrameStatsObserver*>(observerPtr); + FrameMetricsObserver* observer = reinterpret_cast<FrameMetricsObserver*>(observerPtr); renderthread::RenderProxy* renderProxy = reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); - renderProxy->removeFrameStatsObserver(observer); -} - -static jint android_view_ThreadedRenderer_getDroppedFrameReportCount(JNIEnv* env, jclass clazz, - jlong proxyPtr) { - renderthread::RenderProxy* renderProxy = - reinterpret_cast<renderthread::RenderProxy*>(proxyPtr); - return renderProxy->getDroppedFrameReportCount(); + renderProxy->removeFrameMetricsObserver(observer); } // ---------------------------------------------------------------------------- @@ -684,25 +696,26 @@ static const JNINativeMethod gMethods[] = { { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, - { "nAddFrameStatsObserver", - "(JLandroid/view/FrameStatsObserver;)J", - (void*)android_view_ThreadedRenderer_addFrameStatsObserver }, - { "nRemoveFrameStatsObserver", + { "nAddFrameMetricsObserver", + "(JLandroid/view/FrameMetricsObserver;)J", + (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, + { "nRemoveFrameMetricsObserver", "(JJ)V", - (void*)android_view_ThreadedRenderer_removeFrameStatsObserver }, - { "nGetDroppedFrameReportCount", - "(J)J", - (void*)android_view_ThreadedRenderer_getDroppedFrameReportCount }, + (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver }, }; int register_android_view_ThreadedRenderer(JNIEnv* env) { - jclass clazz = FindClassOrDie(env, "android/view/FrameStatsObserver"); - gFrameStatsObserverClassInfo.messageQueue = - GetFieldIDOrDie(env, clazz, "mMessageQueue", "Landroid/os/MessageQueue;"); - gFrameStatsObserverClassInfo.buffer = - GetFieldIDOrDie(env, clazz, "mBuffer", "[J"); - gFrameStatsObserverClassInfo.notifyData = - GetMethodIDOrDie(env, clazz, "notifyDataAvailable", "()V"); + jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver"); + gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie( + env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;"); + gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie( + env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;"); + gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie( + env, observerClass, "notifyDataAvailable", "(I)V"); + + jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics"); + gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie( + env, metricsClass, "mTimingData", "[J"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } diff --git a/libs/hwui/FrameStatsObserver.h b/libs/hwui/FrameMetricsObserver.h index 7abc9f143a0b..2b42a80aca18 100644 --- a/libs/hwui/FrameStatsObserver.h +++ b/libs/hwui/FrameMetricsObserver.h @@ -23,9 +23,9 @@ namespace android { namespace uirenderer { -class FrameStatsObserver : public VirtualLightRefBase { +class FrameMetricsObserver : public VirtualLightRefBase { public: - virtual void notify(BufferPool::Buffer* buffer); + virtual void notify(BufferPool::Buffer* buffer, int dropCount); }; }; // namespace uirenderer diff --git a/libs/hwui/FrameStatsReporter.h b/libs/hwui/FrameMetricsReporter.h index b8a9432d6507..0831d24ccbd3 100644 --- a/libs/hwui/FrameStatsReporter.h +++ b/libs/hwui/FrameMetricsReporter.h @@ -21,7 +21,7 @@ #include "BufferPool.h" #include "FrameInfo.h" -#include "FrameStatsObserver.h" +#include "FrameMetricsObserver.h" #include <string.h> #include <vector> @@ -29,18 +29,18 @@ namespace android { namespace uirenderer { -class FrameStatsReporter { +class FrameMetricsReporter { public: - FrameStatsReporter() { + FrameMetricsReporter() { mBufferPool = new BufferPool(kBufferSize, kBufferCount); LOG_ALWAYS_FATAL_IF(mBufferPool.get() == nullptr, "OOM: unable to allocate buffer pool"); } - void addObserver(FrameStatsObserver* observer) { + void addObserver(FrameMetricsObserver* observer) { mObservers.push_back(observer); } - bool removeObserver(FrameStatsObserver* observer) { + bool removeObserver(FrameMetricsObserver* observer) { for (size_t i = 0; i < mObservers.size(); i++) { if (mObservers[i].get() == observer) { mObservers.erase(mObservers.begin() + i); @@ -54,7 +54,7 @@ public: return mObservers.size() > 0; } - void reportFrameStats(const int64_t* stats) { + void reportFrameMetrics(const int64_t* stats) { BufferPool::Buffer* statsBuffer = mBufferPool->acquire(); if (statsBuffer != nullptr) { @@ -63,11 +63,12 @@ public: // notify on requested threads for (size_t i = 0; i < mObservers.size(); i++) { - mObservers[i]->notify(statsBuffer); + mObservers[i]->notify(statsBuffer, mDroppedReports); } // drop our reference statsBuffer->release(); + mDroppedReports = 0; } else { mDroppedReports++; } @@ -79,7 +80,7 @@ private: static const size_t kBufferCount = 3; static const size_t kBufferSize = static_cast<size_t>(FrameInfoIndex::NumIndexes); - std::vector< sp<FrameStatsObserver> > mObservers; + std::vector< sp<FrameMetricsObserver> > mObservers; sp<BufferPool> mBufferPool; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index ea702c01694e..4f528b1a3cd1 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -507,8 +507,8 @@ void CanvasContext::draw() { mJankTracker.addFrame(*mCurrentFrameInfo); mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo); - if (CC_UNLIKELY(mFrameStatsReporter.get() != nullptr)) { - mFrameStatsReporter->reportFrameStats(mCurrentFrameInfo->data()); + if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) { + mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data()); } GpuMemoryTracker::onFrameCompleted(); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 168166ef5b23..1f819705dc3a 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -20,7 +20,7 @@ #include "DamageAccumulator.h" #include "FrameInfo.h" #include "FrameInfoVisualizer.h" -#include "FrameStatsReporter.h" +#include "FrameMetricsReporter.h" #include "IContextFactory.h" #include "LayerUpdateQueue.h" #include "RenderNode.h" @@ -142,26 +142,26 @@ public: return mRenderThread.renderState(); } - void addFrameStatsObserver(FrameStatsObserver* observer) { - if (mFrameStatsReporter.get() == nullptr) { - mFrameStatsReporter.reset(new FrameStatsReporter()); + void addFrameMetricsObserver(FrameMetricsObserver* observer) { + if (mFrameMetricsReporter.get() == nullptr) { + mFrameMetricsReporter.reset(new FrameMetricsReporter()); } - mFrameStatsReporter->addObserver(observer); + mFrameMetricsReporter->addObserver(observer); } - void removeFrameStatsObserver(FrameStatsObserver* observer) { - if (mFrameStatsReporter.get() != nullptr) { - mFrameStatsReporter->removeObserver(observer); - if (!mFrameStatsReporter->hasObservers()) { - mFrameStatsReporter.reset(nullptr); + void removeFrameMetricsObserver(FrameMetricsObserver* observer) { + if (mFrameMetricsReporter.get() != nullptr) { + mFrameMetricsReporter->removeObserver(observer); + if (!mFrameMetricsReporter->hasObservers()) { + mFrameMetricsReporter.reset(nullptr); } } } long getDroppedFrameReportCount() { - if (mFrameStatsReporter.get() != nullptr) { - return mFrameStatsReporter->getDroppedReports(); + if (mFrameMetricsReporter.get() != nullptr) { + return mFrameMetricsReporter->getDroppedReports(); } return 0; @@ -215,7 +215,7 @@ private: std::string mName; JankTracker mJankTracker; FrameInfoVisualizer mProfiler; - std::unique_ptr<FrameStatsReporter> mFrameStatsReporter; + std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter; std::set<RenderNode*> mPrefetechedLayers; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 7c6cd7e014ef..04223a7d5188 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -568,17 +568,17 @@ void RenderProxy::serializeDisplayListTree() { post(task); } -CREATE_BRIDGE2(addFrameStatsObserver, CanvasContext* context, - FrameStatsObserver* frameStatsObserver) { - args->context->addFrameStatsObserver(args->frameStatsObserver); +CREATE_BRIDGE2(addFrameMetricsObserver, CanvasContext* context, + FrameMetricsObserver* frameStatsObserver) { + args->context->addFrameMetricsObserver(args->frameStatsObserver); if (args->frameStatsObserver != nullptr) { args->frameStatsObserver->decStrong(args->context); } return nullptr; } -void RenderProxy::addFrameStatsObserver(FrameStatsObserver* observer) { - SETUP_TASK(addFrameStatsObserver); +void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observer) { + SETUP_TASK(addFrameMetricsObserver); args->context = mContext; args->frameStatsObserver = observer; if (observer != nullptr) { @@ -587,17 +587,17 @@ void RenderProxy::addFrameStatsObserver(FrameStatsObserver* observer) { post(task); } -CREATE_BRIDGE2(removeFrameStatsObserver, CanvasContext* context, - FrameStatsObserver* frameStatsObserver) { - args->context->removeFrameStatsObserver(args->frameStatsObserver); +CREATE_BRIDGE2(removeFrameMetricsObserver, CanvasContext* context, + FrameMetricsObserver* frameStatsObserver) { + args->context->removeFrameMetricsObserver(args->frameStatsObserver); if (args->frameStatsObserver != nullptr) { args->frameStatsObserver->decStrong(args->context); } return nullptr; } -void RenderProxy::removeFrameStatsObserver(FrameStatsObserver* observer) { - SETUP_TASK(removeFrameStatsObserver); +void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observer) { + SETUP_TASK(removeFrameMetricsObserver); args->context = mContext; args->frameStatsObserver = observer; if (observer != nullptr) { @@ -606,16 +606,6 @@ void RenderProxy::removeFrameStatsObserver(FrameStatsObserver* observer) { post(task); } -CREATE_BRIDGE1(getDroppedFrameReportCount, CanvasContext* context) { - return (void*) args->context->getDroppedFrameReportCount(); -} - -long RenderProxy::getDroppedFrameReportCount() { - SETUP_TASK(getDroppedFrameReportCount); - args->context = mContext; - return (long) postAndWait(task); -} - void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 178724a85d04..8d65a8259513 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -29,7 +29,7 @@ #include <utils/StrongPointer.h> #include "../Caches.h" -#include "../FrameStatsObserver.h" +#include "../FrameMetricsObserver.h" #include "../IContextFactory.h" #include "CanvasContext.h" #include "DrawFrameTask.h" @@ -113,8 +113,8 @@ public: ANDROID_API void drawRenderNode(RenderNode* node); ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom); - ANDROID_API void addFrameStatsObserver(FrameStatsObserver* observer); - ANDROID_API void removeFrameStatsObserver(FrameStatsObserver* observer); + ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer); + ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer); ANDROID_API long getDroppedFrameReportCount(); private: |