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

Commit 731423a0 authored by Oleg Petšjonkin's avatar Oleg Petšjonkin Committed by Android (Google) Code Review
Browse files

Merge "Smooth display should also limit physical refreshRate" into main

parents f52c8f4b 05ceb414
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -154,6 +154,11 @@ public class DisplayManagerFlags {
            Flags::useFusionProxSensor
    );

    private final FlagState mPeakRefreshRatePhysicalLimit = new FlagState(
            Flags.FLAG_ENABLE_PEAK_REFRESH_RATE_PHYSICAL_LIMIT,
            Flags::enablePeakRefreshRatePhysicalLimit
    );

    /**
     * @return {@code true} if 'port' is allowed in display layout configuration file.
     */
@@ -312,6 +317,10 @@ public class DisplayManagerFlags {
        return mUseFusionProxSensor.getName();
    }

    public boolean isPeakRefreshRatePhysicalLimitEnabled() {
        return mPeakRefreshRatePhysicalLimit.isEnabled();
    }

    /**
     * dumps all flagstates
     * @param pw printWriter
@@ -343,6 +352,7 @@ public class DisplayManagerFlags {
        pw.println(" " + mRefactorDisplayPowerController);
        pw.println(" " + mResolutionBackupRestore);
        pw.println(" " + mUseFusionProxSensor);
        pw.println(" " + mPeakRefreshRatePhysicalLimit);
    }

    private static class FlagState {
+11 −0
Original line number Diff line number Diff line
@@ -244,3 +244,14 @@ flag {
    bug: "306203895"
    is_fixed_read_only: true
}

flag {
    name: "enable_peak_refresh_rate_physical_limit"
    namespace: "display_manager"
    description: "Flag for adding physical refresh rate limit if smooth display setting is on "
    bug: "332413475"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+12 −2
Original line number Diff line number Diff line
@@ -940,6 +940,7 @@ public class DisplayModeDirector {
                Settings.Secure.getUriFor(Settings.Secure.MATCH_CONTENT_FRAME_RATE);

        private final boolean mVsynLowPowerVoteEnabled;
        private final boolean mPeakRefreshRatePhysicalLimitEnabled;

        private final Context mContext;
        private float mDefaultPeakRefreshRate;
@@ -950,6 +951,7 @@ public class DisplayModeDirector {
            super(handler);
            mContext = context;
            mVsynLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled();
            mPeakRefreshRatePhysicalLimitEnabled = flags.isPeakRefreshRatePhysicalLimitEnabled();
            // We don't want to load from the DeviceConfig while constructing since this leads to
            // a spike in the latency of DisplayManagerService startup. This happens because
            // reading from the DeviceConfig is an intensive IO operation and having it in the
@@ -1127,11 +1129,19 @@ public class DisplayModeDirector {
            // used to predict if we're going to be doing frequent refresh rate switching, and if
            // so, enable the brightness observer. The logic here is more complicated and fragile
            // than necessary, and we should improve it. See b/156304339 for more info.
            if (mPeakRefreshRatePhysicalLimitEnabled) {
                Vote peakVote = peakRefreshRate == 0f
                        ? null
                        : Vote.forPhysicalRefreshRates(0f,
                                Math.max(minRefreshRate, peakRefreshRate));
                mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
                        peakVote);
            }
            Vote peakRenderVote = peakRefreshRate == 0f
                    ? null
                    : Vote.forRenderFrameRates(0f, Math.max(minRefreshRate, peakRefreshRate));
            mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
                    peakVote);
                    peakRenderVote);
            mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
                    Vote.forRenderFrameRates(minRefreshRate, Float.POSITIVE_INFINITY));
            Vote defaultVote =
+19 −13
Original line number Diff line number Diff line
@@ -76,46 +76,52 @@ interface Vote {

    int PRIORITY_APP_REQUEST_SIZE = 7;

    // SETTING_PEAK_RENDER_FRAME_RATE has a high priority and will restrict the bounds of the
    // rest of low priority voters. It votes [0, max(PEAK, MIN)]
    int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 8;
    // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to
    // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values
    int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8;

    // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than
    // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)]
    // in case physical refresh rate vote is discarded (due to other high priority votes),
    // render rate vote can still apply
    int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9;

    // Restrict all displays to 60Hz when external display is connected. It votes [59Hz, 61Hz].
    int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 9;
    int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10;

    // Restrict displays max available resolution and refresh rates. It votes [0, LIMIT]
    int PRIORITY_LIMIT_MODE = 10;
    int PRIORITY_LIMIT_MODE = 11;

    // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh
    // rate to max value (same as for PRIORITY_UDFPS) on lock screen
    int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 11;
    int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 12;

    // For concurrent displays we want to limit refresh rate on all displays
    int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 12;
    int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 13;

    // For internal application to limit display modes to specific ids
    int PRIORITY_SYSTEM_REQUESTED_MODES = 13;
    int PRIORITY_SYSTEM_REQUESTED_MODES = 14;

    // LOW_POWER_MODE force the render frame rate to [0, 60HZ] if
    // Settings.Global.LOW_POWER_MODE is on.
    int PRIORITY_LOW_POWER_MODE = 14;
    int PRIORITY_LOW_POWER_MODE = 15;

    // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the
    // higher priority voters' result is a range, it will fix the rate to a single choice.
    // It's used to avoid refresh rate switches in certain conditions which may result in the
    // user seeing the display flickering when the switches occur.
    int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 15;
    int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 16;

    // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
    int PRIORITY_SKIN_TEMPERATURE = 16;
    int PRIORITY_SKIN_TEMPERATURE = 17;

    // The proximity sensor needs the refresh rate to be locked in order to function, so this is
    // set to a high priority.
    int PRIORITY_PROXIMITY = 17;
    int PRIORITY_PROXIMITY = 18;

    // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
    // to function, so this needs to be the highest priority of all votes.
    int PRIORITY_UDFPS = 18;
    int PRIORITY_UDFPS = 19;

    // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
    // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
+0 −56
Original line number Diff line number Diff line
@@ -78,7 +78,6 @@ import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.SurfaceControl.IdleScreenRefreshRateConfig;
import android.view.SurfaceControl.RefreshRateRange;
import android.view.SurfaceControl.RefreshRateRanges;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -843,61 +842,6 @@ public class DisplayModeDirectorTest {
        assertThat(desiredSpecs.appRequest.physical.max).isAtLeast(expectedAppRequestedRefreshRate);
    }

    void verifySpecsWithRefreshRateSettings(DisplayModeDirector director, float minFps,
            float peakFps, float defaultFps, RefreshRateRanges primary,
            RefreshRateRanges appRequest) {
        DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(
                minFps, peakFps, defaultFps);
        assertThat(specs.primary).isEqualTo(primary);
        assertThat(specs.appRequest).isEqualTo(appRequest);
    }

    @Test
    public void testSpecsFromRefreshRateSettings() {
        // Confirm that, with varying settings for min, peak, and default refresh rate,
        // DesiredDisplayModeSpecs is calculated correctly.
        float[] refreshRates = {30.f, 60.f, 90.f, 120.f, 150.f};
        DisplayModeDirector director =
                createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/0);

        float inf = Float.POSITIVE_INFINITY;
        RefreshRateRange rangeAll = new RefreshRateRange(0, inf);
        RefreshRateRange range0to60 = new RefreshRateRange(0, 60);
        RefreshRateRange range0to90 = new RefreshRateRange(0, 90);
        RefreshRateRange range0to120 = new RefreshRateRange(0, 120);
        RefreshRateRange range60to90 = new RefreshRateRange(60, 90);
        RefreshRateRange range90to90 = new RefreshRateRange(90, 90);
        RefreshRateRange range90to120 = new RefreshRateRange(90, 120);
        RefreshRateRange range60toInf = new RefreshRateRange(60, inf);
        RefreshRateRange range90toInf = new RefreshRateRange(90, inf);

        RefreshRateRanges frameRateAll = new RefreshRateRanges(rangeAll, rangeAll);
        RefreshRateRanges frameRate90toInf = new RefreshRateRanges(range90toInf, range90toInf);
        RefreshRateRanges frameRate0to60 = new RefreshRateRanges(rangeAll, range0to60);
        RefreshRateRanges frameRate0to90 = new RefreshRateRanges(rangeAll, range0to90);
        RefreshRateRanges frameRate0to120 = new RefreshRateRanges(rangeAll, range0to120);
        RefreshRateRanges frameRate60to90 = new RefreshRateRanges(range60toInf, range60to90);
        RefreshRateRanges frameRate90to90 = new RefreshRateRanges(range90toInf, range90to90);
        RefreshRateRanges frameRate90to120 = new RefreshRateRanges(range90toInf, range90to120);

        verifySpecsWithRefreshRateSettings(director, 0, 0, 0, frameRateAll, frameRateAll);
        verifySpecsWithRefreshRateSettings(director, 0, 0, 90, frameRate0to90, frameRateAll);
        verifySpecsWithRefreshRateSettings(director, 0, 90, 0, frameRate0to90, frameRate0to90);
        verifySpecsWithRefreshRateSettings(director, 0, 90, 60, frameRate0to60, frameRate0to90);
        verifySpecsWithRefreshRateSettings(director, 0, 90, 120, frameRate0to90,
                frameRate0to90);
        verifySpecsWithRefreshRateSettings(director, 90, 0, 0, frameRate90toInf, frameRateAll);
        verifySpecsWithRefreshRateSettings(director, 90, 0, 120, frameRate90to120,
                frameRateAll);
        verifySpecsWithRefreshRateSettings(director, 90, 0, 60, frameRate90toInf, frameRateAll);
        verifySpecsWithRefreshRateSettings(director, 90, 120, 0, frameRate90to120,
                frameRate0to120);
        verifySpecsWithRefreshRateSettings(director, 90, 60, 0, frameRate90to90,
                frameRate0to90);
        verifySpecsWithRefreshRateSettings(director, 60, 120, 90, frameRate60to90,
                frameRate0to120);
    }

    void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
            float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
        BrightnessObserver brightnessObserver = mock(BrightnessObserver.class);
Loading