diff options
| author | 2025-01-29 19:53:20 +0000 | |
|---|---|---|
| committer | 2025-02-11 17:18:08 +0000 | |
| commit | 7100404a66393b4a3d7311c7368208b10376a64b (patch) | |
| tree | afd55d4791425ff75119b01fc051aebf327f2ffd | |
| parent | c13717cd79158bb135f0b3a699af243743de802f (diff) | |
LogicalDisplay to call SC.setDisplaySize
Also performTraversalLocked is split
and renamed into configureSurfaceLocked
and configureDisplaySizeLocked
Change-Id: Idc7de9e1a215cad6acc4ec93fde01e9c28b27c46
Test: atest LogicalDisplayTest DisplayDeviceTest
Bug: 355427258
Flag: com.android.graphics.surfaceflinger.flags.synced_resolution_switch
10 files changed, 153 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 2bdb5c25d0d5..a749a4013cdc 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -68,6 +68,8 @@ abstract class DisplayDevice { private int mCurrentLayerStack = -1; private int mCurrentFlags = 0; private int mCurrentOrientation = -1; + private int mLastDisplayWidth; + private int mLastDisplayHeight; private Rect mCurrentLayerStackRect; private Rect mCurrentDisplayRect; private final Context mContext; @@ -216,9 +218,9 @@ abstract class DisplayDevice { } /** - * Gives the display device a chance to update its properties while in a transaction. + * Updates the surface for the display. */ - public void performTraversalLocked(SurfaceControl.Transaction t) { + public void configureSurfaceLocked(SurfaceControl.Transaction t) { } /** @@ -374,6 +376,29 @@ abstract class DisplayDevice { } /** + * Configure transaction with the display size. + */ + public void configureDisplaySizeLocked(SurfaceControl.Transaction t) { + DisplayDeviceInfo info = getDisplayDeviceInfoLocked(); + boolean isInstalledRotated = info.installOrientation == ROTATION_90 + || info.installOrientation == ROTATION_270; + int displayWidth = isInstalledRotated ? info.height : info.width; + int displayHeight = isInstalledRotated ? info.width : info.height; + setDisplaySizeLocked(t, displayWidth, displayHeight); + } + + /** + * Sets display size while in a transaction. + */ + public final void setDisplaySizeLocked(SurfaceControl.Transaction t, int width, int height) { + if (width != mLastDisplayWidth && height != mLastDisplayHeight) { + mLastDisplayWidth = width; + mLastDisplayHeight = height; + t.setDisplaySize(mDisplayToken, width, height); + } + } + + /** * Sets the display surface while in a transaction. */ public final void setSurfaceLocked(SurfaceControl.Transaction t, Surface surface) { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index e83efc573ea8..fdd76eacba83 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -3110,7 +3110,6 @@ public final class DisplayManagerService extends SystemService { displayTransactions.get(display.getDisplayIdLocked(), t); if (device != null) { configureDisplayLocked(displayTransaction, device); - device.performTraversalLocked(displayTransaction); } }); diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index f9d413732e3e..b2b9ef17ec8d 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -228,14 +228,17 @@ final class LogicalDisplay { */ private final boolean mIsAnisotropyCorrectionEnabled; + private final boolean mSyncedResolutionSwitchEnabled; + private boolean mCanHostTasks; LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) { - this(displayId, layerStack, primaryDisplayDevice, false, false); + this(displayId, layerStack, primaryDisplayDevice, false, false, false); } LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice, - boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled) { + boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled, + boolean isSyncedResolutionSwitchEnabled) { mDisplayId = displayId; mLayerStack = layerStack; mPrimaryDisplayDevice = primaryDisplayDevice; @@ -248,6 +251,7 @@ final class LogicalDisplay { mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId; mIsAnisotropyCorrectionEnabled = isAnisotropyCorrectionEnabled; mAlwaysRotateDisplayDeviceEnabled = isAlwaysRotateDisplayDeviceEnabled; + mSyncedResolutionSwitchEnabled = isSyncedResolutionSwitchEnabled; mCanHostTasks = (mDisplayId == Display.DEFAULT_DISPLAY); } @@ -791,7 +795,12 @@ final class LogicalDisplay { } mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top); + + if (mSyncedResolutionSwitchEnabled || displayDeviceInfo.type == Display.TYPE_VIRTUAL) { + device.configureDisplaySizeLocked(t); + } device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect); + device.configureSurfaceLocked(t); } /** diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index ecc8896b69c6..02db051dff57 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -1248,7 +1248,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final int layerStack = assignLayerStackLocked(displayId); final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device, mFlags.isPixelAnisotropyCorrectionInLogicalDisplayEnabled(), - mFlags.isAlwaysRotateDisplayDeviceEnabled()); + mFlags.isAlwaysRotateDisplayDeviceEnabled(), + mFlags.isSyncedResolutionSwitchEnabled()); display.updateLocked(mDisplayDeviceRepo, mSyntheticModeManager); final DisplayInfo info = display.getDisplayInfoLocked(); diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 382c88327523..b5a9b19bc5c5 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -341,7 +341,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } @Override - public void performTraversalLocked(SurfaceControl.Transaction t) { + public void configureSurfaceLocked(SurfaceControl.Transaction t) { if (mSurfaceTexture != null) { if (mSurface == null) { mSurface = new Surface(mSurfaceTexture); diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index abbdeb9da364..4779b690adfb 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -484,14 +484,19 @@ public class VirtualDisplayAdapter extends DisplayAdapter { } @Override - public void performTraversalLocked(SurfaceControl.Transaction t) { - if ((mPendingChanges & PENDING_RESIZE) != 0) { - t.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight); - } + public void configureSurfaceLocked(SurfaceControl.Transaction t) { if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) { setSurfaceLocked(t, mSurface); + mPendingChanges &= ~PENDING_SURFACE_CHANGE; + } + } + + @Override + public void configureDisplaySizeLocked(SurfaceControl.Transaction t) { + if ((mPendingChanges & PENDING_RESIZE) != 0) { + setDisplaySizeLocked(t, mWidth, mHeight); + mPendingChanges &= ~PENDING_RESIZE; } - mPendingChanges = 0; } @Override diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index 607c5d6a88bc..902eefa824b5 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -640,7 +640,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { } @Override - public void performTraversalLocked(SurfaceControl.Transaction t) { + public void configureSurfaceLocked(SurfaceControl.Transaction t) { if (mSurface != null) { setSurfaceLocked(t, mSurface); } diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index a1e8f08db0a6..bc2120e6f106 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -86,6 +86,11 @@ public class DisplayManagerFlags { com.android.graphics.surfaceflinger.flags.Flags.FLAG_DISPLAY_CONFIG_ERROR_HAL, com.android.graphics.surfaceflinger.flags.Flags::displayConfigErrorHal); + private final FlagState mSyncedResolutionSwitch = new FlagState( + com.android.graphics.surfaceflinger.flags.Flags.FLAG_SYNCED_RESOLUTION_SWITCH, + com.android.graphics.surfaceflinger.flags.Flags::syncedResolutionSwitch + ); + private final FlagState mBrightnessIntRangeUserPerceptionFlagState = new FlagState( Flags.FLAG_BRIGHTNESS_INT_RANGE_USER_PERCEPTION, Flags::brightnessIntRangeUserPerception); @@ -364,6 +369,10 @@ public class DisplayManagerFlags { return mDisplayConfigErrorHalFlagState.isEnabled(); } + public boolean isSyncedResolutionSwitchEnabled() { + return mSyncedResolutionSwitch.isEnabled(); + } + public boolean isBrightnessIntRangeUserPerceptionEnabled() { return mBrightnessIntRangeUserPerceptionFlagState.isEnabled(); } @@ -620,6 +629,7 @@ public class DisplayManagerFlags { pw.println(" " + mEvenDimmerFlagState); pw.println(" " + mSmallAreaDetectionFlagState); pw.println(" " + mDisplayConfigErrorHalFlagState); + pw.println(" " + mSyncedResolutionSwitch); pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState); pw.println(" " + mRestrictDisplayModes); pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState); diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java index 00296745a81f..38586155993e 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java @@ -23,10 +23,17 @@ import static android.view.Surface.ROTATION_90; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + import android.graphics.Point; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.Display; +import android.view.Surface; import android.view.SurfaceControl; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -37,6 +44,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; /** @@ -154,6 +162,65 @@ public class DisplayDeviceTest { assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE); } + @Test + public void testSetDisplaySize_landscapeInstallRotation() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); + mDisplayDeviceInfo.installOrientation = Surface.ROTATION_0; + mDisplayDeviceInfo.width = 100; + mDisplayDeviceInfo.height = 200; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(100), eq(200)); + + Mockito.clearInvocations(mMockTransaction); + + mDisplayDeviceInfo.installOrientation = Surface.ROTATION_180; + mDisplayDeviceInfo.width = 300; + mDisplayDeviceInfo.height = 400; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(300), eq(400)); + } + + @Test + public void testSetDisplaySize_portraitInstallRotation() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); + mDisplayDeviceInfo.installOrientation = Surface.ROTATION_90; + mDisplayDeviceInfo.width = 100; + mDisplayDeviceInfo.height = 200; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(200), eq(100)); + + Mockito.clearInvocations(mMockTransaction); + + mDisplayDeviceInfo.installOrientation = Surface.ROTATION_270; + mDisplayDeviceInfo.width = 300; + mDisplayDeviceInfo.height = 400; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(400), eq(300)); + } + + @Test + public void testSetDisplaySize_invokedOnlyAfterResize() { + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); + mDisplayDeviceInfo.installOrientation = Surface.ROTATION_90; + mDisplayDeviceInfo.width = 100; + mDisplayDeviceInfo.height = 200; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(200), eq(100)); + + Mockito.clearInvocations(mMockTransaction); + + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction, never()).setDisplaySize(isNull(), anyInt(), anyInt()); + + mDisplayDeviceInfo.width = 300; + mDisplayDeviceInfo.height = 400; + displayDevice.configureDisplaySizeLocked(mMockTransaction); + verify(mMockTransaction).setDisplaySize(isNull(), eq(400), eq(300)); + } + private static class FakeDisplayDevice extends DisplayDevice { private final DisplayDeviceInfo mDisplayDeviceInfo; diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java index 1a0ab252f128..37f8aba1fb6c 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java @@ -159,7 +159,8 @@ public class LogicalDisplayTest { mDisplayDeviceInfo.type = Display.TYPE_INTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); // In case of Anisotropy of pixels, then the content should be rescaled so it would adjust // to using the whole screen. This is because display will rescale it back to fill the @@ -188,7 +189,8 @@ public class LogicalDisplayTest { mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); // In case of Anisotropy of pixels, then the content should be rescaled so it would adjust // to using the whole screen. This is because display will rescale it back to fill the @@ -217,7 +219,8 @@ public class LogicalDisplayTest { mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); DisplayInfo displayInfo = new DisplayInfo(); displayInfo.logicalWidth = DISPLAY_WIDTH; @@ -275,7 +278,8 @@ public class LogicalDisplayTest { mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); DisplayInfo displayInfo = new DisplayInfo(); displayInfo.logicalWidth = DISPLAY_WIDTH; @@ -304,7 +308,8 @@ public class LogicalDisplayTest { mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); // In case of Anisotropy of pixels, then the content should be rescaled so it would adjust // to using the whole screen. This is because display will rescale it back to fill the @@ -379,11 +384,24 @@ public class LogicalDisplayTest { } @Test + public void testSetDisplaySizeIsCalledDuringConfigureDisplayLocked() { + mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, + /*isAnisotropyCorrectionEnabled=*/ true, + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); + mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager); + SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class); + mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + verify(mDisplayDevice).configureDisplaySizeLocked(eq(t)); + } + + @Test public void testGetDisplayPositionAlwaysRotateDisplayEnabled() { mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL; mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice, /*isAnisotropyCorrectionEnabled=*/ true, - /*isAlwaysRotateDisplayDeviceEnabled=*/ true); + /*isAlwaysRotateDisplayDeviceEnabled=*/ true, + /*isSyncedResolutionSwitchEnabled=*/ true); mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager); Point expectedPosition = new Point(); |