Loading core/java/android/view/SurfaceControlViewHost.java +7 −1 Original line number Original line Diff line number Diff line Loading @@ -124,8 +124,14 @@ public class SurfaceControlViewHost { /** @hide */ /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, @NonNull WindowlessWindowManager wwm) { @NonNull WindowlessWindowManager wwm) { this(c, d, wwm, false /* useSfChoreographer */); } /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, @NonNull WindowlessWindowManager wwm, boolean useSfChoreographer) { mWm = wwm; mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm); mViewRoot = new ViewRootImpl(c, d, mWm, useSfChoreographer); mViewRoot.forceDisableBLAST(); mViewRoot.forceDisableBLAST(); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } Loading core/java/android/view/ViewRootImpl.java +11 −3 Original line number Original line Diff line number Diff line Loading @@ -449,7 +449,7 @@ public final class ViewRootImpl implements ViewParent, InputQueue mInputQueue; InputQueue mInputQueue; @UnsupportedAppUsage @UnsupportedAppUsage FallbackEventHandler mFallbackEventHandler; FallbackEventHandler mFallbackEventHandler; Choreographer mChoreographer; final Choreographer mChoreographer; // used in relayout to get SurfaceControl size // used in relayout to get SurfaceControl size // for BLAST adapter surface setup // for BLAST adapter surface setup Loading Loading @@ -692,11 +692,18 @@ public final class ViewRootImpl implements ViewParent, private SurfaceControl.Transaction mRtBLASTSyncTransaction = new SurfaceControl.Transaction(); private SurfaceControl.Transaction mRtBLASTSyncTransaction = new SurfaceControl.Transaction(); private String mTag = TAG; private String mTag = TAG; public ViewRootImpl(Context context, Display display) { public ViewRootImpl(Context context, Display display) { this(context, display, WindowManagerGlobal.getWindowSession()); this(context, display, WindowManagerGlobal.getWindowSession(), false /* useSfChoreographer */); } } public ViewRootImpl(Context context, Display display, IWindowSession session) { public ViewRootImpl(Context context, Display display, IWindowSession session) { this(context, display, session, false /* useSfChoreographer */); } public ViewRootImpl(Context context, Display display, IWindowSession session, boolean useSfChoreographer) { mContext = context; mContext = context; mWindowSession = session; mWindowSession = session; mDisplay = display; mDisplay = display; Loading Loading @@ -732,7 +739,8 @@ public final class ViewRootImpl implements ViewParent, mDensity = context.getResources().getDisplayMetrics().densityDpi; mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mFallbackEventHandler = new PhoneFallbackEventHandler(context); mFallbackEventHandler = new PhoneFallbackEventHandler(context); mChoreographer = Choreographer.getInstance(); mChoreographer = useSfChoreographer ? Choreographer.getSfInstance() : Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mInsetsController = new InsetsController(this); mInsetsController = new InsetsController(this); Loading core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.javadeleted 100644 → 0 +0 −94 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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 com.android.internal.view; import android.os.Handler; import android.os.Message; import android.view.Choreographer; import android.view.Display; /** * Utility class to schedule things at vsync-sf instead of vsync-app * @hide */ public class SurfaceFlingerVsyncChoreographer { private static final long ONE_MS_IN_NS = 1000000; private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000; private final Handler mHandler; private final Choreographer mChoreographer; /** * The offset between vsync-app and vsync-surfaceflinger. See * {@link #calculateAppSurfaceFlingerVsyncOffsetMs} why this is necessary. */ private long mSurfaceFlingerOffsetMs; public SurfaceFlingerVsyncChoreographer(Handler handler, Display display, Choreographer choreographer) { mHandler = handler; mChoreographer = choreographer; mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs(display); } public long getSurfaceFlingerOffsetMs() { return mSurfaceFlingerOffsetMs; } /** * This method calculates the offset between vsync-surfaceflinger and vsync-app. If vsync-app * is a couple of milliseconds before vsync-sf, a touch or animation event that causes a surface * flinger transaction are sometimes processed before the vsync-sf tick, and sometimes after, * which leads to jank. Figure out this difference here and then post all the touch/animation * events to start being processed at vsync-sf. * * @return The offset between vsync-app and vsync-sf, or 0 if vsync app happens after vsync-sf. */ private long calculateAppSurfaceFlingerVsyncOffsetMs(Display display) { // Calculate vsync offset from SurfaceFlinger. // See frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:getDisplayConfigs long vsyncPeriod = (long) (ONE_S_IN_NS / display.getRefreshRate()); long sfVsyncOffset = vsyncPeriod - (display.getPresentationDeadlineNanos() - ONE_MS_IN_NS); return Math.max(0, (sfVsyncOffset - display.getAppVsyncOffsetNanos()) / ONE_MS_IN_NS); } public void scheduleAtSfVsync(Runnable r) { final long delay = calculateDelay(); if (delay <= 0) { r.run(); } else { mHandler.postDelayed(r, delay); } } public void scheduleAtSfVsync(Handler h, Message m) { final long delay = calculateDelay(); if (delay <= 0) { h.handleMessage(m); } else { m.setAsynchronous(true); h.sendMessageDelayed(m, delay); } } private long calculateDelay() { final long sinceFrameStart = System.nanoTime() - mChoreographer.getLastFrameTimeNanos(); return mSurfaceFlingerOffsetMs - sinceFrameStart / 1000000; } } packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +8 −33 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.ValueAnimator; Loading @@ -32,10 +33,8 @@ import android.graphics.Region.Op; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Slog; import android.util.Slog; import android.view.Choreographer; import android.view.Display; import android.view.Display; import android.view.InsetsState; import android.view.InsetsState; import android.view.MotionEvent; import android.view.MotionEvent; Loading @@ -57,12 +56,12 @@ import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import android.widget.FrameLayout; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.internal.policy.DockedDividerUtils; import com.android.internal.view.SurfaceFlingerVsyncChoreographer; import com.android.systemui.Interpolators; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.shared.system.WindowManagerWrapper; Loading Loading @@ -111,8 +110,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private static final Interpolator IME_ADJUST_INTERPOLATOR = private static final Interpolator IME_ADJUST_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 0.1f, 1f); new PathInterpolator(0.2f, 0f, 0.1f, 1f); private static final int MSG_RESIZE_STACK = 0; private DividerHandleView mHandle; private DividerHandleView mHandle; private View mBackground; private View mBackground; private MinimizedDockShadow mMinimizedShadow; private MinimizedDockShadow mMinimizedShadow; Loading Loading @@ -149,6 +146,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private SplitDisplayLayout mSplitLayout; private SplitDisplayLayout mSplitLayout; private DividerCallbacks mCallback; private DividerCallbacks mCallback; private final Rect mStableInsets = new Rect(); private final Rect mStableInsets = new Rect(); private final AnimationHandler mAnimationHandler = new AnimationHandler(); private boolean mGrowRecents; private boolean mGrowRecents; private ValueAnimator mCurrentAnimator; private ValueAnimator mCurrentAnimator; Loading @@ -159,7 +157,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private boolean mHomeStackResizable; private boolean mHomeStackResizable; private boolean mAdjustedForIme; private boolean mAdjustedForIme; private DividerState mState; private DividerState mState; private final SurfaceFlingerVsyncChoreographer mSfChoreographer; private SplitScreenTaskOrganizer mTiles; private SplitScreenTaskOrganizer mTiles; boolean mFirstLayout = true; boolean mFirstLayout = true; Loading @@ -173,18 +170,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, // used interact with keyguard. // used interact with keyguard. private boolean mSurfaceHidden = false; private boolean mSurfaceHidden = false; private final Handler mHandler = new Handler() { private final Handler mHandler = new Handler(); @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_RESIZE_STACK: resizeStackSurfaces(msg.arg1, msg.arg2, (SnapTarget) msg.obj); break; default: super.handleMessage(msg); } } }; private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { @Override @Override Loading Loading @@ -277,11 +263,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes); mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(), Choreographer.getInstance()); final DisplayManager displayManager = final DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider()); } } @Override @Override Loading Loading @@ -326,7 +311,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, void onDividerRemoved() { void onDividerRemoved() { mRemoved = true; mRemoved = true; mCallback = null; mCallback = null; mHandler.removeMessages(MSG_RESIZE_STACK); } } @Override @Override Loading Loading @@ -548,7 +532,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) { if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) { SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget( SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget( mStartPosition, 0 /* velocity */, false /* hardDismiss */); mStartPosition, 0 /* velocity */, false /* hardDismiss */); resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget); resizeStackSurfaces(calculatePosition(x, y), mStartPosition, snapTarget); } } break; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP: Loading Loading @@ -633,7 +617,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (DEBUG) Slog.d(TAG, "Getting fling " + position + "->" + snapTarget.position); if (DEBUG) Slog.d(TAG, "Getting fling " + position + "->" + snapTarget.position); final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE; final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE; ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position); ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position); anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(), anim.addUpdateListener(animation -> resizeStackSurfaces((int) animation.getAnimatedValue(), taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f ? TASK_POSITION_SAME ? TASK_POSITION_SAME : snapTarget.taskPosition, : snapTarget.taskPosition, Loading Loading @@ -682,7 +666,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, @Override @Override public void onAnimationCancel(Animator animation) { public void onAnimationCancel(Animator animation) { mHandler.removeMessages(MSG_RESIZE_STACK); mCancelled = true; mCancelled = true; } } Loading @@ -693,8 +676,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, delay = endDelay; delay = endDelay; } else if (mCancelled) { } else if (mCancelled) { delay = 0; delay = 0; } else if (mSfChoreographer.getSurfaceFlingerOffsetMs() > 0) { delay = mSfChoreographer.getSurfaceFlingerOffsetMs(); } } if (delay == 0) { if (delay == 0) { endAction.accept(mCancelled); endAction.accept(mCancelled); Loading @@ -705,6 +686,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, } } } } }); }); anim.setAnimationHandler(mAnimationHandler); mCurrentAnimator = anim; mCurrentAnimator = anim; return anim; return anim; } } Loading Loading @@ -1047,13 +1029,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, mDividerSize); mDividerSize); } } public void resizeStackDelayed(int position, int taskPosition, SnapTarget taskSnapTarget) { Message message = mHandler.obtainMessage(MSG_RESIZE_STACK, position, taskPosition, taskSnapTarget); message.setAsynchronous(true); mSfChoreographer.scheduleAtSfVsync(mHandler, message); } private void resizeStackSurfaces(SnapTarget taskSnapTarget) { private void resizeStackSurfaces(SnapTarget taskSnapTarget) { resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget); resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget); } } Loading packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -194,7 +194,9 @@ public class SystemWindows { return; return; } } final Display display = mDisplayController.getDisplay(mDisplayId); final Display display = mDisplayController.getDisplay(mDisplayId); SurfaceControlViewHost viewRoot = new SurfaceControlViewHost(mContext, display, wwm); SurfaceControlViewHost viewRoot = new SurfaceControlViewHost(mContext, display, wwm, true /* useSfChoreographer */); attrs.flags |= FLAG_HARDWARE_ACCELERATED; attrs.flags |= FLAG_HARDWARE_ACCELERATED; viewRoot.setView(view, attrs); viewRoot.setView(view, attrs); mViewRoots.put(view, viewRoot); mViewRoots.put(view, viewRoot); Loading Loading
core/java/android/view/SurfaceControlViewHost.java +7 −1 Original line number Original line Diff line number Diff line Loading @@ -124,8 +124,14 @@ public class SurfaceControlViewHost { /** @hide */ /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, @NonNull WindowlessWindowManager wwm) { @NonNull WindowlessWindowManager wwm) { this(c, d, wwm, false /* useSfChoreographer */); } /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, @NonNull WindowlessWindowManager wwm, boolean useSfChoreographer) { mWm = wwm; mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm); mViewRoot = new ViewRootImpl(c, d, mWm, useSfChoreographer); mViewRoot.forceDisableBLAST(); mViewRoot.forceDisableBLAST(); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection(); } } Loading
core/java/android/view/ViewRootImpl.java +11 −3 Original line number Original line Diff line number Diff line Loading @@ -449,7 +449,7 @@ public final class ViewRootImpl implements ViewParent, InputQueue mInputQueue; InputQueue mInputQueue; @UnsupportedAppUsage @UnsupportedAppUsage FallbackEventHandler mFallbackEventHandler; FallbackEventHandler mFallbackEventHandler; Choreographer mChoreographer; final Choreographer mChoreographer; // used in relayout to get SurfaceControl size // used in relayout to get SurfaceControl size // for BLAST adapter surface setup // for BLAST adapter surface setup Loading Loading @@ -692,11 +692,18 @@ public final class ViewRootImpl implements ViewParent, private SurfaceControl.Transaction mRtBLASTSyncTransaction = new SurfaceControl.Transaction(); private SurfaceControl.Transaction mRtBLASTSyncTransaction = new SurfaceControl.Transaction(); private String mTag = TAG; private String mTag = TAG; public ViewRootImpl(Context context, Display display) { public ViewRootImpl(Context context, Display display) { this(context, display, WindowManagerGlobal.getWindowSession()); this(context, display, WindowManagerGlobal.getWindowSession(), false /* useSfChoreographer */); } } public ViewRootImpl(Context context, Display display, IWindowSession session) { public ViewRootImpl(Context context, Display display, IWindowSession session) { this(context, display, session, false /* useSfChoreographer */); } public ViewRootImpl(Context context, Display display, IWindowSession session, boolean useSfChoreographer) { mContext = context; mContext = context; mWindowSession = session; mWindowSession = session; mDisplay = display; mDisplay = display; Loading Loading @@ -732,7 +739,8 @@ public final class ViewRootImpl implements ViewParent, mDensity = context.getResources().getDisplayMetrics().densityDpi; mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mFallbackEventHandler = new PhoneFallbackEventHandler(context); mFallbackEventHandler = new PhoneFallbackEventHandler(context); mChoreographer = Choreographer.getInstance(); mChoreographer = useSfChoreographer ? Choreographer.getSfInstance() : Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mInsetsController = new InsetsController(this); mInsetsController = new InsetsController(this); Loading
core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.javadeleted 100644 → 0 +0 −94 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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 com.android.internal.view; import android.os.Handler; import android.os.Message; import android.view.Choreographer; import android.view.Display; /** * Utility class to schedule things at vsync-sf instead of vsync-app * @hide */ public class SurfaceFlingerVsyncChoreographer { private static final long ONE_MS_IN_NS = 1000000; private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000; private final Handler mHandler; private final Choreographer mChoreographer; /** * The offset between vsync-app and vsync-surfaceflinger. See * {@link #calculateAppSurfaceFlingerVsyncOffsetMs} why this is necessary. */ private long mSurfaceFlingerOffsetMs; public SurfaceFlingerVsyncChoreographer(Handler handler, Display display, Choreographer choreographer) { mHandler = handler; mChoreographer = choreographer; mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs(display); } public long getSurfaceFlingerOffsetMs() { return mSurfaceFlingerOffsetMs; } /** * This method calculates the offset between vsync-surfaceflinger and vsync-app. If vsync-app * is a couple of milliseconds before vsync-sf, a touch or animation event that causes a surface * flinger transaction are sometimes processed before the vsync-sf tick, and sometimes after, * which leads to jank. Figure out this difference here and then post all the touch/animation * events to start being processed at vsync-sf. * * @return The offset between vsync-app and vsync-sf, or 0 if vsync app happens after vsync-sf. */ private long calculateAppSurfaceFlingerVsyncOffsetMs(Display display) { // Calculate vsync offset from SurfaceFlinger. // See frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:getDisplayConfigs long vsyncPeriod = (long) (ONE_S_IN_NS / display.getRefreshRate()); long sfVsyncOffset = vsyncPeriod - (display.getPresentationDeadlineNanos() - ONE_MS_IN_NS); return Math.max(0, (sfVsyncOffset - display.getAppVsyncOffsetNanos()) / ONE_MS_IN_NS); } public void scheduleAtSfVsync(Runnable r) { final long delay = calculateDelay(); if (delay <= 0) { r.run(); } else { mHandler.postDelayed(r, delay); } } public void scheduleAtSfVsync(Handler h, Message m) { final long delay = calculateDelay(); if (delay <= 0) { h.handleMessage(m); } else { m.setAsynchronous(true); h.sendMessageDelayed(m, delay); } } private long calculateDelay() { final long sinceFrameStart = System.nanoTime() - mChoreographer.getLastFrameTimeNanos(); return mSurfaceFlingerOffsetMs - sinceFrameStart / 1000000; } }
packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +8 −33 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.ValueAnimator; Loading @@ -32,10 +33,8 @@ import android.graphics.Region.Op; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Slog; import android.util.Slog; import android.view.Choreographer; import android.view.Display; import android.view.Display; import android.view.InsetsState; import android.view.InsetsState; import android.view.MotionEvent; import android.view.MotionEvent; Loading @@ -57,12 +56,12 @@ import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import android.widget.FrameLayout; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.internal.policy.DockedDividerUtils; import com.android.internal.view.SurfaceFlingerVsyncChoreographer; import com.android.systemui.Interpolators; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.shared.system.WindowManagerWrapper; Loading Loading @@ -111,8 +110,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private static final Interpolator IME_ADJUST_INTERPOLATOR = private static final Interpolator IME_ADJUST_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 0.1f, 1f); new PathInterpolator(0.2f, 0f, 0.1f, 1f); private static final int MSG_RESIZE_STACK = 0; private DividerHandleView mHandle; private DividerHandleView mHandle; private View mBackground; private View mBackground; private MinimizedDockShadow mMinimizedShadow; private MinimizedDockShadow mMinimizedShadow; Loading Loading @@ -149,6 +146,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private SplitDisplayLayout mSplitLayout; private SplitDisplayLayout mSplitLayout; private DividerCallbacks mCallback; private DividerCallbacks mCallback; private final Rect mStableInsets = new Rect(); private final Rect mStableInsets = new Rect(); private final AnimationHandler mAnimationHandler = new AnimationHandler(); private boolean mGrowRecents; private boolean mGrowRecents; private ValueAnimator mCurrentAnimator; private ValueAnimator mCurrentAnimator; Loading @@ -159,7 +157,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private boolean mHomeStackResizable; private boolean mHomeStackResizable; private boolean mAdjustedForIme; private boolean mAdjustedForIme; private DividerState mState; private DividerState mState; private final SurfaceFlingerVsyncChoreographer mSfChoreographer; private SplitScreenTaskOrganizer mTiles; private SplitScreenTaskOrganizer mTiles; boolean mFirstLayout = true; boolean mFirstLayout = true; Loading @@ -173,18 +170,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, // used interact with keyguard. // used interact with keyguard. private boolean mSurfaceHidden = false; private boolean mSurfaceHidden = false; private final Handler mHandler = new Handler() { private final Handler mHandler = new Handler(); @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_RESIZE_STACK: resizeStackSurfaces(msg.arg1, msg.arg2, (SnapTarget) msg.obj); break; default: super.handleMessage(msg); } } }; private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { @Override @Override Loading Loading @@ -277,11 +263,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); super(context, attrs, defStyleAttr, defStyleRes); mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(), Choreographer.getInstance()); final DisplayManager displayManager = final DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider()); } } @Override @Override Loading Loading @@ -326,7 +311,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, void onDividerRemoved() { void onDividerRemoved() { mRemoved = true; mRemoved = true; mCallback = null; mCallback = null; mHandler.removeMessages(MSG_RESIZE_STACK); } } @Override @Override Loading Loading @@ -548,7 +532,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) { if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) { SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget( SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget( mStartPosition, 0 /* velocity */, false /* hardDismiss */); mStartPosition, 0 /* velocity */, false /* hardDismiss */); resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget); resizeStackSurfaces(calculatePosition(x, y), mStartPosition, snapTarget); } } break; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP: Loading Loading @@ -633,7 +617,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (DEBUG) Slog.d(TAG, "Getting fling " + position + "->" + snapTarget.position); if (DEBUG) Slog.d(TAG, "Getting fling " + position + "->" + snapTarget.position); final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE; final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE; ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position); ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position); anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(), anim.addUpdateListener(animation -> resizeStackSurfaces((int) animation.getAnimatedValue(), taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f ? TASK_POSITION_SAME ? TASK_POSITION_SAME : snapTarget.taskPosition, : snapTarget.taskPosition, Loading Loading @@ -682,7 +666,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, @Override @Override public void onAnimationCancel(Animator animation) { public void onAnimationCancel(Animator animation) { mHandler.removeMessages(MSG_RESIZE_STACK); mCancelled = true; mCancelled = true; } } Loading @@ -693,8 +676,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, delay = endDelay; delay = endDelay; } else if (mCancelled) { } else if (mCancelled) { delay = 0; delay = 0; } else if (mSfChoreographer.getSurfaceFlingerOffsetMs() > 0) { delay = mSfChoreographer.getSurfaceFlingerOffsetMs(); } } if (delay == 0) { if (delay == 0) { endAction.accept(mCancelled); endAction.accept(mCancelled); Loading @@ -705,6 +686,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, } } } } }); }); anim.setAnimationHandler(mAnimationHandler); mCurrentAnimator = anim; mCurrentAnimator = anim; return anim; return anim; } } Loading Loading @@ -1047,13 +1029,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, mDividerSize); mDividerSize); } } public void resizeStackDelayed(int position, int taskPosition, SnapTarget taskSnapTarget) { Message message = mHandler.obtainMessage(MSG_RESIZE_STACK, position, taskPosition, taskSnapTarget); message.setAsynchronous(true); mSfChoreographer.scheduleAtSfVsync(mHandler, message); } private void resizeStackSurfaces(SnapTarget taskSnapTarget) { private void resizeStackSurfaces(SnapTarget taskSnapTarget) { resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget); resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget); } } Loading
packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -194,7 +194,9 @@ public class SystemWindows { return; return; } } final Display display = mDisplayController.getDisplay(mDisplayId); final Display display = mDisplayController.getDisplay(mDisplayId); SurfaceControlViewHost viewRoot = new SurfaceControlViewHost(mContext, display, wwm); SurfaceControlViewHost viewRoot = new SurfaceControlViewHost(mContext, display, wwm, true /* useSfChoreographer */); attrs.flags |= FLAG_HARDWARE_ACCELERATED; attrs.flags |= FLAG_HARDWARE_ACCELERATED; viewRoot.setView(view, attrs); viewRoot.setView(view, attrs); mViewRoots.put(view, viewRoot); mViewRoots.put(view, viewRoot); Loading