Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53373681 authored by petsjonkin's avatar petsjonkin Committed by Oleg Petšjonkin
Browse files

Introducing Display Sythetic modes - used for app request refresh rate/resolution selection

Synthetic modes are used for vrr displays to hide normal speed modes for applications.
When application request synthetic mode, instead voting for this mode, DisplayModeDirector will vote for RenderRate and Size

Bug: b/338183249
Test: atest DisplayServiceTests
Change-Id: I374f137fefd2ba43ab72507db68043d840334835
parent 59cf6de3
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -1223,7 +1223,7 @@ public final class Display {
    public Mode[] getSupportedModes() {
        synchronized (mLock) {
            updateDisplayInfoLocked();
            final Display.Mode[] modes = mDisplayInfo.supportedModes;
            final Display.Mode[] modes = mDisplayInfo.appsSupportedModes;
            return Arrays.copyOf(modes, modes.length);
        }
    }
@@ -2206,6 +2206,7 @@ public final class Display {
        @NonNull
        @HdrCapabilities.HdrType
        private final int[] mSupportedHdrTypes;
        private final boolean mIsSynthetic;

        /**
         * @hide
@@ -2216,13 +2217,6 @@ public final class Display {
                    new int[0]);
        }

        /**
         * @hide
         */
        public Mode(int width, int height, float refreshRate, float vsyncRate) {
            this(INVALID_MODE_ID, width, height, refreshRate, vsyncRate, new float[0], new int[0]);
        }

        /**
         * @hide
         */
@@ -2246,11 +2240,21 @@ public final class Display {
         */
        public Mode(int modeId, int width, int height, float refreshRate, float vsyncRate,
                float[] alternativeRefreshRates, @HdrCapabilities.HdrType int[] supportedHdrTypes) {
            this(modeId, width, height, refreshRate, vsyncRate, false, alternativeRefreshRates,
                    supportedHdrTypes);
        }
        /**
         * @hide
         */
        public Mode(int modeId, int width, int height, float refreshRate, float vsyncRate,
                boolean isSynthetic, float[] alternativeRefreshRates,
                @HdrCapabilities.HdrType int[] supportedHdrTypes) {
            mModeId = modeId;
            mWidth = width;
            mHeight = height;
            mPeakRefreshRate = refreshRate;
            mVsyncRate = vsyncRate;
            mIsSynthetic = isSynthetic;
            mAlternativeRefreshRates =
                    Arrays.copyOf(alternativeRefreshRates, alternativeRefreshRates.length);
            Arrays.sort(mAlternativeRefreshRates);
@@ -2314,6 +2318,15 @@ public final class Display {
            return mVsyncRate;
        }

        /**
         * Returns true if mode is synthetic and does not have corresponding
         * SurfaceControl.DisplayMode
         * @hide
         */
        public boolean isSynthetic() {
            return mIsSynthetic;
        }

        /**
         * Returns an array of refresh rates which can be switched to seamlessly.
         * <p>
@@ -2449,6 +2462,7 @@ public final class Display {
                    .append(", height=").append(mHeight)
                    .append(", fps=").append(mPeakRefreshRate)
                    .append(", vsync=").append(mVsyncRate)
                    .append(", synthetic=").append(mIsSynthetic)
                    .append(", alternativeRefreshRates=")
                    .append(Arrays.toString(mAlternativeRefreshRates))
                    .append(", supportedHdrTypes=")
@@ -2464,7 +2478,7 @@ public final class Display {

        private Mode(Parcel in) {
            this(in.readInt(), in.readInt(), in.readInt(), in.readFloat(), in.readFloat(),
                    in.createFloatArray(), in.createIntArray());
                    in.readBoolean(), in.createFloatArray(), in.createIntArray());
        }

        @Override
@@ -2474,6 +2488,7 @@ public final class Display {
            out.writeInt(mHeight);
            out.writeFloat(mPeakRefreshRate);
            out.writeFloat(mVsyncRate);
            out.writeBoolean(mIsSynthetic);
            out.writeFloatArray(mAlternativeRefreshRates);
            out.writeIntArray(mSupportedHdrTypes);
        }
+21 −1
Original line number Diff line number Diff line
@@ -211,6 +211,12 @@ public final class DisplayInfo implements Parcelable {
     */
    public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;

    /**
     * The supported modes that will be exposed externally.
     * Might have different set of modes that supportedModes for VRR displays
     */
    public Display.Mode[] appsSupportedModes = Display.Mode.EMPTY_ARRAY;

    /** The active color mode. */
    public int colorMode;

@@ -429,6 +435,7 @@ public final class DisplayInfo implements Parcelable {
                && defaultModeId == other.defaultModeId
                && userPreferredModeId == other.userPreferredModeId
                && Arrays.equals(supportedModes, other.supportedModes)
                && Arrays.equals(appsSupportedModes, other.appsSupportedModes)
                && colorMode == other.colorMode
                && Arrays.equals(supportedColorModes, other.supportedColorModes)
                && Objects.equals(hdrCapabilities, other.hdrCapabilities)
@@ -488,6 +495,8 @@ public final class DisplayInfo implements Parcelable {
        defaultModeId = other.defaultModeId;
        userPreferredModeId = other.userPreferredModeId;
        supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
        appsSupportedModes = Arrays.copyOf(
                other.appsSupportedModes, other.appsSupportedModes.length);
        colorMode = other.colorMode;
        supportedColorModes = Arrays.copyOf(
                other.supportedColorModes, other.supportedColorModes.length);
@@ -545,6 +554,11 @@ public final class DisplayInfo implements Parcelable {
        for (int i = 0; i < nModes; i++) {
            supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
        }
        int nAppModes = source.readInt();
        appsSupportedModes = new Display.Mode[nAppModes];
        for (int i = 0; i < nAppModes; i++) {
            appsSupportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
        }
        colorMode = source.readInt();
        int nColorModes = source.readInt();
        supportedColorModes = new int[nColorModes];
@@ -611,6 +625,10 @@ public final class DisplayInfo implements Parcelable {
        for (int i = 0; i < supportedModes.length; i++) {
            supportedModes[i].writeToParcel(dest, flags);
        }
        dest.writeInt(appsSupportedModes.length);
        for (int i = 0; i < appsSupportedModes.length; i++) {
            appsSupportedModes[i].writeToParcel(dest, flags);
        }
        dest.writeInt(colorMode);
        dest.writeInt(supportedColorModes.length);
        for (int i = 0; i < supportedColorModes.length; i++) {
@@ -849,8 +867,10 @@ public final class DisplayInfo implements Parcelable {
        sb.append(defaultModeId);
        sb.append(", userPreferredModeId ");
        sb.append(userPreferredModeId);
        sb.append(", modes ");
        sb.append(", supportedModes ");
        sb.append(Arrays.toString(supportedModes));
        sb.append(", appsSupportedModes ");
        sb.append(Arrays.toString(appsSupportedModes));
        sb.append(", hdrCapabilities ");
        sb.append(hdrCapabilities);
        sb.append(", userDisabledHdrTypes ");
+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ abstract class DisplayAdapter {
            float[] alternativeRefreshRates,
            @Display.HdrCapabilities.HdrType int[] supportedHdrTypes) {
        return new Display.Mode(NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate,
                vsyncRate, alternativeRefreshRates, supportedHdrTypes);
                vsyncRate, false, alternativeRefreshRates, supportedHdrTypes);
    }

    public interface Listener {
+7 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.view.SurfaceControl;

import com.android.server.display.layout.Layout;
import com.android.server.display.mode.DisplayModeDirector;
import com.android.server.display.mode.SyntheticModeManager;
import com.android.server.wm.utils.InsetUtils;

import java.io.PrintWriter;
@@ -408,7 +409,8 @@ final class LogicalDisplay {
     *
     * @param deviceRepo Repository of active {@link DisplayDevice}s.
     */
    public void updateLocked(DisplayDeviceRepository deviceRepo) {
    public void updateLocked(DisplayDeviceRepository deviceRepo,
            SyntheticModeManager syntheticModeManager) {
        // Nothing to update if already invalid.
        if (mPrimaryDisplayDevice == null) {
            return;
@@ -426,6 +428,7 @@ final class LogicalDisplay {
        // logical display that they are sharing.  (eg. Adjust size for pixel-perfect
        // mirroring over HDMI.)
        DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
        DisplayDeviceConfig config = mPrimaryDisplayDevice.getDisplayDeviceConfig();
        if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo) || mDirty) {
            mBaseDisplayInfo.layerStack = mLayerStack;
            mBaseDisplayInfo.flags = 0;
@@ -507,6 +510,9 @@ final class LogicalDisplay {
            mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId;
            mBaseDisplayInfo.supportedModes = Arrays.copyOf(
                    deviceInfo.supportedModes, deviceInfo.supportedModes.length);
            mBaseDisplayInfo.appsSupportedModes = syntheticModeManager.createAppSupportedModes(
                    config, mBaseDisplayInfo.supportedModes
            );
            mBaseDisplayInfo.colorMode = deviceInfo.colorMode;
            mBaseDisplayInfo.supportedColorModes = Arrays.copyOf(
                    deviceInfo.supportedColorModes,
+8 −4
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import com.android.server.LocalServices;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.DisplayIdProducer;
import com.android.server.display.layout.Layout;
import com.android.server.display.mode.SyntheticModeManager;
import com.android.server.display.utils.DebugUtils;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.utils.FoldSettingProvider;
@@ -204,6 +205,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    private boolean mBootCompleted = false;
    private boolean mInteractive;
    private final DisplayManagerFlags mFlags;
    private final SyntheticModeManager mSyntheticModeManager;

    LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider,
            FoldGracePeriodProvider foldGracePeriodProvider,
@@ -213,7 +215,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        this(context, foldSettingProvider, foldGracePeriodProvider, repo, listener, syncRoot,
                handler,
                new DeviceStateToLayoutMap((isDefault) -> isDefault ? DEFAULT_DISPLAY
                        : sNextNonDefaultDisplayId++, flags), flags);
                        : sNextNonDefaultDisplayId++, flags), flags,
                new SyntheticModeManager(flags));
    }

    LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider,
@@ -221,7 +224,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
            @NonNull DisplayDeviceRepository repo,
            @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
            @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap,
            DisplayManagerFlags flags) {
            DisplayManagerFlags flags, SyntheticModeManager syntheticModeManager) {
        mSyncRoot = syncRoot;
        mPowerManager = context.getSystemService(PowerManager.class);
        mInteractive = mPowerManager.isInteractive();
@@ -241,6 +244,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        mDisplayDeviceRepo.addListener(this);
        mDeviceStateToLayoutMap = deviceStateToLayoutMap;
        mFlags = flags;
        mSyntheticModeManager = syntheticModeManager;
    }

    @Override
@@ -737,7 +741,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
            mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
            display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);

            display.updateLocked(mDisplayDeviceRepo);
            display.updateLocked(mDisplayDeviceRepo, mSyntheticModeManager);
            final DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
            final int updateState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
            final boolean wasPreviouslyUpdated = updateState != UPDATE_STATE_NEW;
@@ -1177,7 +1181,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device,
                mFlags.isPixelAnisotropyCorrectionInLogicalDisplayEnabled(),
                mFlags.isAlwaysRotateDisplayDeviceEnabled());
        display.updateLocked(mDisplayDeviceRepo);
        display.updateLocked(mDisplayDeviceRepo, mSyntheticModeManager);

        final DisplayInfo info = display.getDisplayInfoLocked();
        if (info.type == Display.TYPE_INTERNAL && mDeviceStateToLayoutMap.size() > 1) {
Loading