Investigate first measure/layout/draw events |
|||||
Issue descriptionI was always curious about strange sequence of Looper.dispatchMessage events that don't run Chrome tasks. In the attached screenshot (trace.html from crbug.com/735799#c31) three Looper.dispatchMessage take 211ms. I ran tracing with gfx,view,wm categories and found that those Looper events seem to correspond to animator:translationZ animation. See screenshot and attached trace. Do we know who is responsible for this animation?
,
Sep 13 2017
,
Sep 13 2017
Found the culprit: main[1] print getNameForTrace() getNameForTrace() = "animator:translationZ" main[1] where [1] android.animation.ValueAnimator.startAnimation (ValueAnimator.java:1,225) [2] android.animation.ValueAnimator.start (ValueAnimator.java:1,041) [3] android.animation.ValueAnimator.start (ValueAnimator.java:1,065) [4] android.animation.ObjectAnimator.start (ObjectAnimator.java:852) [5] android.animation.ValueAnimator.startWithoutPulsing (ValueAnimator.java:1,058) [6] android.animation.AnimatorSet.handleAnimationEvents (AnimatorSet.java:1,142) [7] android.animation.AnimatorSet.startAnimation (AnimatorSet.java:1,227) [8] android.animation.AnimatorSet.start (AnimatorSet.java:729) [9] android.animation.AnimatorSet.start (AnimatorSet.java:684) [10] android.animation.StateListAnimator.start (StateListAnimator.java:188) [11] android.animation.StateListAnimator.setState (StateListAnimator.java:181) [12] android.view.View.drawableStateChanged (View.java:19,990) [13] android.widget.TextView.drawableStateChanged (TextView.java:4,969) [14] org.chromium.chrome.browser.widget.newtab.NewTabButton.drawableStateChanged (NewTabButton.java:54) [15] android.view.View.refreshDrawableState (View.java:20,045) [16] android.view.View.dispatchAttachedToWindow (View.java:17,437) [17] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [18] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [19] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [20] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [21] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [22] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [23] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [24] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [25] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [26] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [27] android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1,668) [28] android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1,392) [29] android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6,752) [30] android.view.Choreographer$CallbackRecord.run (Choreographer.java:911) [31] android.view.Choreographer.doCallbacks (Choreographer.java:723) [32] android.view.Choreographer.doFrame (Choreographer.java:658) [33] android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897) [34] android.os.Handler.handleCallback (Handler.java:790) [35] android.os.Handler.dispatchMessage (Handler.java:99) [36] android.os.Looper.loop (Looper.java:164) [37] android.app.ActivityThread.main (ActivityThread.java:6,494) [38] java.lang.reflect.Method.invoke (native method) [39] com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438) [40] com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807) Actually, NewTabButton starts one more animation before that: main[1] print getNameForTrace() getNameForTrace() = "animator:elevation" main[1] where [1] android.animation.ValueAnimator.startAnimation (ValueAnimator.java:1,225) [2] android.animation.ValueAnimator.start (ValueAnimator.java:1,041) [3] android.animation.ValueAnimator.start (ValueAnimator.java:1,065) [4] android.animation.ObjectAnimator.start (ObjectAnimator.java:852) [5] android.animation.ValueAnimator.startWithoutPulsing (ValueAnimator.java:1,058) [6] android.animation.AnimatorSet.handleAnimationEvents (AnimatorSet.java:1,142) [7] android.animation.AnimatorSet.startAnimation (AnimatorSet.java:1,227) [8] android.animation.AnimatorSet.start (AnimatorSet.java:729) [9] android.animation.AnimatorSet.start (AnimatorSet.java:684) [10] android.animation.StateListAnimator.start (StateListAnimator.java:188) [11] android.animation.StateListAnimator.setState (StateListAnimator.java:181) [12] android.view.View.drawableStateChanged (View.java:19,990) [13] android.widget.TextView.drawableStateChanged (TextView.java:4,969) [14] org.chromium.chrome.browser.widget.newtab.NewTabButton.drawableStateChanged (NewTabButton.java:54) [15] android.view.View.refreshDrawableState (View.java:20,045) [16] android.view.View.dispatchAttachedToWindow (View.java:17,437) [17] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [18] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [19] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [20] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [21] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [22] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [23] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [24] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [25] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [26] android.view.ViewGroup.dispatchAttachedToWindow (ViewGroup.java:3,333) [27] android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1,668) [28] android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1,392) [29] android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6,752) [30] android.view.Choreographer$CallbackRecord.run (Choreographer.java:911) [31] android.view.Choreographer.doCallbacks (Choreographer.java:723) [32] android.view.Choreographer.doFrame (Choreographer.java:658) [33] android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897) [34] android.os.Handler.handleCallback (Handler.java:790) [35] android.os.Handler.dispatchMessage (Handler.java:99) [36] android.os.Looper.loop (Looper.java:164) [37] android.app.ActivityThread.main (ActivityThread.java:6,494) [38] java.lang.reflect.Method.invoke (native method) [39] com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438) [40] com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
,
Sep 13 2017
Both of those animations are button_state_list_anim_material, set as "stateListAnimator" in "Widget.Material.Button". main[1] where [1] android.view.View.setStateListAnimator (View.java:14,783) [2] android.view.View.<init> (View.java:5,048) [3] android.widget.TextView.<init> (TextView.java:826) [4] android.widget.Button.<init> (Button.java:166) [5] android.widget.Button.<init> (Button.java:141) [6] android.widget.Button.<init> (Button.java:117) [7] org.chromium.chrome.browser.widget.newtab.NewTabButton.<init> (NewTabButton.java:1) [8] java.lang.reflect.Constructor.newInstance0 (native method) [9] java.lang.reflect.Constructor.newInstance (Constructor.java:334) [10] android.view.LayoutInflater.createView (LayoutInflater.java:647) [11] android.view.LayoutInflater.createViewFromTag (LayoutInflater.java:790) [12] android.view.LayoutInflater.createViewFromTag (LayoutInflater.java:730) [13] android.view.LayoutInflater.rInflate (LayoutInflater.java:863) [14] android.view.LayoutInflater.parseInclude (LayoutInflater.java:963) [15] android.view.LayoutInflater.rInflate (LayoutInflater.java:859) [16] android.view.LayoutInflater.rInflateChildren (LayoutInflater.java:824) [17] android.view.LayoutInflater.inflate (LayoutInflater.java:515) [18] android.view.LayoutInflater.inflate (LayoutInflater.java:423) [19] android.view.ViewStub.inflateViewNoAdd (ViewStub.java:269) [20] android.view.ViewStub.inflate (ViewStub.java:302) [21] org.chromium.chrome.browser.toolbar.ToolbarControlContainer.initWithToolbar (ToolbarControlContainer.java:49) [22] org.chromium.chrome.browser.ChromeActivity.setContentView (ChromeActivity.java:180) [23] org.chromium.chrome.browser.init.AsyncInitializationActivity.setContentViewAndLoadLibrary (AsyncInitializationActivity.java:28) [24] org.chromium.chrome.browser.init.ChromeBrowserInitializer.handlePreNativeStartup (ChromeBrowserInitializer.java:77) [25] org.chromium.chrome.browser.init.AsyncInitializationActivity.onCreate (AsyncInitializationActivity.java:111)
,
Sep 13 2017
I can get rid of animation by calling setStateListAnimator(null) in NewTabButton ctor, but that doesn't help with those events. It looks like we're rendering our UI hierarchy there, measuring it for the first time. I.e. we need to simplify UI to cut that down.
,
Sep 19 2017
When you say the animation doesn't help with those events, are you saying removing the animator doesn't give any benefit? Should we instead just change this bug to be something like "lazily inflate new tab button on startup"? I don't think we'd want to set the Animator to null anyway. I think we could try to just have it call jumpToCurrentState in the constructor to get rid of the animation call.
,
Nov 9 2017
I've taken method trace between ChromeApplication.onCreate and ChromeBrowserInitializer.startChromeBrowserProcessesAsync, so it includes the events this bug is concerned about.
One interesting thing I can see is that hierarchy is measured twice during the invocation of ViewRootImpl.performTraversals():
* First from ViewRootImpl.measureHierarchy() -> ViewRootImpl.performMeasure().
* Second time ViewRootImpl.performMeasure() is called directly by performTraversals(), and that's likely happens here [1]. Note that there is an optional log that hints that this situation is not common ("Ooops, something changed!").
I think we need to dig deeper here to understand why we're measuring for the second time.
[1] https://android.googlesource.com/platform/frameworks/base/+/oreo-release/core/java/android/view/ViewRootImpl.java#2155
,
Nov 9 2017
I added instrumentation and found that first time measure() is called with
"width: {MeasureSpec: EXACTLY 480}, height: {MeasureSpec: EXACTLY 746}"
and the second time it's called with
"width: {MeasureSpec: EXACTLY 480}, height: {MeasureSpec: EXACTLY 854}"
Any idea why height changed? Seem that the second time height includes the status bar?
,
Nov 23 2017
,
Jan 9 2018
I tried disabling animations and didn't see any change, see here: https://docs.google.com/document/d/1OAd1fYv2ugUaiLOTnBPtebNsfvzKaxA-aQVeasmQ6dA/edit#heading=h.scgi3ifyuop2 |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by dskiba@chromium.org
, Sep 12 2017