Merge "Use blast sync for 180 degrees rotation" into udc-dev
This commit is contained in:
@@ -93,6 +93,9 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
/** Whether the start transaction of the transition is committed (by shell). */
|
||||
private boolean mIsStartTransactionCommitted;
|
||||
|
||||
/** Whether all windows should wait for the start transaction. */
|
||||
private boolean mAlwaysWaitForStartTransaction;
|
||||
|
||||
/** Whether the target windows have been requested to sync their draw transactions. */
|
||||
private boolean mIsSyncDrawRequested;
|
||||
|
||||
@@ -144,6 +147,15 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
if (mTransitionOp == OP_LEGACY) {
|
||||
mIsStartTransactionCommitted = true;
|
||||
} else if (displayContent.mTransitionController.isCollecting(displayContent)) {
|
||||
final Transition transition =
|
||||
mDisplayContent.mTransitionController.getCollectingTransition();
|
||||
if (transition != null) {
|
||||
final BLASTSyncEngine.SyncGroup syncGroup =
|
||||
mDisplayContent.mWmService.mSyncEngine.getSyncSet(transition.getSyncId());
|
||||
if (syncGroup != null && syncGroup.mSyncMethod == BLASTSyncEngine.METHOD_BLAST) {
|
||||
mAlwaysWaitForStartTransaction = true;
|
||||
}
|
||||
}
|
||||
keepAppearanceInPreviousRotation();
|
||||
}
|
||||
}
|
||||
@@ -202,7 +214,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
// target windows. But the windows still need to use sync transaction to keep the appearance
|
||||
// in previous rotation, so request a no-op sync to keep the state.
|
||||
for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
|
||||
if (mTargetWindowTokens.valueAt(i).canDrawBeforeStartTransaction()) {
|
||||
if (canDrawBeforeStartTransaction(mTargetWindowTokens.valueAt(i))) {
|
||||
// Expect a screenshot layer will cover the non seamless windows.
|
||||
continue;
|
||||
}
|
||||
@@ -521,7 +533,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
if (op == null) return false;
|
||||
if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w);
|
||||
if (postDrawTransaction == null || !mIsSyncDrawRequested
|
||||
|| op.canDrawBeforeStartTransaction()) {
|
||||
|| canDrawBeforeStartTransaction(op)) {
|
||||
mDisplayContent.finishAsyncRotation(w.mToken);
|
||||
return false;
|
||||
}
|
||||
@@ -563,6 +575,14 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
return super.getFadeOutAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the corresponding window can draw its latest content before the
|
||||
* start transaction of rotation transition is applied.
|
||||
*/
|
||||
private boolean canDrawBeforeStartTransaction(Operation op) {
|
||||
return !mAlwaysWaitForStartTransaction && op.mAction != Operation.ACTION_SEAMLESS;
|
||||
}
|
||||
|
||||
/** The operation to control the rotation appearance associated with window token. */
|
||||
private static class Operation {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -588,14 +608,5 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
Operation(@Action int action) {
|
||||
mAction = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the corresponding window can draw its latest content before the
|
||||
* start transaction of rotation transition is applied.
|
||||
*/
|
||||
boolean canDrawBeforeStartTransaction() {
|
||||
return TransitionController.SYNC_METHOD != BLASTSyncEngine.METHOD_BLAST
|
||||
&& mAction != ACTION_SEAMLESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ class BLASTSyncEngine {
|
||||
*/
|
||||
class SyncGroup {
|
||||
final int mSyncId;
|
||||
final int mSyncMethod;
|
||||
int mSyncMethod = METHOD_BLAST;
|
||||
final TransactionReadyListener mListener;
|
||||
final Runnable mOnTimeout;
|
||||
boolean mReady = false;
|
||||
@@ -103,9 +103,8 @@ class BLASTSyncEngine {
|
||||
private SurfaceControl.Transaction mOrphanTransaction = null;
|
||||
private String mTraceName;
|
||||
|
||||
private SyncGroup(TransactionReadyListener listener, int id, String name, int method) {
|
||||
private SyncGroup(TransactionReadyListener listener, int id, String name) {
|
||||
mSyncId = id;
|
||||
mSyncMethod = method;
|
||||
mListener = listener;
|
||||
mOnTimeout = () -> {
|
||||
Slog.w(TAG, "Sync group " + mSyncId + " timeout");
|
||||
@@ -288,13 +287,12 @@ class BLASTSyncEngine {
|
||||
* Prepares a {@link SyncGroup} that is not active yet. Caller must call {@link #startSyncSet}
|
||||
* before calling {@link #addToSyncSet(int, WindowContainer)} on any {@link WindowContainer}.
|
||||
*/
|
||||
SyncGroup prepareSyncSet(TransactionReadyListener listener, String name, int method) {
|
||||
return new SyncGroup(listener, mNextSyncId++, name, method);
|
||||
SyncGroup prepareSyncSet(TransactionReadyListener listener, String name) {
|
||||
return new SyncGroup(listener, mNextSyncId++, name);
|
||||
}
|
||||
|
||||
int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name,
|
||||
int method) {
|
||||
final SyncGroup s = prepareSyncSet(listener, name, method);
|
||||
int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name) {
|
||||
final SyncGroup s = prepareSyncSet(listener, name);
|
||||
startSyncSet(s, timeoutMs);
|
||||
return s.mSyncId;
|
||||
}
|
||||
@@ -334,6 +332,15 @@ class BLASTSyncEngine {
|
||||
getSyncGroup(id).addToSync(wc);
|
||||
}
|
||||
|
||||
void setSyncMethod(int id, int method) {
|
||||
final SyncGroup syncGroup = getSyncGroup(id);
|
||||
if (!syncGroup.mRootMembers.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Not allow to change sync method after adding group member, id=" + id);
|
||||
}
|
||||
syncGroup.mSyncMethod = method;
|
||||
}
|
||||
|
||||
void setReady(int id, boolean ready) {
|
||||
getSyncGroup(id).setReady(ready);
|
||||
}
|
||||
|
||||
@@ -369,7 +369,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
return mState;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int getSyncId() {
|
||||
return mSyncId;
|
||||
}
|
||||
@@ -409,18 +408,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
return mState == STATE_FINISHED;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void startCollecting(long timeoutMs) {
|
||||
startCollecting(timeoutMs, TransitionController.SYNC_METHOD);
|
||||
}
|
||||
|
||||
/** Starts collecting phase. Once this starts, all relevant surface operations are sync. */
|
||||
void startCollecting(long timeoutMs, int method) {
|
||||
void startCollecting(long timeoutMs) {
|
||||
if (mState != STATE_PENDING) {
|
||||
throw new IllegalStateException("Attempting to re-use a transition");
|
||||
}
|
||||
mState = STATE_COLLECTING;
|
||||
mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG, method);
|
||||
mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG);
|
||||
mSyncEngine.setSyncMethod(mSyncId, TransitionController.SYNC_METHOD);
|
||||
|
||||
mLogger.mSyncId = mSyncId;
|
||||
mLogger.mCollectTimeNs = SystemClock.elapsedRealtimeNanos();
|
||||
|
||||
@@ -51,7 +51,6 @@ import android.window.TransitionRequestInfo;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.protolog.ProtoLogGroup;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.server.FgThread;
|
||||
@@ -200,12 +199,6 @@ class TransitionController {
|
||||
|
||||
/** Starts Collecting */
|
||||
void moveToCollecting(@NonNull Transition transition) {
|
||||
moveToCollecting(transition, SYNC_METHOD);
|
||||
}
|
||||
|
||||
/** Starts Collecting */
|
||||
@VisibleForTesting
|
||||
void moveToCollecting(@NonNull Transition transition, int method) {
|
||||
if (mCollectingTransition != null) {
|
||||
throw new IllegalStateException("Simultaneous transition collection not supported.");
|
||||
}
|
||||
@@ -219,7 +212,7 @@ class TransitionController {
|
||||
// Distinguish change type because the response time is usually expected to be not too long.
|
||||
final long timeoutMs =
|
||||
transition.mType == TRANSIT_CHANGE ? CHANGE_TIMEOUT_MS : DEFAULT_TIMEOUT_MS;
|
||||
mCollectingTransition.startCollecting(timeoutMs, method);
|
||||
mCollectingTransition.startCollecting(timeoutMs);
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Start collecting in Transition: %s",
|
||||
mCollectingTransition);
|
||||
dispatchLegacyAppTransitionPending();
|
||||
@@ -492,6 +485,15 @@ class TransitionController {
|
||||
} else {
|
||||
newTransition = requestStartTransition(createTransition(type, flags),
|
||||
trigger != null ? trigger.asTask() : null, remoteTransition, displayChange);
|
||||
if (newTransition != null && displayChange != null && (displayChange.getStartRotation()
|
||||
+ displayChange.getEndRotation()) % 2 == 0) {
|
||||
// 180 degrees rotation change may not change screen size. So the clients may draw
|
||||
// some frames before and after the display projection transaction is applied by the
|
||||
// remote player. That may cause some buffers to show in different rotation. So use
|
||||
// sync method to pause clients drawing until the projection transaction is applied.
|
||||
mAtm.mWindowManager.mSyncEngine.setSyncMethod(newTransition.getSyncId(),
|
||||
BLASTSyncEngine.METHOD_BLAST);
|
||||
}
|
||||
}
|
||||
if (trigger != null) {
|
||||
if (isExistenceType(type)) {
|
||||
|
||||
@@ -1648,7 +1648,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
private BLASTSyncEngine.SyncGroup prepareSyncWithOrganizer(
|
||||
IWindowContainerTransactionCallback callback) {
|
||||
final BLASTSyncEngine.SyncGroup s = mService.mWindowManager.mSyncEngine
|
||||
.prepareSyncSet(this, "", BLASTSyncEngine.METHOD_BLAST);
|
||||
.prepareSyncSet(this, "Organizer");
|
||||
mTransactionCallbacksByPendingSyncId.put(s.mSyncId, callback);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
import static com.android.server.wm.BLASTSyncEngine.METHOD_BLAST;
|
||||
import static com.android.server.wm.BLASTSyncEngine.METHOD_NONE;
|
||||
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
|
||||
import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||
@@ -363,7 +362,8 @@ public class SyncEngineTests extends WindowTestsBase {
|
||||
BLASTSyncEngine.TransactionReadyListener listener = mock(
|
||||
BLASTSyncEngine.TransactionReadyListener.class);
|
||||
|
||||
int id = startSyncSet(bse, listener, METHOD_NONE);
|
||||
final int id = startSyncSet(bse, listener);
|
||||
bse.setSyncMethod(id, METHOD_NONE);
|
||||
bse.addToSyncSet(id, mAppWindow.mToken);
|
||||
mAppWindow.prepareSync();
|
||||
assertFalse(mAppWindow.shouldSyncWithBuffers());
|
||||
@@ -373,12 +373,7 @@ public class SyncEngineTests extends WindowTestsBase {
|
||||
|
||||
static int startSyncSet(BLASTSyncEngine engine,
|
||||
BLASTSyncEngine.TransactionReadyListener listener) {
|
||||
return startSyncSet(engine, listener, METHOD_BLAST);
|
||||
}
|
||||
|
||||
static int startSyncSet(BLASTSyncEngine engine,
|
||||
BLASTSyncEngine.TransactionReadyListener listener, int method) {
|
||||
return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "", method);
|
||||
return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test");
|
||||
}
|
||||
|
||||
static class TestWindowContainer extends WindowContainer {
|
||||
|
||||
@@ -1704,7 +1704,8 @@ public class TransitionTests extends WindowTestsBase {
|
||||
mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
|
||||
final Transition transition = new Transition(TRANSIT_OPEN, 0 /* flags */,
|
||||
app.mTransitionController, mWm.mSyncEngine);
|
||||
app.mTransitionController.moveToCollecting(transition, BLASTSyncEngine.METHOD_NONE);
|
||||
app.mTransitionController.moveToCollecting(transition);
|
||||
mWm.mSyncEngine.setSyncMethod(transition.getSyncId(), BLASTSyncEngine.METHOD_NONE);
|
||||
final ArrayList<WindowContainer> freezeCalls = new ArrayList<>();
|
||||
transition.setContainerFreezer(new Transition.IContainerFreezer() {
|
||||
@Override
|
||||
@@ -1755,7 +1756,8 @@ public class TransitionTests extends WindowTestsBase {
|
||||
mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
|
||||
final Transition transition = new Transition(TRANSIT_CHANGE, 0 /* flags */,
|
||||
app.mTransitionController, mWm.mSyncEngine);
|
||||
app.mTransitionController.moveToCollecting(transition, BLASTSyncEngine.METHOD_NONE);
|
||||
app.mTransitionController.moveToCollecting(transition);
|
||||
mWm.mSyncEngine.setSyncMethod(transition.getSyncId(), BLASTSyncEngine.METHOD_NONE);
|
||||
final SurfaceControl mockSnapshot = mock(SurfaceControl.class);
|
||||
transition.setContainerFreezer(new Transition.IContainerFreezer() {
|
||||
@Override
|
||||
|
||||
@@ -42,7 +42,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
|
||||
import static com.android.server.wm.ActivityRecord.State.RESUMED;
|
||||
import static com.android.server.wm.BLASTSyncEngine.METHOD_BLAST;
|
||||
import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||
import static com.android.server.wm.WindowContainer.SYNC_STATE_READY;
|
||||
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
|
||||
@@ -1001,7 +1000,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
||||
BLASTSyncEngine.TransactionReadyListener transactionListener =
|
||||
mock(BLASTSyncEngine.TransactionReadyListener.class);
|
||||
|
||||
int id = bse.startSyncSet(transactionListener, BLAST_TIMEOUT_DURATION, "", METHOD_BLAST);
|
||||
final int id = bse.startSyncSet(transactionListener, BLAST_TIMEOUT_DURATION, "Test");
|
||||
bse.addToSyncSet(id, task);
|
||||
bse.setReady(id);
|
||||
bse.onSurfacePlacement();
|
||||
|
||||
Reference in New Issue
Block a user