Merge "Apply rotation change on display thread" into udc-qpr-dev

This commit is contained in:
Riddle Hsu
2023-06-29 10:02:26 +00:00
committed by Android (Google) Code Review
4 changed files with 33 additions and 11 deletions

View File

@@ -77,6 +77,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
@@ -2696,6 +2697,26 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
});
}
/**
* Returns {@code true} if the transition and the corresponding transaction should be applied
* on display thread. Currently, this only checks for display rotation change because the order
* of dispatching the new display info will be after requesting the windows to sync drawing.
* That avoids potential flickering of screen overlays (e.g. cutout, rounded corner). Also,
* because the display thread has a higher priority, it is faster to perform the configuration
* changes and window hierarchy traversal.
*/
boolean shouldApplyOnDisplayThread() {
for (int i = mParticipants.size() - 1; i >= 0; --i) {
final DisplayContent dc = mParticipants.valueAt(i).asDisplayContent();
if (dc == null) continue;
final ChangeInfo changeInfo = mChanges.get(dc);
if (changeInfo != null && changeInfo.mRotation != dc.getRotation()) {
return Looper.myLooper() != mController.mAtm.mWindowManager.mH.getLooper();
}
}
return false;
}
/** Applies the new configuration for the changed displays. */
void applyDisplayChangeIfNeeded() {
for (int i = mParticipants.size() - 1; i >= 0; --i) {

View File

@@ -588,15 +588,6 @@ class TransitionController {
/** Sets the sync method for the display change. */
private void setDisplaySyncMethod(@NonNull TransitionRequestInfo.DisplayChange displayChange,
@NonNull Transition displayTransition, @NonNull DisplayContent displayContent) {
final int startRotation = displayChange.getStartRotation();
final int endRotation = displayChange.getEndRotation();
if (startRotation != endRotation && (startRotation + endRotation) % 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.
mSyncEngine.setSyncMethod(displayTransition.getSyncId(), BLASTSyncEngine.METHOD_BLAST);
}
final Rect startBounds = displayChange.getStartAbsBounds();
final Rect endBounds = displayChange.getEndAbsBounds();
if (startBounds == null || endBounds == null) return;

View File

@@ -321,9 +321,18 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
applyTransaction(wct, -1 /*syncId*/, null /*transition*/, caller);
return transition.getToken();
}
transition.start();
transition.mLogger.mStartWCT = wct;
applyTransaction(wct, -1 /*syncId*/, transition, caller);
if (transition.shouldApplyOnDisplayThread()) {
mService.mH.post(() -> {
synchronized (mService.mGlobalLock) {
transition.start();
applyTransaction(wct, -1 /* syncId */, transition, caller);
}
});
} else {
transition.start();
applyTransaction(wct, -1 /* syncId */, transition, caller);
}
// Since the transition is already provided, it means WMCore is determining the
// "readiness lifecycle" outside the provided transaction, so don't set ready here.
return transition.getToken();

View File

@@ -2046,6 +2046,7 @@ public class DisplayContentTests extends WindowTestsBase {
// Once transition starts, rotation is applied and transition shows DC rotating.
testPlayer.startTransition();
waitUntilHandlersIdle();
assertNotEquals(origRot, dc.getConfiguration().windowConfiguration.getRotation());
assertNotNull(testPlayer.mLastReady);
assertTrue(testPlayer.mController.isPlaying());