Merge "Reduce switch split flicker on protrait split" into tm-qpr-dev am: 86fa95f3a4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20263254

Change-Id: Ic7b8e181a4c866ac78336d1500ffa208ebdd0a16
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-11-01 13:03:28 +00:00
committed by Automerger Merge Worker
2 changed files with 46 additions and 20 deletions

View File

@@ -69,6 +69,7 @@ import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.function.Consumer;
/** /**
* Records and handles layout of splits. Helps to calculate proper bounds when configuration or * Records and handles layout of splits. Helps to calculate proper bounds when configuration or
@@ -599,7 +600,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
/** Swich both surface position with animation. */ /** Swich both surface position with animation. */
public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1, public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1,
SurfaceControl leash2, Runnable finishCallback) { SurfaceControl leash2, Consumer<Rect> finishCallback) {
final boolean isLandscape = isLandscape(); final boolean isLandscape = isLandscape();
final Rect insets = getDisplayInsets(mContext); final Rect insets = getDisplayInsets(mContext);
insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top, insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top,
@@ -617,18 +618,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
distBounds1.offset(-mRootBounds.left, -mRootBounds.top); distBounds1.offset(-mRootBounds.left, -mRootBounds.top);
distBounds2.offset(-mRootBounds.left, -mRootBounds.top); distBounds2.offset(-mRootBounds.left, -mRootBounds.top);
distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top); distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top);
// DO NOT move to insets area for smooth animation.
distBounds1.set(distBounds1.left, distBounds1.top,
distBounds1.right - insets.right, distBounds1.bottom - insets.bottom);
distBounds2.set(distBounds2.left + insets.left, distBounds2.top + insets.top,
distBounds2.right, distBounds2.bottom);
ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1, ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1,
false /* alignStart */); -insets.left, -insets.top);
ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2, ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2,
true /* alignStart */); insets.left, insets.top);
ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(), ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(),
distDividerBounds, true /* alignStart */); distDividerBounds, 0 /* offsetX */, 0 /* offsetY */);
AnimatorSet set = new AnimatorSet(); AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2, animator3); set.playTogether(animator1, animator2, animator3);
@@ -638,14 +634,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
mDividePosition = dividerPos; mDividePosition = dividerPos;
updateBounds(mDividePosition); updateBounds(mDividePosition);
finishCallback.run(); finishCallback.accept(insets);
} }
}); });
set.start(); set.start();
} }
private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash, private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash,
Rect start, Rect end, boolean alignStart) { Rect start, Rect end, float offsetX, float offsetY) {
Rect tempStart = new Rect(start); Rect tempStart = new Rect(start);
Rect tempEnd = new Rect(end); Rect tempEnd = new Rect(end);
final float diffX = tempEnd.left - tempStart.left; final float diffX = tempEnd.left - tempStart.left;
@@ -661,15 +657,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
final float distY = tempStart.top + scale * diffY; final float distY = tempStart.top + scale * diffY;
final int width = (int) (tempStart.width() + scale * diffWidth); final int width = (int) (tempStart.width() + scale * diffWidth);
final int height = (int) (tempStart.height() + scale * diffHeight); final int height = (int) (tempStart.height() + scale * diffHeight);
if (alignStart) { if (offsetX == 0 && offsetY == 0) {
t.setPosition(leash, distX, distY); t.setPosition(leash, distX, distY);
t.setWindowCrop(leash, width, height); t.setWindowCrop(leash, width, height);
} else { } else {
final int offsetX = width - tempStart.width(); final int diffOffsetX = (int) (scale * offsetX);
final int offsetY = height - tempStart.height(); final int diffOffsetY = (int) (scale * offsetY);
t.setPosition(leash, distX + offsetX, distY + offsetY); t.setPosition(leash, distX + diffOffsetX, distY + diffOffsetY);
mTempRect.set(0, 0, width, height); mTempRect.set(0, 0, width, height);
mTempRect.offsetTo(-offsetX, -offsetY); mTempRect.offsetTo(-diffOffsetX, -diffOffsetY);
t.setCrop(leash, mTempRect); t.setCrop(leash, mTempRect);
} }
t.apply(); t.apply();

View File

@@ -115,6 +115,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ScreenshotUtils;
import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.TransactionPool;
@@ -846,15 +847,44 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) { void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) {
if (mSideStagePosition == sideStagePosition) return; if (mSideStagePosition == sideStagePosition) return;
SurfaceControl.Transaction t = mTransactionPool.acquire(); SurfaceControl.Transaction t = mTransactionPool.acquire();
mTempRect1.setEmpty();
final StageTaskListener topLeftStage = final StageTaskListener topLeftStage =
mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
final SurfaceControl topLeftScreenshot = ScreenshotUtils.takeScreenshot(t,
topLeftStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1);
final StageTaskListener bottomRightStage = final StageTaskListener bottomRightStage =
mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
final SurfaceControl bottomRightScreenshot = ScreenshotUtils.takeScreenshot(t,
bottomRightStage.mRootLeash, mTempRect1, Integer.MAX_VALUE - 1);
mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash,
() -> { insets -> {
setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), WindowContainerTransaction wct = new WindowContainerTransaction();
null /* wct */); setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct);
mTransactionPool.release(t); mSyncQueue.queue(wct);
mSyncQueue.runInSync(st -> {
updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */);
st.setPosition(topLeftScreenshot, -insets.left, -insets.top);
st.setPosition(bottomRightScreenshot, insets.left, insets.top);
final ValueAnimator va = ValueAnimator.ofFloat(1, 0);
va.addUpdateListener(valueAnimator-> {
final float progress = (float) valueAnimator.getAnimatedValue();
t.setAlpha(topLeftScreenshot, progress);
t.setAlpha(bottomRightScreenshot, progress);
t.apply();
});
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(
@androidx.annotation.NonNull Animator animation) {
t.remove(topLeftScreenshot);
t.remove(bottomRightScreenshot);
t.apply();
mTransactionPool.release(t);
}
});
va.start();
});
}); });
} }