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

Commit 43661b18 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Shortcut double-relayout under specific conditions" into main

parents 93645eab f4c6c3b6
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -776,6 +776,16 @@ public final class ViewRootImpl implements ViewParent,
    int mSyncSeqId = 0;
    int mLastSyncSeqId = 0;
    /**
     * Specific optimization where a sync relayout (WM) has determined that the results of a
     * relayout are likely-valid despite this client providing parameters based on an out-dated
     * configuration. In this case, relayout will provide a (later) seqId (this one) which it
     * believes doesn't require another sync relayout and then will NOT cancel. This allows the
     * VRI to assume the frames are already correct, layout/draw immediately, and then skip the
     * next sync relayout.
     */
    int mNonSyncEarlySeqId = 0;
    /** @hide */
    public static final class NoPreloadHolder {
        public static final boolean sAlwaysSeqId;
@@ -9597,7 +9607,9 @@ public final class ViewRootImpl implements ViewParent,
        if ((mViewFrameInfo.flags & FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED) == 0
                && mWindowAttributes.type != TYPE_APPLICATION_STARTING
                && mSyncSeqId <= mLastSyncSeqId
                && (mSeqId <= mLastSeqId || !NoPreloadHolder.sAlwaysSeqId)
                && (!NoPreloadHolder.sAlwaysSeqId
                    || mSeqId <= mLastSeqId
                    || mSeqId <= mNonSyncEarlySeqId)
                && winConfigFromAm.diff(winConfigFromWm, false /* compareUndefined */) == 0) {
            final InsetsState state = mInsetsController.getState();
            final Rect displayCutoutSafe = mTempRect;
@@ -9688,9 +9700,13 @@ public final class ViewRootImpl implements ViewParent,
                    mPendingActivityWindowInfo.set(outInfo);
                }
            }
            final int maybeSyncSeqId = mRelayoutResult.syncSeqId;
            if (maybeSyncSeqId > (NoPreloadHolder.sAlwaysSeqId ? mSyncSeqId : 0)) {
                mSyncSeqId = maybeSyncSeqId;
            if (NoPreloadHolder.sAlwaysSeqId) {
                // mRelayoutResult.syncSeqId is a legacy name. In practice, with sAlwaysSeqId, it
                // has been repurposed to be "the highest (non-sync) seqId that this relayout
                // result is valid for". See docstring on mNonSyncEarlySeqId for more info.
                mNonSyncEarlySeqId = Math.max(mRelayoutResult.syncSeqId, mNonSyncEarlySeqId);
            } else if (mRelayoutResult.syncSeqId > 0) {
                mSyncSeqId = mRelayoutResult.syncSeqId;
            }
            mWinFrameInScreen.set(mTmpFrames.frame);
+40 −4
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ import static com.android.server.wm.SensitiveContentPackages.PackageInfo;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
@@ -2431,7 +2432,12 @@ public class WindowManagerService extends IWindowManager.Stub
                return false;
            }

            return win.cancelAndRedraw(seqId);
            final boolean cancel = win.cancelAndRedraw(seqId);
            if (cancel && Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancelDraw clientSeqId=" + seqId
                        + " serverSeqId=" + win.mSyncSeqId + " bufferSeqId=" + win.mBufferSeqId);
            }
            return cancel;
        }
    }

@@ -2480,6 +2486,11 @@ public class WindowManagerService extends IWindowManager.Stub
                // The client has reported the sync draw, but we haven't finished it yet.
                // Don't let the client perform a non-sync draw at this time.
                result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
                if (mAlwaysSeqId && Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.instant(TRACE_TAG_WINDOW_MANAGER, "earlyCancelDraw clientSeqId="
                            + syncSeqId + " serverSeqId=" + win.mSyncSeqId
                            + " bufferSeqId=" + win.mBufferSeqId);
                }
            }

            final DisplayContent displayContent = win.getDisplayContent();
@@ -2854,12 +2865,37 @@ public class WindowManagerService extends IWindowManager.Stub
                            : -1;
                    win.markRedrawForSyncReported();
                } else {
                    if (mAlwaysSeqId && win.cancelAndRedraw(syncSeqId)) {
                    outRelayoutResult.syncSeqId = -1;
                    if (mAlwaysSeqId && (result & RELAYOUT_RES_CANCEL_AND_REDRAW) == 0
                            && win.cancelAndRedraw(syncSeqId)) {
                        // Surface-placement has resulted in a new configuration or a new sync,
                        // so this current layout is invalid until subsequent reportResized.

                        // However, make a targeted optimization to let the client draw early if the
                        // relayout result won't change even after the client receives the new
                        // configuration. If there is an explicit sync, though, the user-perceived
                        // latency will be worse due to the client drawing content that won't be
                        // presented; so, don't "optimize" in that case.
                        final boolean inExplicitSync = syncSeqId <= win.mBufferSeqId
                                || win.mSyncState == SYNC_STATE_WAITING_FOR_DRAW;
                        if (!inExplicitSync && win.layoutIgnoresClientConfig()) {
                            // Returning a seqId indicates, to the client, that it can use this
                            // result even though it's configuration is out-dated.
                            outRelayoutResult.syncSeqId = win.mSyncSeqId;
                            if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                                Trace.instant(TRACE_TAG_WINDOW_MANAGER, "ignoreCancelDraw seqId="
                                        + win.mSyncSeqId);
                            }
                        } else {
                            result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
                            if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                                Trace.instant(TRACE_TAG_WINDOW_MANAGER, "lateCancelDraw "
                                        + " clientSeqId=" + syncSeqId
                                        + " serverSeqId=" + win.mSyncSeqId
                                        + " bufferSeqId=" + win.mBufferSeqId);
                            }
                        }
                    }
                    outRelayoutResult.syncSeqId = -1;
                }
            }

+19 −6
Original line number Diff line number Diff line
@@ -6138,12 +6138,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        if (!mWmService.mAlwaysSeqId) {
            return mPrepareSyncSeqId > 0;
        }
        final boolean cancel = Math.max(mSyncSeqId, mBufferSeqId) > seqId;
        if (cancel) {
            Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancelDraw clientSeqId=" + seqId
                    + " serverSeqId=" + mSyncSeqId + " bufferSeqId=" + mBufferSeqId);
        return Math.max(mSyncSeqId, mBufferSeqId) > seqId;
    }
        return cancel;

    /**
     * Normally, if the client hasn't received the latest configuration yet, we can't assume that
     * the layout parameters are accurate (since they can depend on the configuration).
     *
     * However, there are specific situations where layout logic ignores configuration-dependent
     * layout params AND where we are confident that those layout params aren't, themselves,
     * configuration-dependent. We can use this information for certain optimizations.
     *
     * @return {@code true} if this window's client configuration is irrelevant to layout.
     */
    boolean layoutIgnoresClientConfig() {
        // We are only confident that fullscreen system-ui windows remain fullscreen regardless of
        // of configuration.
        return mActivityRecord == null && !mIsWallpaper
                && mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT
                && mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT;
    }

    public boolean isActivityWindow() {