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

Commit 00c3a02a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove references of the previous surface control in ViewRootImpl"

parents b8c81408 eaab0e5a
Loading
Loading
Loading
Loading
+14 −40
Original line number Diff line number Diff line
@@ -97,8 +97,7 @@ import java.util.concurrent.locks.ReentrantLock;
 * artifacts may occur on previous versions of the platform when its window is
 * positioned asynchronously.</p>
 */
public class SurfaceView extends View
        implements ViewRootImpl.WindowStoppedCallback, ViewRootImpl.SurfaceChangedCallback {
public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
    private static final String TAG = "SurfaceView";
    private static final boolean DEBUG = false;

@@ -120,7 +119,7 @@ public class SurfaceView extends View
    boolean mDrawFinished = false;

    final Rect mScreenRect = new Rect();
    final SurfaceSession mSurfaceSession = new SurfaceSession();
    SurfaceSession mSurfaceSession;

    SurfaceControl mSurfaceControl;
    // In the case of format changes we switch out the surface in-place
@@ -243,22 +242,11 @@ public class SurfaceView extends View
        updateSurface();
    }

    /** @hide */
    @Override
    public void surfaceChangedCallback(SurfaceControl.Transaction transaction) {
        if (getViewRootImpl() != null && mBackgroundControl != null && mSurfaceControl != null) {
            SurfaceControl sc = getViewRootImpl().getSurfaceControl();
            transaction.setRelativeLayer(mBackgroundControl, sc, Integer.MIN_VALUE);
            transaction.setRelativeLayer(mSurfaceControl, sc, mSubLayer);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        getViewRootImpl().addWindowStoppedCallback(this);
        getViewRootImpl().addSurfaceChangedCallback(this);
        mWindowStopped = false;

        mViewVisibility = getVisibility() == VISIBLE;
@@ -333,7 +321,6 @@ public class SurfaceView extends View
        // the SurfaceHolder forward, most live wallpapers do it.
        if (viewRoot != null) {
            viewRoot.removeWindowStoppedCallback(this);
            viewRoot.removeSurfaceChangedCallback(this);
        }

        mAttachedToWindow = false;
@@ -615,32 +602,19 @@ public class SurfaceView extends View
                mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);

                if (creating) {
                    viewRoot.createBoundsSurface(mSubLayer);
                    mSurfaceSession = new SurfaceSession();
                    mDeferredDestroySurfaceControl = mSurfaceControl;

                    updateOpaqueFlag();
                    // SurfaceView hierarchy
                    // ViewRootImpl surface
                    //   - bounds layer (crops all child surfaces to parent surface insets)
                    //     - SurfaceView surface (drawn relative to ViewRootImpl surface)
                    //     - Background color layer (drawn behind all SurfaceView surfaces)
                    //
                    // The bounds layer is used to crop the surface view so it does not draw into
                    // the parent surface inset region. Since there can be multiple surface views
                    // below or above the parent surface, one option is to create multiple bounds
                    // layer for each z order. The other option, the one implement is to create
                    // a single bounds layer and set z order for each child surface relative to the
                    // parent surface.
                    // When creating the surface view, we parent it to the bounds layer and then
                    // set the relative z order. When the parent surface changes, we have to
                    // make sure to update the relative z via ViewRootImpl.SurfaceChangedCallback.
                    final String name = "SurfaceView - " + viewRoot.getTitle().toString();
                    mSurfaceControl =
                            new SurfaceControl.Builder(mSurfaceSession)

                    mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                        .setName(name)
                        .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
                        .setBufferSize(mSurfaceWidth, mSurfaceHeight)
                        .setFormat(mFormat)
                                    .setParent(viewRoot.getBoundsLayer())
                        .setParent(viewRoot.getSurfaceControl())
                        .setFlags(mSurfaceFlags)
                        .build();
                    mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
@@ -665,7 +639,7 @@ public class SurfaceView extends View

                    SurfaceControl.openTransaction();
                    try {
                        mSurfaceControl.setRelativeLayer(viewRoot.getSurfaceControl(), mSubLayer);
                        mSurfaceControl.setLayer(mSubLayer);

                        if (mViewVisibility) {
                            mSurfaceControl.show();
+44 −68
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -477,19 +476,17 @@ public final class ViewRootImpl implements ViewParent,
    @UnsupportedAppUsage
    public final Surface mSurface = new Surface();
    private final SurfaceControl mSurfaceControl = new SurfaceControl();
    private IBinder mPreviousSurfaceControlHandle = null;

    private final Transaction mChangeSurfaceTransaction = new Transaction();
    private final SurfaceSession mSurfaceSession = new SurfaceSession();

    /**
     * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
     * the surface insets. This surface is created only if a client requests it via {@link
     * #getBoundsLayer()}. By parenting to this bounds surface, child surfaces can ensure they do
     * not draw into the surface inset regions set by the parent window.
     * Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds
     * are set to the parent's bounds adjusted for surface insets. This surface is created when
     * {@link ViewRootImpl#createBoundsSurface(int)} is called.
     * By parenting to this bounds surface, child surfaces can ensure they do not draw into the
     * surface inset regions set by the parent window.
     */
    private SurfaceControl mBoundsLayer;

    public final Surface mBoundsSurface = new Surface();
    private SurfaceSession mSurfaceSession;
    private SurfaceControl mBoundsSurfaceControl;
    private final Transaction mTransaction = new Transaction();

    @UnsupportedAppUsage
@@ -1579,76 +1576,65 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    /** Register callback to be notified when the ViewRootImpl surface changes. */
    interface SurfaceChangedCallback {
        void surfaceChangedCallback(SurfaceControl.Transaction transaction);
    }

    private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>();
    void addSurfaceChangedCallback(SurfaceChangedCallback c) {
        mSurfaceChangedCallbacks.add(c);
    }

    void removeSurfaceChangedCallback(SurfaceChangedCallback c) {
        mSurfaceChangedCallbacks.remove(c);
    }

    private void notifySurfaceChanged(SurfaceControl.Transaction transaction) {
        for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
            mSurfaceChangedCallbacks.get(i).surfaceChangedCallback(transaction);
        }
    }

    /**
     * Returns a child layer with the same bounds as its parent {@code mSurface} and cropped to the
     * surface insets. If the layer does not exist, it is created.
     * Creates a surface as a child of {@code mSurface} with the same bounds as its parent and
     * crop bounds set to the parent's bounds adjusted for surface insets.
     *
     * <p>Parenting to this layer will ensure that its children are cropped by the view's surface
     * insets.
     * @param zOrderLayer Z order relative to the parent surface.
     */
    public SurfaceControl getBoundsLayer() {
        if (mBoundsLayer == null) {
            mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession)
                .setContainerLayer()
    public void createBoundsSurface(int zOrderLayer) {
        if (mSurfaceSession == null) {
            mSurfaceSession = new SurfaceSession();
        }
        if (mBoundsSurfaceControl != null && mBoundsSurface.isValid()) {
            return; // surface control for bounds surface already exists.
        }

        mBoundsSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                .setName("Bounds for - " + getTitle().toString())
                .setParent(mSurfaceControl)
                .build();

            setBoundsLayerCrop(mTransaction);
            mTransaction.show(mBoundsLayer).apply();
        }
        return mBoundsLayer;
        setBoundsSurfaceCrop();
        mTransaction.setLayer(mBoundsSurfaceControl, zOrderLayer)
                    .show(mBoundsSurfaceControl)
                    .apply();
        mBoundsSurface.copyFrom(mBoundsSurfaceControl);
    }

    private void setBoundsLayerCrop(Transaction t) {
    private void setBoundsSurfaceCrop() {
        // mWinFrame is already adjusted for surface insets. So offset it and use it as
        // the cropping bounds.
        mTempBoundsRect.set(mWinFrame);
        mTempBoundsRect.offsetTo(mWindowAttributes.surfaceInsets.left,
                mWindowAttributes.surfaceInsets.top);
        t.setWindowCrop(mBoundsLayer, mTempBoundsRect);
        mTransaction.setWindowCrop(mBoundsSurfaceControl, mTempBoundsRect);
    }

    /**
     * Called after window layout to update the bounds surface. If the surface insets have changed
     * or the surface has resized, update the bounds surface.
     * Called after window layout to update the bounds surface. If the surface insets have
     * changed or the surface has resized, update the bounds surface.
     */
    private void updateBoundsLayer() {
        if (mBoundsLayer != null) {
            setBoundsLayerCrop(mTransaction);
            mTransaction.deferTransactionUntilSurface(mBoundsLayer,
    private void updateBoundsSurface() {
        if (mBoundsSurfaceControl != null && mSurface.isValid()) {
            setBoundsSurfaceCrop();
            mTransaction.deferTransactionUntilSurface(mBoundsSurfaceControl,
                    mSurface, mSurface.getNextFrameNumber())
                    .apply();
        }
    }

    private void destroySurface() {
        if (mBoundsLayer != null) {
            mBoundsLayer.release();
            mBoundsLayer = null;
        }
        mSurface.release();
        mSurfaceControl.release();

        mSurfaceSession = null;

        if (mBoundsSurfaceControl != null) {
            mBoundsSurfaceControl.remove();
            mBoundsSurface.release();
            mBoundsSurfaceControl = null;
        }
    }

    /**
@@ -2612,7 +2598,7 @@ public final class ViewRootImpl implements ViewParent,
        }

        if (surfaceSizeChanged) {
            updateBoundsLayer();
            updateBoundsSurface();
        }

        final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
@@ -3452,9 +3438,7 @@ public final class ViewRootImpl implements ViewParent,
    private void reportDrawFinished() {
        try {
            mDrawsNeededToReport = 0;
            if (mSurfaceControl.isValid()) {
                mWindowSession.finishDrawing(mWindow, mChangeSurfaceTransaction);
            }
            mWindowSession.finishDrawing(mWindow, null /* postDrawTransaction */);
        } catch (RemoteException e) {
            // Have fun!
        }
@@ -7107,9 +7091,6 @@ public final class ViewRootImpl implements ViewParent,
            frameNumber = mSurface.getNextFrameNumber();
        }

        mPreviousSurfaceControlHandle = mSurfaceControl.isValid()
                ? mSurfaceControl.getHandle() : null;

        int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
@@ -7123,11 +7104,6 @@ public final class ViewRootImpl implements ViewParent,
            destroySurface();
        }

        if (mPreviousSurfaceControlHandle != null && mSurfaceControl.isValid()
                && mPreviousSurfaceControlHandle != mSurfaceControl.getHandle()) {
            notifySurfaceChanged(mChangeSurfaceTransaction);
        }

        mPendingAlwaysConsumeSystemBars =
                (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;