Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e95a488 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

More optimization while dragging docked divider

- Make sure mPendingBackdropFrame gets also set when if the window
triggers a relayout on it's own, so it doesn't call into window manager
all the time.
- Set the insets of the docked divider to empty so we don't trigger a
layout when we are just moving it - it doesn't need it in any case.
- Send a window move message to the divider when it moved
- Update attach info in all move cases, update light center

The whole resize operation now only takes around 4ms per frame, and
leaves a lot more resources for the apps to do configuration changes.

Bug: 25015474
Change-Id: Ica48129570a0fc858a89c21f46abf3442efb0224
parent 844e1712
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ public abstract class WallpaperService extends Service {
        final Rect mDispatchedOutsets = new Rect();
        final Rect mFinalSystemInsets = new Rect();
        final Rect mFinalStableInsets = new Rect();
        final Rect mBackdropFrame = new Rect();
        final Configuration mConfiguration = new Configuration();

        final WindowManager.LayoutParams mLayout
@@ -675,8 +676,8 @@ public abstract class WallpaperService extends Service {
                    final int relayoutResult = mSession.relayout(
                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                            View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
                            mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
                            mSurfaceHolder.mSurface);
                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
                            mConfiguration, mSurfaceHolder.mSurface);

                    if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
                            + ", frame=" + mWinFrame);
+4 −1
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ interface IWindowSession {
     * so complex relayout of the window should not happen based on them.
     * @param outOutsets Rect in which is placed the dead area of the screen that we would like to
     * treat as real display. Example of such area is a chin in some models of wearable devices.
     * @param outBackdropFrame Rect which is used draw the resizing background during a resize
     * operation.
     * @param outConfiguration New configuration of window, if it is now
     * becoming visible and the global configuration has changed since it
     * was last displayed.
@@ -93,7 +95,8 @@ interface IWindowSession {
            int requestedWidth, int requestedHeight, int viewVisibility,
            int flags, out Rect outFrame, out Rect outOverscanInsets,
            out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
            out Rect outOutsets, out Configuration outConfig, out Surface outSurface);
            out Rect outOutsets, out Rect outBackdropFrame, out Configuration outConfig,
            out Surface outSurface);

    /**
     *  Position a window relative to it's parent (attached) window without triggering
+3 −2
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ public class SurfaceView extends View {
    final Rect mContentInsets = new Rect();
    final Rect mStableInsets = new Rect();
    final Rect mOutsets = new Rect();
    final Rect mBackdropFrame = new Rect();
    final Configuration mConfiguration = new Configuration();

    static final int KEEP_SCREEN_ON_MSG = 1;
@@ -529,8 +530,8 @@ public class SurfaceView extends View {
                            visible ? VISIBLE : GONE,
                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
                            mWinFrame, mOverscanInsets, mContentInsets,
                            mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
                            mNewSurface);
                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
                            mConfiguration, mNewSurface);
                    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                        reportDrawNeeded = true;
                    }
+34 −25
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
@@ -1953,29 +1954,7 @@ public final class ViewRootImpl implements ViewParent,
            // in the attach info. We translate only the window frame since on window move
            // the window manager tells us only for the new frame but the insets are the
            // same and we do not want to translate them more than once.

            // TODO: Well, we are checking whether the frame has changed similarly
            // to how this is done for the insets. This is however incorrect since
            // the insets and the frame are translated. For example, the old frame
            // was (1, 1 - 1, 1) and was translated to say (2, 2 - 2, 2), now the new
            // reported frame is (2, 2 - 2, 2) which implies no change but this is not
            // true since we are comparing a not translated value to a translated one.
            // This scenario is rare but we may want to fix that.

            final boolean windowMoved = (mAttachInfo.mWindowLeft != frame.left
                    || mAttachInfo.mWindowTop != frame.top);
            if (windowMoved) {
                if (mTranslator != null) {
                    mTranslator.translateRectInScreenToAppWinFrame(frame);
                }
                mAttachInfo.mWindowLeft = frame.left;
                mAttachInfo.mWindowTop = frame.top;

                // Update the light position for the new window offsets.
                if (mAttachInfo.mHardwareRenderer != null) {
                    mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
                }
            }
            maybeHandleWindowMove(frame);
        }

        final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
@@ -2140,6 +2119,31 @@ public final class ViewRootImpl implements ViewParent,
        mIsInTraversal = false;
    }

    private void maybeHandleWindowMove(Rect frame) {

        // TODO: Well, we are checking whether the frame has changed similarly
        // to how this is done for the insets. This is however incorrect since
        // the insets and the frame are translated. For example, the old frame
        // was (1, 1 - 1, 1) and was translated to say (2, 2 - 2, 2), now the new
        // reported frame is (2, 2 - 2, 2) which implies no change but this is not
        // true since we are comparing a not translated value to a translated one.
        // This scenario is rare but we may want to fix that.

        final boolean windowMoved = mAttachInfo.mWindowLeft != frame.left
                || mAttachInfo.mWindowTop != frame.top;
        if (windowMoved) {
            if (mTranslator != null) {
                mTranslator.translateRectInScreenToAppWinFrame(frame);
            }
            mAttachInfo.mWindowLeft = frame.left;
            mAttachInfo.mWindowTop = frame.top;

            // Update the light position for the new window offsets.
            if (mAttachInfo.mHardwareRenderer != null) {
                mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
            }
        }
    }
    private void handleOutOfResourcesException(Surface.OutOfResourcesException e) {
        Log.e(mTag, "OutOfResourcesException initializing HW surface", e);
        try {
@@ -3403,12 +3407,16 @@ public final class ViewRootImpl implements ViewParent,

                    // Suppress layouts during resizing - a correct layout will happen when resizing
                    // is done, and this just increases system load.
                    boolean suppress = mDragResizing && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER;
                    boolean isDockedDivider = mWindowAttributes.type == TYPE_DOCK_DIVIDER;
                    boolean suppress = (mDragResizing && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER)
                            || isDockedDivider;
                    if (!suppress) {
                        if (mView != null) {
                            forceLayout(mView);
                        }
                        requestLayout();
                    } else {
                        maybeHandleWindowMove(mWinFrame);
                    }
                }
                break;
@@ -5522,7 +5530,8 @@ public final class ViewRootImpl implements ViewParent,
                (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,
                mSurface);
        //Log.d(mTag, "<<<<<< BACK FROM relayout");
        if (restore) {
            params.restore();
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;

/**
@@ -50,6 +51,7 @@ public class DividerWindowManager {
                        | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
                PixelFormat.TRANSLUCENT);
        mLp.setTitle(WINDOW_TITLE);
        mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
        view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
Loading