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

Commit a27b862b authored by Marzia Favaro's avatar Marzia Favaro
Browse files

Update dim state when new window is drawn

We used to update the dim state only in prepareSurfaces, but this lead
to flickers with windows that were showing during a transition. Therefore,
when a new window is drawn, we recalculate the state of the possible
affected dim and update it in the same transaction.

Bug: 327332488
Test: DimmerTests
Flag: com.android.window.flags.update_dims_when_window_shown
Change-Id: Idc52a3ee6875218350e34ad44f1c28f6cb5666a1
parent 31068add
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -180,6 +180,17 @@ flag {
  }
}

flag {
  name: "update_dims_when_window_shown"
  namespace: "windowing_frontend"
  description: "Check if we need to update dim layers when a new window draws the first frame"
  bug: "327332488"
  is_fixed_read_only: true
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
    name: "release_snapshot_aggressively"
    namespace: "windowing_frontend"
+15 −6
Original line number Diff line number Diff line
@@ -109,8 +109,10 @@ public class DimmerAnimationHelper {

    // Sets the requested layer to reparent the dim to without applying it immediately
    void setRequestedGeometryParent(WindowContainer<?> geometryParent) {
        if (geometryParent != null) {
            mRequestedProperties.mGeometryParent = geometryParent;
        }
    }

    // Sets a requested change without applying it immediately
    void setRequestedAppearance(float alpha, int blurRadius) {
@@ -139,9 +141,14 @@ public class DimmerAnimationHelper {
            dim.remove(t);
            return;
        }
        if (!dim.mDimSurface.isValid()) {
            Log.e(TAG, "Dimming surface " + dim.mDimSurface + " has already been released!"
                    + " Can not apply changes.");
            return;
        }

        dim.ensureVisible(t);
        reparent(dim.mDimSurface,
        reparent(dim,
                startProperties.mGeometryParent != mRequestedProperties.mGeometryParent
                        ? mRequestedProperties.mGeometryParent.getSurfaceControl() : null,
                mRequestedProperties.mDimmingContainer != startProperties.mDimmingContainer
@@ -159,7 +166,7 @@ public class DimmerAnimationHelper {
                        "%s skipping animation and directly setting alpha=%f, blur=%d",
                        dim, startProperties.mAlpha,
                        mRequestedProperties.mBlurRadius);
                setCurrentAlphaBlur(dim.mDimSurface, t);
                setCurrentAlphaBlur(dim, t);
                dim.mSkipAnimation = false;
            } else {
                startAnimation(t, dim, startProperties, mRequestedProperties);
@@ -186,7 +193,7 @@ public class DimmerAnimationHelper {
                    synchronized (dim.mHostContainer.mWmService.mGlobalLock) {
                        SurfaceControl.Transaction finishTransaction =
                                dim.mHostContainer.getSyncTransaction();
                        setCurrentAlphaBlur(dim.mDimSurface, finishTransaction);
                        setCurrentAlphaBlur(dim, finishTransaction);
                        if (targetAlpha == 0f && !dim.isDimming()) {
                            dim.remove(finishTransaction);
                        }
@@ -229,10 +236,11 @@ public class DimmerAnimationHelper {
    /**
     * Change the geometry and relative parent of this dim layer
     */
    static void reparent(@NonNull SurfaceControl dimLayer,
    void reparent(@NonNull Dimmer.DimState dim,
                  @Nullable SurfaceControl newGeometryParent,
                  @Nullable SurfaceControl newRelativeParent,
                  @NonNull SurfaceControl.Transaction t) {
        final SurfaceControl dimLayer = dim.mDimSurface;
        try {
            if (newGeometryParent != null) {
                t.reparent(dimLayer, newGeometryParent);
@@ -245,7 +253,8 @@ public class DimmerAnimationHelper {
        }
    }

    void setCurrentAlphaBlur(@NonNull SurfaceControl sc, @NonNull SurfaceControl.Transaction t) {
    void setCurrentAlphaBlur(@NonNull Dimmer.DimState dim, @NonNull SurfaceControl.Transaction t) {
        final SurfaceControl sc = dim.mDimSurface;
        try {
            t.setAlpha(sc, mCurrentProperties.mAlpha);
            t.setBackgroundBlurRadius(sc, mCurrentProperties.mBlurRadius);
+9 −0
Original line number Diff line number Diff line
@@ -2874,6 +2874,15 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        }
    }

    /**
     * Go through the hierarchy to allow windows to request a dim if needed
     */
    void adjustDims() {
        for (int i = 0; i < mChildren.size(); i++) {
            mChildren.get(i).adjustDims();
        }
    }

    /**
     * Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
     * will be applied.
+17 −0
Original line number Diff line number Diff line
@@ -4409,6 +4409,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        for (int i = mChildren.size() - 1; i >= 0; i--) {
            committed |= mChildren.get(i).commitFinishDrawing(t);
        }

        // When a new activity is showing, update dim in this transaction
        if (Flags.updateDimsWhenWindowShown()) {
            final Dimmer dimmer = getDimController();
            final WindowContainer<?> dimParent = getDimParent();
            if (dimmer != null && dimParent != null) {
                dimParent.adjustDims();
                dimmer.updateDims(t);
            }
        }

        // In case commitFinishDrawingLocked starts a window level animation, make sure the surface
        // operation (reparent to leash) is synced with the visibility by transition.
        if (getAnimationLeash() != null) {
@@ -5304,6 +5315,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        super.prepareSurfaces();
    }

    @Override
    void adjustDims() {
        applyDims();
        super.adjustDims();
    }

    void updateSurfacePositionIfNeeded() {
        if (mWindowFrames.mRelFrame.top == mWindowFrames.mLastRelFrame.top
                && mWindowFrames.mRelFrame.left == mWindowFrames.mLastRelFrame.left) {