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

Commit d3d8ca36 authored by Oleg Blinnikov's avatar Oleg Blinnikov
Browse files

Resolution range voting in DisplayModeDirector

Change-Id: Iadaf82cfde007daa955a3fc5159d09bcc0e499bd
Test: atest DisplayModeDirectorTest
Bug: 242093547
parent 3bd5f4c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -556,7 +556,7 @@ public final class DisplayManagerService extends SystemService {
        mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
                new FoldSettingProvider(mContext, new SettingsWrapper()), mDisplayDeviceRepo,
                new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
        mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
        mDisplayModeDirector = new DisplayModeDirector(context, mHandler, mFlags);
        mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
        Resources resources = mContext.getResources();
        mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
+9 −0
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ public class DisplayManagerFlags {
            Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1,
            Flags::enableAdaptiveToneImprovements1);

    private final FlagState mDisplayResolutionRangeVotingState = new FlagState(
            Flags.FLAG_ENABLE_DISPLAY_RESOLUTION_RANGE_VOTING,
            Flags::enableDisplayResolutionRangeVoting);

    /** Returns whether connected display management is enabled or not. */
    public boolean isConnectedDisplayManagementEnabled() {
        return mConnectedDisplayManagementFlagState.isEnabled();
@@ -68,6 +72,11 @@ public class DisplayManagerFlags {
        return mAdaptiveToneImprovements1.isEnabled();
    }

    /** Returns whether resolution range voting feature is enabled or not. */
    public boolean isDisplayResolutionRangeVotingEnabled() {
        return mDisplayResolutionRangeVotingState.isEnabled();
    }

    private static class FlagState {

        private final String mName;
+8 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ package: "com.android.server.display.feature.flags"
flag {
    name: "enable_connected_display_management"
    namespace: "display_manager"
    description: "Feature flag for Connected Display managment"
    description: "Feature flag for Connected Display management"
    bug: "280739508"
    is_fixed_read_only: true
}
@@ -34,3 +34,10 @@ flag {
    is_fixed_read_only: true
}

flag {
    name: "enable_display_resolution_range_voting"
    namespace: "display_manager"
    description: "Feature flag to enable voting for ranges of resolutions"
    bug: "299297058"
    is_fixed_read_only: true
}
+65 −8
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterFactory;
import com.android.server.display.utils.DeviceConfigParsingUtils;
@@ -151,12 +152,21 @@ public class DisplayModeDirector {
    @DisplayManager.SwitchingType
    private int mModeSwitchingType = DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;

    public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
        this(context, handler, new RealInjector(context));
    /**
     * Whether resolution range voting feature is enabled.
     */
    private final boolean mIsDisplayResolutionRangeVotingEnabled;

    public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
            @NonNull DisplayManagerFlags displayManagerFlags) {
        this(context, handler, new RealInjector(context), displayManagerFlags);
    }

    public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
            @NonNull Injector injector) {
            @NonNull Injector injector,
            @NonNull DisplayManagerFlags displayManagerFlags) {
        mIsDisplayResolutionRangeVotingEnabled = displayManagerFlags
                .isDisplayResolutionRangeVotingEnabled();
        mContext = context;
        mHandler = new DisplayModeDirectorHandler(handler.getLooper());
        mInjector = injector;
@@ -230,6 +240,8 @@ public class DisplayModeDirector {
        public float maxRenderFrameRate;
        public int width;
        public int height;
        public int minWidth;
        public int minHeight;
        public boolean disableRefreshRateSwitching;
        public float appRequestBaseModeRefreshRate;

@@ -244,6 +256,8 @@ public class DisplayModeDirector {
            maxRenderFrameRate = Float.POSITIVE_INFINITY;
            width = Vote.INVALID_SIZE;
            height = Vote.INVALID_SIZE;
            minWidth = 0;
            minHeight = 0;
            disableRefreshRateSwitching = false;
            appRequestBaseModeRefreshRate = 0f;
        }
@@ -256,6 +270,8 @@ public class DisplayModeDirector {
                    + ", maxRenderFrameRate=" + maxRenderFrameRate
                    + ", width=" + width
                    + ", height=" + height
                    + ", minWidth=" + minWidth
                    + ", minHeight=" + minHeight
                    + ", disableRefreshRateSwitching=" + disableRefreshRateSwitching
                    + ", appRequestBaseModeRefreshRate=" + appRequestBaseModeRefreshRate;
        }
@@ -277,7 +293,6 @@ public class DisplayModeDirector {
                continue;
            }


            // For physical refresh rates, just use the tightest bounds of all the votes.
            // The refresh rate cannot be lower than the minimal render frame rate.
            final float minPhysicalRefreshRate = Math.max(vote.refreshRateRanges.physical.min,
@@ -298,10 +313,18 @@ public class DisplayModeDirector {
            // For display size, disable refresh rate switching and base mode refresh rate use only
            // the first vote we come across (i.e. the highest priority vote that includes the
            // attribute).
            if (summary.height == Vote.INVALID_SIZE && summary.width == Vote.INVALID_SIZE
                    && vote.height > 0 && vote.width > 0) {
            if (vote.height > 0 && vote.width > 0) {
                if (summary.width == Vote.INVALID_SIZE && summary.height == Vote.INVALID_SIZE) {
                    summary.width = vote.width;
                    summary.height = vote.height;
                    summary.minWidth = vote.minWidth;
                    summary.minHeight = vote.minHeight;
                } else if (mIsDisplayResolutionRangeVotingEnabled) {
                    summary.width = Math.min(summary.width, vote.width);
                    summary.height = Math.min(summary.height, vote.height);
                    summary.minWidth = Math.max(summary.minWidth, vote.minWidth);
                    summary.minHeight = Math.max(summary.minHeight, vote.minHeight);
                }
            }
            if (!summary.disableRefreshRateSwitching && vote.disableRefreshRateSwitching) {
                summary.disableRefreshRateSwitching = true;
@@ -413,6 +436,8 @@ public class DisplayModeDirector {
                        || primarySummary.width == Vote.INVALID_SIZE) {
                    primarySummary.width = defaultMode.getPhysicalWidth();
                    primarySummary.height = defaultMode.getPhysicalHeight();
                } else if (mIsDisplayResolutionRangeVotingEnabled) {
                    updateSummaryWithBestAllowedResolution(modes, primarySummary);
                }

                availableModes = filterModes(modes, primarySummary);
@@ -654,6 +679,38 @@ public class DisplayModeDirector {
        return availableModes;
    }

    private void updateSummaryWithBestAllowedResolution(final Display.Mode[] supportedModes,
            VoteSummary outSummary) {
        final int maxAllowedWidth = outSummary.width;
        final int maxAllowedHeight = outSummary.height;
        if (mLoggingEnabled) {
            Slog.i(TAG, "updateSummaryWithBestAllowedResolution " + outSummary);
        }
        outSummary.width = Vote.INVALID_SIZE;
        outSummary.height = Vote.INVALID_SIZE;

        int maxNumberOfPixels = 0;
        for (Display.Mode mode : supportedModes) {
            if (mode.getPhysicalWidth() > maxAllowedWidth
                    || mode.getPhysicalHeight() > maxAllowedHeight
                    || mode.getPhysicalWidth() < outSummary.minWidth
                    || mode.getPhysicalHeight() < outSummary.minHeight) {
                continue;
            }

            int numberOfPixels = mode.getPhysicalHeight() * mode.getPhysicalWidth();
            if (numberOfPixels > maxNumberOfPixels || (mode.getPhysicalWidth() == maxAllowedWidth
                    && mode.getPhysicalHeight() == maxAllowedHeight)) {
                if (mLoggingEnabled) {
                    Slog.i(TAG, "updateSummaryWithBestAllowedResolution updated with " + mode);
                }
                maxNumberOfPixels = numberOfPixels;
                outSummary.width = mode.getPhysicalWidth();
                outSummary.height = mode.getPhysicalHeight();
            }
        }
    }

    /**
     * Gets the observer responsible for application display mode requests.
     */
+65 −16
Original line number Diff line number Diff line
@@ -126,6 +126,14 @@ final class Vote {
     * The requested height of the display in pixels, or INVALID_SIZE;
     */
    public final int height;
    /**
     * Min requested width of the display in pixels, or 0;
     */
    public final int minWidth;
    /**
     * Min requested height of the display in pixels, or 0;
     */
    public final int minHeight;
    /**
     * Information about the refresh rate frame rate ranges DM would like to set the display to.
     */
@@ -144,42 +152,82 @@ final class Vote {
    public final float appRequestBaseModeRefreshRate;

    static Vote forPhysicalRefreshRates(float minRefreshRate, float maxRefreshRate) {
        return new Vote(INVALID_SIZE, INVALID_SIZE, minRefreshRate, maxRefreshRate, 0,
                Float.POSITIVE_INFINITY,
                minRefreshRate == maxRefreshRate, 0f);
        return new Vote(/* minWidth= */ 0, /* minHeight= */ 0,
                /* width= */ INVALID_SIZE, /* height= */ INVALID_SIZE,
                /* minPhysicalRefreshRate= */ minRefreshRate,
                /* maxPhysicalRefreshRate= */ maxRefreshRate,
                /* minRenderFrameRate= */ 0,
                /* maxRenderFrameRate= */ Float.POSITIVE_INFINITY,
                /* disableRefreshRateSwitching= */ minRefreshRate == maxRefreshRate,
                /* baseModeRefreshRate= */ 0f);
    }

    static Vote forRenderFrameRates(float minFrameRate, float maxFrameRate) {
        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, minFrameRate,
        return new Vote(/* minWidth= */ 0, /* minHeight= */ 0,
                /* width= */ INVALID_SIZE, /* height= */ INVALID_SIZE,
                /* minPhysicalRefreshRate= */ 0,
                /* maxPhysicalRefreshRate= */ Float.POSITIVE_INFINITY,
                minFrameRate,
                maxFrameRate,
                false, 0f);
                /* disableRefreshRateSwitching= */ false,
                /* baseModeRefreshRate= */ 0f);
    }

    static Vote forSize(int width, int height) {
        return new Vote(width, height, 0, Float.POSITIVE_INFINITY, 0, Float.POSITIVE_INFINITY,
                false,
                0f);
        return new Vote(/* minWidth= */ width, /* minHeight= */ height,
                width, height,
                /* minPhysicalRefreshRate= */ 0,
                /* maxPhysicalRefreshRate= */ Float.POSITIVE_INFINITY,
                /* minRenderFrameRate= */ 0,
                /* maxRenderFrameRate= */ Float.POSITIVE_INFINITY,
                /* disableRefreshRateSwitching= */ false,
                /* baseModeRefreshRate= */ 0f);
    }

    static Vote forSizeAndPhysicalRefreshRatesRange(int minWidth, int minHeight,
            int width, int height, float minRefreshRate, float maxRefreshRate) {
        return new Vote(minWidth, minHeight,
                width, height,
                minRefreshRate,
                maxRefreshRate,
                /* minRenderFrameRate= */ 0,
                /* maxRenderFrameRate= */ Float.POSITIVE_INFINITY,
                /* disableRefreshRateSwitching= */ minRefreshRate == maxRefreshRate,
                /* baseModeRefreshRate= */ 0f);
    }

    static Vote forDisableRefreshRateSwitching() {
        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
                Float.POSITIVE_INFINITY, true,
                0f);
        return new Vote(/* minWidth= */ 0, /* minHeight= */ 0,
                /* width= */ INVALID_SIZE, /* height= */ INVALID_SIZE,
                /* minPhysicalRefreshRate= */ 0,
                /* maxPhysicalRefreshRate= */ Float.POSITIVE_INFINITY,
                /* minRenderFrameRate= */ 0,
                /* maxRenderFrameRate= */ Float.POSITIVE_INFINITY,
                /* disableRefreshRateSwitching= */ true,
                /* baseModeRefreshRate= */ 0f);
    }

    static Vote forBaseModeRefreshRate(float baseModeRefreshRate) {
        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
                Float.POSITIVE_INFINITY, false,
                baseModeRefreshRate);
        return new Vote(/* minWidth= */ 0, /* minHeight= */ 0,
                /* width= */ INVALID_SIZE, /* height= */ INVALID_SIZE,
                /* minPhysicalRefreshRate= */ 0,
                /* maxPhysicalRefreshRate= */ Float.POSITIVE_INFINITY,
                /* minRenderFrameRate= */ 0,
                /* maxRenderFrameRate= */ Float.POSITIVE_INFINITY,
                /* disableRefreshRateSwitching= */ false,
                /* baseModeRefreshRate= */ baseModeRefreshRate);
    }

    private Vote(int width, int height,
    private Vote(int minWidth, int minHeight,
            int width, int height,
            float minPhysicalRefreshRate,
            float maxPhysicalRefreshRate,
            float minRenderFrameRate,
            float maxRenderFrameRate,
            boolean disableRefreshRateSwitching,
            float baseModeRefreshRate) {
        this.minWidth = minWidth;
        this.minHeight = minHeight;
        this.width = width;
        this.height = height;
        this.refreshRateRanges = new SurfaceControl.RefreshRateRanges(
@@ -229,7 +277,8 @@ final class Vote {
    @Override
    public String toString() {
        return "Vote: {"
                + "width: " + width + ", height: " + height
                + "minWidth: " + minWidth + ", minHeight: " + minHeight
                + ", width: " + width + ", height: " + height
                + ", refreshRateRanges: " + refreshRateRanges
                + ", disableRefreshRateSwitching: " + disableRefreshRateSwitching
                + ", appRequestBaseModeRefreshRate: "  + appRequestBaseModeRefreshRate + "}";
Loading