Remove usages of global transaction
The performSurfacePlacement will prepare the operation in the
pending transaction and then let WindowAnimator apply it with
vsync. Since there are only few usages of global transaction,
the transaction applied from performSurfacePlacement is almost
only from DisplayContent#prepareSurface, so it is more efficient
to centralize with WindowAnimator.
This can reduce an IPC to surfaceflinger in every surface
placement, which should eliminate one of major cost.
Bug: 159103089
Test: CtsWindowManagerDeviceActivity
Change-Id: I67e4e58aced78a2f36163178a64ca55d3c77e6f3
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index eeeca10..816e0a2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -115,7 +115,6 @@
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
-import static android.view.SurfaceControl.getGlobalTransaction;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -5693,14 +5692,10 @@
// can be synchronized with showing the next surface in the transition.
if (!usingShellTransitions && !isVisible() && !delayed
&& !displayContent.mAppTransition.isTransitionSet()) {
- SurfaceControl.openTransaction();
- try {
- forAllWindows(win -> {
- win.mWinAnimator.hide(getGlobalTransaction(), "immediately hidden");
- }, true);
- } finally {
- SurfaceControl.closeTransaction();
- }
+ forAllWindows(win -> {
+ win.mWinAnimator.hide(getPendingTransaction(), "immediately hidden");
+ }, true);
+ scheduleAnimation();
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 777b5cd..e14d0fa 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1633,7 +1633,12 @@
}
}
- private void removeRootTaskInSurfaceTransaction(Task rootTask) {
+ /**
+ * Removes the root task associated with the given {@param rootTask}. If the {@param rootTask}
+ * is the pinned task, then its child tasks are not explicitly removed when the root task is
+ * destroyed, but instead moved back onto the TaskDisplayArea.
+ */
+ void removeRootTask(Task rootTask) {
if (rootTask.getWindowingMode() == WINDOWING_MODE_PINNED) {
removePinnedRootTaskInSurfaceTransaction(rootTask);
} else {
@@ -1644,15 +1649,6 @@
}
/**
- * Removes the root task associated with the given {@param task}. If the {@param task} is the
- * pinned task, then its child tasks are not explicitly removed when the root task is
- * destroyed, but instead moved back onto the TaskDisplayArea.
- */
- void removeRootTask(Task task) {
- mWindowManager.inSurfaceTransaction(() -> removeRootTaskInSurfaceTransaction(task));
- }
-
- /**
* Removes the task with the specified task id.
*
* @param taskId Identifier of the task to be removed.
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 805bff2..05087f8 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -71,7 +71,6 @@
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WallpaperAnimationAdapter.shouldStartWallpaperAnimation;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -82,7 +81,6 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
-import android.util.Slog;
import android.view.Display;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
@@ -1179,16 +1177,7 @@
}
app.updateReportedVisibilityLocked();
app.waitingToShow = false;
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- ">>> OPEN TRANSACTION handleAppTransitionReady()");
- mService.openSurfaceTransaction();
- try {
- app.showAllWindowsLocked();
- } finally {
- mService.closeSurfaceTransaction("handleAppTransitionReady");
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION handleAppTransitionReady()");
- }
+ app.showAllWindowsLocked();
if (mDisplayContent.mAppTransition.isNextAppTransitionThumbnailUp()) {
app.attachThumbnailAnimation();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7f80807..b910321 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5586,12 +5586,7 @@
void prepareSurfaces() {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
try {
- final Transaction transaction = getPendingTransaction();
super.prepareSurfaces();
-
- // TODO: Once we totally eliminate global transaction we will pass transaction in here
- // rather than merging to global.
- SurfaceControl.mergeToGlobalTransaction(transaction);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index b738c1c..5269d35 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -307,7 +307,7 @@
mService.stopAppSwitches();
}
- mWindowManager.inSurfaceTransaction(() -> {
+ inSurfaceTransaction(() -> {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
mService.deferWindowLayout();
@@ -419,6 +419,11 @@
}
}
+ // No-op wrapper to keep legacy code.
+ private static void inSurfaceTransaction(Runnable exec) {
+ exec.run();
+ }
+
/** Gives the owner of recents animation higher priority. */
private void setProcessAnimating(boolean animating) {
if (mCaller == null) return;
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index eb639b6..a98b9f7 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -307,7 +307,6 @@
mIsFinishing = true;
unlinkToDeathOfRunner();
releaseFinishedCallback();
- mService.openSurfaceTransaction();
try {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
"onAnimationFinished(): Notify animation finished:");
@@ -348,7 +347,6 @@
Slog.e(TAG, "Failed to finish remote animation", e);
throw e;
} finally {
- mService.closeSurfaceTransaction("RemoteAnimationController#finished");
mIsFinishing = false;
}
// Reset input for all activities when the remote animation is finished.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 5227a52..8038d6e 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -75,7 +75,6 @@
import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_INVISIBLE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
@@ -788,23 +787,13 @@
final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
- if (SHOW_LIGHT_TRANSACTIONS) {
- Slog.i(TAG,
- ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
- }
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
- mWmService.openSurfaceTransaction();
try {
applySurfaceChangesTransaction();
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
- mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- if (SHOW_LIGHT_TRANSACTIONS) {
- Slog.i(TAG,
- "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
- }
}
// Send any pending task-info changes that were queued-up during a layout deferment
@@ -998,9 +987,6 @@
// Give the display manager a chance to adjust properties like display rotation if it needs
// to.
mWmService.mDisplayManagerInternal.performTraversal(t);
- if (t != defaultDc.mSyncTransaction) {
- SurfaceControl.mergeToGlobalTransaction(t);
- }
}
/**
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index a778415..440f0eb 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4544,12 +4544,6 @@
* @param creating {@code true} if this is being run during task construction.
*/
void setWindowingMode(int preferredWindowingMode, boolean creating) {
- mWmService.inSurfaceTransaction(() -> setWindowingModeInSurfaceTransaction(
- preferredWindowingMode, creating));
- }
-
- private void setWindowingModeInSurfaceTransaction(int preferredWindowingMode,
- boolean creating) {
final TaskDisplayArea taskDisplayArea = getDisplayArea();
if (taskDisplayArea == null) {
Slog.d(TAG, "taskDisplayArea is null, bail early");
@@ -5965,18 +5959,16 @@
"Can't exit pinned mode if it's not pinned already.");
}
- mWmService.inSurfaceTransaction(() -> {
- final Task task = getBottomMostTask();
- setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ final Task task = getBottomMostTask();
+ setWindowingMode(WINDOWING_MODE_UNDEFINED);
- // Task could have been removed from the hierarchy due to windowing mode change
- // where its only child is reparented back to their original parent task.
- if (isAttached()) {
- getDisplayArea().positionChildAt(POSITION_TOP, this, false /* includingParents */);
- }
+ // Task could have been removed from the hierarchy due to windowing mode change
+ // where its only child is reparented back to their original parent task.
+ if (isAttached()) {
+ getDisplayArea().positionChildAt(POSITION_TOP, this, false /* includingParents */);
+ }
- mTaskSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
- });
+ mTaskSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
}
private int setBounds(Rect existing, Rect bounds) {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index e95d265..fd22f15 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -128,7 +128,6 @@
}
ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION animate");
- mService.openSurfaceTransaction();
try {
// Remove all deferred displays, tasks, and activities.
root.handleCompleteDeferredRemoval();
@@ -163,6 +162,7 @@
dc.mLastContainsRunningSurfaceAnimator = false;
dc.enableHighFrameRate(false);
}
+ mTransaction.merge(dc.getPendingTransaction());
}
cancelAnimation();
@@ -196,8 +196,8 @@
updateRunningExpensiveAnimationsLegacy();
}
- SurfaceControl.mergeToGlobalTransaction(mTransaction);
- mService.closeSurfaceTransaction("WindowAnimator");
+ mTransaction.apply();
+ mService.mWindowTracing.logState("WindowAnimator");
ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 55678c5..786fb40 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1054,29 +1054,6 @@
SystemPerformanceHinter mSystemPerformanceHinter;
- void openSurfaceTransaction() {
- try {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
- SurfaceControl.openTransaction();
- } finally {
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
- }
-
- /**
- * Closes a surface transaction.
- * @param where debug string indicating where the transaction originated
- */
- void closeSurfaceTransaction(String where) {
- try {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
- SurfaceControl.closeTransaction();
- mWindowTracing.logState(where);
- } finally {
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
- }
-
/** Listener to notify activity manager about app transitions. */
final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
= new WindowManagerInternal.AppTransitionListener() {
@@ -8576,39 +8553,6 @@
mAppFreezeListeners.remove(listener);
}
- /**
- * WARNING: This interrupts surface updates, be careful! Don't
- * execute within the transaction for longer than you would
- * execute on an animation thread.
- * WARNING: This method contains locks known to the State of California
- * to cause Deadlocks and other conditions.
- *
- * Begins a surface transaction with which the AM can batch operations.
- * All Surface updates performed by the WindowManager following this
- * will not appear on screen until after the call to
- * closeSurfaceTransaction.
- *
- * ActivityManager can use this to ensure multiple 'commands' will all
- * be reflected in a single frame. For example when reparenting a window
- * which was previously hidden due to it's parent properties, we may
- * need to ensure it is hidden in the same frame that the properties
- * from the new parent are inherited, otherwise it could be revealed
- * mistakenly.
- *
- * TODO(b/36393204): We can investigate totally replacing #deferSurfaceLayout
- * with something like this but it seems that some existing cases of
- * deferSurfaceLayout may be a little too broad, in particular the total
- * enclosure of startActivityUnchecked which could run for quite some time.
- */
- void inSurfaceTransaction(Runnable exec) {
- SurfaceControl.openTransaction();
- try {
- exec.run();
- } finally {
- SurfaceControl.closeTransaction();
- }
- }
-
/** Called to inform window manager if non-Vr UI shoul be disabled or not. */
public void disableNonVrUi(boolean disable) {
synchronized (mGlobalLock) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4e17011..6281ecd 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -29,7 +29,6 @@
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.SurfaceControl.Transaction;
-import static android.view.SurfaceControl.getGlobalTransaction;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -2794,7 +2793,7 @@
clearPolicyVisibilityFlag(LEGACY_POLICY_VISIBILITY);
}
if (!isVisibleByPolicy()) {
- mWinAnimator.hide(getGlobalTransaction(), "checkPolicyVisibilityChange");
+ mWinAnimator.hide(getPendingTransaction(), "checkPolicyVisibilityChange");
if (isFocused()) {
ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
"setAnimationLocked: setting mFocusMayChange true");
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 209d934..4238eb7 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -20,7 +20,6 @@
import static android.view.SurfaceControl.METADATA_OWNER_PID;
import static android.view.SurfaceControl.METADATA_OWNER_UID;
import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
-import static android.view.SurfaceControl.getGlobalTransaction;
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
@@ -157,14 +156,9 @@
if (mSurfaceControl == null) {
return;
}
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
- mService.openSurfaceTransaction();
- try {
- getGlobalTransaction().setOpaque(mSurfaceControl, isOpaque);
- } finally {
- mService.closeSurfaceTransaction("setOpaqueLocked");
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
- }
+
+ mAnimator.mWin.getPendingTransaction().setOpaque(mSurfaceControl, isOpaque);
+ mService.scheduleAnimationLocked();
}
void setSecure(boolean isSecure) {
@@ -174,18 +168,15 @@
return;
}
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
- mService.openSurfaceTransaction();
- try {
- getGlobalTransaction().setSecure(mSurfaceControl, isSecure);
- final DisplayContent dc = mAnimator.mWin.mDisplayContent;
- if (dc != null) {
- dc.refreshImeSecureFlag(getGlobalTransaction());
- }
- } finally {
- mService.closeSurfaceTransaction("setSecure");
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
+ final SurfaceControl.Transaction t = mAnimator.mWin.getPendingTransaction();
+ t.setSecure(mSurfaceControl, isSecure);
+
+ final DisplayContent dc = mAnimator.mWin.mDisplayContent;
+ if (dc != null) {
+ dc.refreshImeSecureFlag(t);
}
+ mService.scheduleAnimationLocked();
}
void setColorSpaceAgnostic(SurfaceControl.Transaction t, boolean agnostic) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index eaeb804..75d9d10 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -273,7 +273,6 @@
assertFalse(win.mHasSurface);
assertNull(win.mWinAnimator.mSurfaceController);
- doReturn(mSystemServicesTestRule.mTransaction).when(SurfaceControl::getGlobalTransaction);
// Invisible requested activity should not get the last config even if its view is visible.
mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);