Merge "Avoid changing resolution by display mode when animating"

This commit is contained in:
Riddle Hsu
2023-02-03 04:03:19 +00:00
committed by Android (Google) Code Review
3 changed files with 56 additions and 17 deletions

View File

@@ -2163,6 +2163,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
}, true /* traverseTopToBottom */);
mPinnedTaskController.startSeamlessRotationIfNeeded(transaction, oldRotation, rotation);
if (!mDisplayRotation.hasSeamlessRotatingWindow()) {
// Make sure DisplayRotation#isRotatingSeamlessly() will return false.
mDisplayRotation.cancelSeamlessRotation();
}
}
mWmService.mDisplayManagerInternal.performTraversal(transaction);
@@ -4927,7 +4931,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mInsetsStateController.getImeSourceProvider().checkShowImePostLayout();
mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
if (!mWmService.mDisplayFrozen) {
if (!mWmService.mDisplayFrozen && !mDisplayRotation.isRotatingSeamlessly()) {
mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
mLastHasContent,
mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,

View File

@@ -59,6 +59,8 @@ class RefreshRatePolicy {
}
}
private final DisplayInfo mDisplayInfo;
private final Mode mDefaultMode;
private final Mode mLowRefreshRateMode;
private final PackageRefreshRate mNonHighRefreshRatePackages = new PackageRefreshRate();
private final HighRefreshRateDenylist mHighRefreshRateDenylist;
@@ -89,7 +91,9 @@ class RefreshRatePolicy {
RefreshRatePolicy(WindowManagerService wmService, DisplayInfo displayInfo,
HighRefreshRateDenylist denylist) {
mLowRefreshRateMode = findLowRefreshRateMode(displayInfo);
mDisplayInfo = displayInfo;
mDefaultMode = displayInfo.getDefaultMode();
mLowRefreshRateMode = findLowRefreshRateMode(displayInfo, mDefaultMode);
mHighRefreshRateDenylist = denylist;
mWmService = wmService;
}
@@ -98,10 +102,9 @@ class RefreshRatePolicy {
* Finds the mode id with the lowest refresh rate which is >= 60hz and same resolution as the
* default mode.
*/
private Mode findLowRefreshRateMode(DisplayInfo displayInfo) {
Mode mode = displayInfo.getDefaultMode();
private Mode findLowRefreshRateMode(DisplayInfo displayInfo, Mode defaultMode) {
float[] refreshRates = displayInfo.getDefaultRefreshRates();
float bestRefreshRate = mode.getRefreshRate();
float bestRefreshRate = defaultMode.getRefreshRate();
mMinSupportedRefreshRate = bestRefreshRate;
mMaxSupportedRefreshRate = bestRefreshRate;
for (int i = refreshRates.length - 1; i >= 0; i--) {
@@ -127,13 +130,39 @@ class RefreshRatePolicy {
}
int getPreferredModeId(WindowState w) {
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate.
if (w.isAnimating(TRANSITION | PARENTS)) {
final int preferredDisplayModeId = w.mAttrs.preferredDisplayModeId;
if (preferredDisplayModeId <= 0) {
// Unspecified, use default mode.
return 0;
}
return w.mAttrs.preferredDisplayModeId;
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate. But if the display size of default mode is different
// from the using preferred mode, then still keep the preferred mode to avoid disturbing
// the animation.
if (w.isAnimating(TRANSITION | PARENTS)) {
Display.Mode preferredMode = null;
for (Display.Mode mode : mDisplayInfo.supportedModes) {
if (preferredDisplayModeId == mode.getModeId()) {
preferredMode = mode;
break;
}
}
if (preferredMode != null) {
final int pW = preferredMode.getPhysicalWidth();
final int pH = preferredMode.getPhysicalHeight();
if ((pW != mDefaultMode.getPhysicalWidth()
|| pH != mDefaultMode.getPhysicalHeight())
&& pW == mDisplayInfo.getNaturalWidth()
&& pH == mDisplayInfo.getNaturalHeight()) {
// Prefer not to change display size when animating.
return preferredDisplayModeId;
}
}
return 0;
}
return preferredDisplayModeId;
}
/**
@@ -234,14 +263,10 @@ class RefreshRatePolicy {
if (refreshRateSwitchingType != SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY) {
final int preferredModeId = w.mAttrs.preferredDisplayModeId;
if (preferredModeId > 0) {
DisplayInfo info = w.getDisplayInfo();
if (info != null) {
for (Display.Mode mode : info.supportedModes) {
if (preferredModeId == mode.getModeId()) {
return w.mFrameRateVote.update(mode.getRefreshRate(),
Surface.FRAME_RATE_COMPATIBILITY_EXACT);
}
for (Display.Mode mode : mDisplayInfo.supportedModes) {
if (preferredModeId == mode.getModeId()) {
return w.mFrameRateVote.update(mode.getRefreshRate(),
Surface.FRAME_RATE_COMPATIBILITY_EXACT);
}
}
}

View File

@@ -24,7 +24,9 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITIO
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.hardware.display.DisplayManager;
@@ -289,6 +291,14 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
// If there will be display size change when switching from preferred mode to default mode,
// then keep the current preferred mode during animating.
mDisplayInfo = spy(mDisplayInfo);
final Mode defaultMode = new Mode(4321 /* width */, 1234 /* height */, LOW_REFRESH_RATE);
doReturn(defaultMode).when(mDisplayInfo).getDefaultMode();
mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist);
assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
}
@Test