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

Commit 215c18cf authored by Chavi Weingarten's avatar Chavi Weingarten
Browse files

Use passed in Transaction when creating bounds layer in VRI

When the bounds layer is created, the visibility and initial bounds are set
using a new transaction that is applied immediately. This can cause a
race condition because the initial bounds are sent using a different
apply token than the buffer updates. When the crop for the bounds layer is
updated, that is sent in sync with the BBQ frame which has a separate
apply token. This means the updated bounds can be applied before the
intial bounds, causing unexpected behavior.

Test: testCropWithChildBoundingInsets 100 times
Bug: 288339794
Change-Id: I61776050e99d8fa9524a7b6e4fe6034c171d49a7
parent 7baeec3c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1340,7 +1340,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                    .setName(name)
                    .setLocalOwnerView(this)
                    .setParent(viewRoot.getBoundsLayer())
                    .setParent(viewRoot.updateAndGetBoundsLayer(surfaceUpdateTransaction))
                    .setCallsite("SurfaceView.updateSurface")
                    .setContainerLayer()
                    .build();
+8 −7
Original line number Diff line number Diff line
@@ -716,9 +716,9 @@ public final class ViewRootImpl implements ViewParent,

    /**
     * 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 region set by the parent window.
     * the surface insets. This surface is created only if a client requests it via
     * {@link #updateAndGetBoundsLayer(Transaction)}. By parenting to this bounds surface, child
     * surfaces can ensure they do not draw into the surface inset region set by the parent window.
     */
    private SurfaceControl mBoundsLayer;
    private final SurfaceSession mSurfaceSession = new SurfaceSession();
@@ -2262,7 +2262,7 @@ public final class ViewRootImpl implements ViewParent,
     * <p>Parenting to this layer will ensure that its children are cropped by the view's surface
     * insets.
     */
    public SurfaceControl getBoundsLayer() {
    public SurfaceControl updateAndGetBoundsLayer(Transaction t) {
        if (mBoundsLayer == null) {
            mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession)
                    .setContainerLayer()
@@ -2270,8 +2270,8 @@ public final class ViewRootImpl implements ViewParent,
                    .setParent(getSurfaceControl())
                    .setCallsite("ViewRootImpl.getBoundsLayer")
                    .build();
            setBoundsLayerCrop(mTransaction);
            mTransaction.show(mBoundsLayer).apply();
            setBoundsLayerCrop(t);
            t.show(mBoundsLayer);
        }
       return mBoundsLayer;
    }
@@ -11180,7 +11180,8 @@ public final class ViewRootImpl implements ViewParent,
    @Nullable public SurfaceControl.Transaction buildReparentTransaction(
        @NonNull SurfaceControl child) {
        if (mSurfaceControl.isValid()) {
          return new SurfaceControl.Transaction().reparent(child, getBoundsLayer());
            Transaction t = new Transaction();
            return t.reparent(child, updateAndGetBoundsLayer(t));
        }
        return null;
    }