From a27b862bc0f064a322a38cef2351f6de806ec0b8 Mon Sep 17 00:00:00 2001 From: Marzia Favaro Date: Fri, 6 Sep 2024 11:38:02 +0000 Subject: 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 --- .../android/window/flags/windowing_frontend.aconfig | 11 +++++++++++ .../android/server/wm/DimmerAnimationHelper.java | 21 +++++++++++++++------ .../java/com/android/server/wm/WindowContainer.java | 9 +++++++++ .../java/com/android/server/wm/WindowState.java | 17 +++++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index a786fc24d9a7..03e230c39f05 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -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" diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java index faf6dc667916..bc188959164d 100644 --- a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java +++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java @@ -109,7 +109,9 @@ public class DimmerAnimationHelper { // Sets the requested layer to reparent the dim to without applying it immediately void setRequestedGeometryParent(WindowContainer geometryParent) { - mRequestedProperties.mGeometryParent = geometryParent; + if (geometryParent != null) { + mRequestedProperties.mGeometryParent = geometryParent; + } } // Sets a requested change without applying it immediately @@ -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); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 1eeb3ecaf9d6..9d4652957487 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2874,6 +2874,15 @@ class 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. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 021be5727bf6..b5276303f6b9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4409,6 +4409,17 @@ class WindowState extends WindowContainer 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 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) { -- cgit v1.2.3-59-g8ed1b