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

Commit 4659a118 authored by Robert Carr's avatar Robert Carr
Browse files

WindowStateAnimator: Abstract global transaction usage (1/n).

For the BLASTSyncEngine we will need all WSA GlobalTransaction
usage to be redirected to the pending transaction instead.

To prepare for this we first slimmed down WSA as much as possible
to make the remaining job easier. As a next step we start refactoring
code to use a passed in Transaction, but without chasing the global
Transaction all the way to the top. To do this we expose the global
transaction from SurfaceControl.java but with a special wrapper
that makes sure we don't accidentally call apply directly.

As we start cleaning up global transaction usage we can remove some
variants in WindowSurfaceController. In this CL we get setMatrix
and setPosition global variants removed.

Bug: 161937501
Test: Existing tests pass
Change-Id: Ibd8f710c8ca01e57f6f994f23dd7bf2dca3902fd
parent 5a964a3f
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -268,7 +268,7 @@ public final class SurfaceControl implements Parcelable {

    private WeakReference<View> mLocalOwnerView;

    static Transaction sGlobalTransaction;
    static GlobalTransactionWrapper sGlobalTransaction;
    static long sTransactionNestCount = 0;

    /**
@@ -1454,7 +1454,7 @@ public final class SurfaceControl implements Parcelable {
    public static void openTransaction() {
        synchronized (SurfaceControl.class) {
            if (sGlobalTransaction == null) {
                sGlobalTransaction = new Transaction();
                sGlobalTransaction = new GlobalTransactionWrapper();
            }
            synchronized(SurfaceControl.class) {
                sTransactionNestCount++;
@@ -1488,7 +1488,7 @@ public final class SurfaceControl implements Parcelable {
            } else if (--sTransactionNestCount > 0) {
                return;
            }
            sGlobalTransaction.apply();
            sGlobalTransaction.applyGlobalTransaction(false);
        }
    }

@@ -2556,7 +2556,10 @@ public final class SurfaceControl implements Parcelable {
            nativeApplyTransaction(mNativeObject, sync);
        }

        private void applyResizedSurfaces() {
        /**
         * @hide
         */
        protected void applyResizedSurfaces() {
            for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) {
                final Point size = mResizedSurfaces.valueAt(i);
                final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i);
@@ -2568,7 +2571,10 @@ public final class SurfaceControl implements Parcelable {
            mResizedSurfaces.clear();
        }

        private void notifyReparentedSurfaces() {
        /**
         * @hide
         */
        protected void notifyReparentedSurfaces() {
            final int reparentCount = mReparentedSurfaces.size();
            for (int i = reparentCount - 1; i >= 0; i--) {
                final SurfaceControl child = mReparentedSurfaces.keyAt(i);
@@ -3406,6 +3412,26 @@ public final class SurfaceControl implements Parcelable {
        }
    }

    /**
     * As part of eliminating usage of the global Transaction we expose
     * a SurfaceControl.getGlobalTransaction function. However calling
     * apply on this global transaction (rather than using closeTransaction)
     * would be very dangerous. So for the global transaction we use this
     * subclass of Transaction where the normal apply throws an exception.
     */
    private static class GlobalTransactionWrapper extends SurfaceControl.Transaction {
        void applyGlobalTransaction(boolean sync) {
            applyResizedSurfaces();
            notifyReparentedSurfaces();
            nativeApplyTransaction(mNativeObject, sync);
        }

        @Override
        public void apply(boolean sync) {
            throw new RuntimeException("Global transaction must be applied from closeTransaction");
        }
    }

    /**
     * Acquire a frame rate flexibility token, which allows surface flinger to freely switch display
     * frame rates. This is used by CTS tests to put the device in a consistent state. See
@@ -3426,4 +3452,17 @@ public final class SurfaceControl implements Parcelable {
    public static void releaseFrameRateFlexibilityToken(long token) {
        nativeReleaseFrameRateFlexibilityToken(token);
    }

    /**
     * This is a refactoring utility function to enable lower levels of code to be refactored
     * from using the global transaction (and instead use a passed in Transaction) without
     * having to refactor the higher levels at the same time.
     * The returned global transaction can't be applied, it must be applied from closeTransaction
     * Unless you are working on removing Global Transaction usage in the WindowManager, this
     * probably isn't a good function to use.
     * @hide
     */
    public static Transaction getGlobalTransaction() {
        return sGlobalTransaction;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -5322,7 +5322,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        // Send information to SufaceFlinger about the priority of the current window.
        updateFrameRateSelectionPriorityIfNeeded();

        mWinAnimator.prepareSurfaceLocked(true);
        mWinAnimator.prepareSurfaceLocked(SurfaceControl.getGlobalTransaction(), true);
        notifyBlastSyncTransaction();
        super.prepareSurfaces();
    }
+20 −19
Original line number Diff line number Diff line
@@ -652,7 +652,7 @@ class WindowStateAnimator {
      return true;
    }

    void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
    void setSurfaceBoundariesLocked(SurfaceControl.Transaction t, final boolean recoveringMemory) {
        if (mSurfaceController == null) {
            return;
        }
@@ -662,11 +662,11 @@ class WindowStateAnimator {
        final Task task = w.getTask();

        if (shouldConsumeMainWindowSizeTransaction()) {
            task.getMainWindowSizeChangeTask().getSurfaceControl().deferTransactionUntil(
            t.deferTransactionUntil(task.getMainWindowSizeChangeTask().getSurfaceControl(),
                mWin.getClientViewRootSurface(), mWin.getFrameNumber());
            mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
                    mWin.getFrameNumber());
            SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());
            t.deferTransactionUntil(mSurfaceController.mSurfaceControl,
                mWin.getClientViewRootSurface(), mWin.getFrameNumber());
            t.merge(task.getMainWindowSizeChangeTransaction());
            task.setMainWindowSizeChangeTransaction(null);
        }

@@ -691,8 +691,8 @@ class WindowStateAnimator {
                    // the WS position is reset (so the stack position is shown) at the same
                    // time that the buffer size changes.
                    setOffsetPositionForStackResize(false);
                    mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
                            mWin.getFrameNumber());
                    t.deferTransactionUntil(mSurfaceController.mSurfaceControl,
                        mWin.getClientViewRootSurface(), mWin.getFrameNumber());
                } else {
                    final Task stack = mWin.getRootTask();
                    mTmpPos.x = 0;
@@ -705,9 +705,9 @@ class WindowStateAnimator {
                }
            }
            if (!mIsWallpaper) {
                mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory);
                mSurfaceController.setPosition(t, xOffset, yOffset, recoveringMemory);
            } else {
                setWallpaperPositionAndScale(
                setWallpaperPositionAndScale(t,
                        xOffset, yOffset, mWallpaperScale, recoveringMemory);
            }
        }
@@ -716,7 +716,7 @@ class WindowStateAnimator {
            // Wallpaper is already updated above when calling setWallpaperPositionAndScale so
            // we only need to consider the non-wallpaper case here.
            if (!mIsWallpaper) {
                mSurfaceController.setMatrixInTransaction(
                mSurfaceController.setMatrix(t,
                    mDsDx * w.mHScale,
                    mDtDx * w.mVScale,
                    mDtDy * w.mHScale,
@@ -738,7 +738,7 @@ class WindowStateAnimator {
        }
    }

    void prepareSurfaceLocked(final boolean recoveringMemory) {
    void prepareSurfaceLocked(SurfaceControl.Transaction t, final boolean recoveringMemory) {
        final WindowState w = mWin;
        if (!hasSurface()) {

@@ -755,7 +755,7 @@ class WindowStateAnimator {

        computeShownFrameLocked();

        setSurfaceBoundariesLocked(recoveringMemory);
        setSurfaceBoundariesLocked(t, recoveringMemory);

        if (mIsWallpaper && !w.mWallpaperVisible) {
            // Wallpaper is no longer visible and there is no wp target => hide it.
@@ -797,7 +797,7 @@ class WindowStateAnimator {
            boolean prepared = true;

            if (mIsWallpaper) {
                setWallpaperPositionAndScale(
                setWallpaperPositionAndScale(t,
                        mXOffset, mYOffset, mWallpaperScale, recoveringMemory);
            } else {
                prepared =
@@ -884,7 +884,8 @@ class WindowStateAnimator {
                    Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
                }
                mService.openSurfaceTransaction();
                setWallpaperPositionAndScale(dx, dy, scale, false);
                setWallpaperPositionAndScale(SurfaceControl.getGlobalTransaction(),
                    dx, dy, scale, false);
            } catch (RuntimeException e) {
                Slog.w(TAG, "Error positioning surface of " + mWin
                        + " pos=(" + dx + "," + dy + ")", e);
@@ -899,8 +900,8 @@ class WindowStateAnimator {
        return true;
    }

    private void setWallpaperPositionAndScale(int dx, int dy, float scale,
            boolean recoveringMemory) {
    private void setWallpaperPositionAndScale(SurfaceControl.Transaction t,
        int dx, int dy, float scale, boolean recoveringMemory) {
        DisplayInfo displayInfo = mWin.getDisplayInfo();
        Matrix matrix = mWin.mTmpMatrix;
        matrix.setTranslate(dx, dy);
@@ -909,9 +910,9 @@ class WindowStateAnimator {
        matrix.getValues(mWin.mTmpMatrixArray);
        matrix.reset();

        mSurfaceController.setPositionInTransaction(mWin.mTmpMatrixArray[MTRANS_X],
        mSurfaceController.setPosition(t,mWin.mTmpMatrixArray[MTRANS_X],
                mWin.mTmpMatrixArray[MTRANS_Y], recoveringMemory);
        mSurfaceController.setMatrixInTransaction(
        mSurfaceController.setMatrix(t,
                mDsDx * mWin.mTmpMatrixArray[MSCALE_X] * mWin.mHScale,
                mDtDx * mWin.mTmpMatrixArray[MSKEW_Y] * mWin.mVScale,
                mDtDy * mWin.mTmpMatrixArray[MSKEW_X] * mWin.mHScale,
+2 −19
Original line number Diff line number Diff line
@@ -236,10 +236,6 @@ class WindowSurfaceController {
        }
    }

    void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
        setPosition(null, left, top, recoveringMemory);
    }

    void setPosition(SurfaceControl.Transaction t, float left, float top,
            boolean recoveringMemory) {
        final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
@@ -251,11 +247,7 @@ class WindowSurfaceController {
                ProtoLog.i(WM_SHOW_TRANSACTIONS,
                        "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s", left, top, title);

                if (t == null) {
                    mSurfaceControl.setPosition(left, top);
                } else {
                t.setPosition(mSurfaceControl, left, top);
                }
            } catch (RuntimeException e) {
                Slog.w(TAG, "Error positioning surface of " + this
                        + " pos=(" + left + "," + top + ")", e);
@@ -266,11 +258,6 @@ class WindowSurfaceController {
        }
    }

    void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
            boolean recoveringMemory) {
        setMatrix(null, dsdx, dtdx, dtdy, dsdy, false);
    }

    void setMatrix(SurfaceControl.Transaction t, float dsdx, float dtdx,
            float dtdy, float dsdy, boolean recoveringMemory) {
        final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
@@ -287,11 +274,7 @@ class WindowSurfaceController {
        try {
            ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE MATRIX [%f,%f,%f,%f]: %s",
                    dsdx, dtdx, dtdy, dsdy, title);
            if (t == null) {
                mSurfaceControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
            } else {
            t.setMatrix(mSurfaceControl, dsdx, dtdx, dtdy, dsdy);
            }
        } catch (RuntimeException e) {
            // If something goes wrong with the surface (such
            // as running out of memory), don't take down the