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

Commit dd39ff9d authored by Kriti Dang's avatar Kriti Dang
Browse files

Handle interaction between minimal post processing and HDR output

control

Test: atest DisplayManagerServiceTest
Bug: 272684013
Change-Id: I376a2b6b628ac2d70884b10f8e6cbba64567484f
parent 181bcdba
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ public class DisplayControl {
    private static native int nativeSetHdrConversionMode(int conversionMode,
            int preferredHdrOutputType, int[] autoHdrTypes, int autoHdrTypesLength);
    private static native int[] nativeGetSupportedHdrOutputTypes();
    private static native int[] nativeGetHdrOutputTypesWithLatency();
    private static native boolean nativeGetHdrOutputConversionSupport();

    /**
@@ -127,6 +128,14 @@ public class DisplayControl {
        return nativeGetSupportedHdrOutputTypes();
    }

    /**
     * Returns the HDR output types which introduces latency on conversion to them.
     * @hide
     */
    public static @Display.HdrCapabilities.HdrType int[] getHdrOutputTypesWithLatency() {
        return nativeGetHdrOutputTypesWithLatency();
    }

    /**
     * Returns whether the HDR output conversion is supported by the device.
     * @hide
+49 −7
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
@@ -737,6 +738,20 @@ public final class DisplayManagerService extends SystemService {
        return mDisplayDeviceRepo;
    }

    @VisibleForTesting
    boolean isMinimalPostProcessingAllowed() {
        synchronized (mSyncRoot) {
            return mMinimalPostProcessingAllowed;
        }
    }

    @VisibleForTesting
    void setMinimalPostProcessingAllowed(boolean allowed) {
        synchronized (mSyncRoot) {
            mMinimalPostProcessingAllowed = allowed;
        }
    }

    private void loadStableDisplayValuesLocked() {
        final Point size = mPersistentDataStore.getStableDisplaySize();
        if (size.x > 0 && size.y > 0) {
@@ -937,8 +952,9 @@ public final class DisplayManagerService extends SystemService {
    }

    private void updateSettingsLocked() {
        mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
        setMinimalPostProcessingAllowed(Settings.Secure.getIntForUser(
                mContext.getContentResolver(), Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
                1, UserHandle.USER_CURRENT) != 0);
    }

    private void updateUserDisabledHdrTypesFromSettingsLocked() {
@@ -2166,6 +2182,17 @@ public final class DisplayManagerService extends SystemService {
        return autoHdrOutputTypesArray.toArray();
    }

    @GuardedBy("mSyncRoot")
    private boolean hdrConversionIntroducesLatencyLocked() {
        final int preferredHdrOutputType =
                getHdrConversionModeSettingInternal().getPreferredHdrOutputType();
        if (preferredHdrOutputType != Display.HdrCapabilities.HDR_TYPE_INVALID) {
            int[] hdrTypesWithLatency = mInjector.getHdrOutputTypesWithLatency();
            return ArrayUtils.contains(hdrTypesWithLatency, preferredHdrOutputType);
        }
        return false;
    }

    Display.Mode getUserPreferredDisplayModeInternal(int displayId) {
        synchronized (mSyncRoot) {
            if (displayId == Display.INVALID_DISPLAY) {
@@ -2243,7 +2270,7 @@ public final class DisplayManagerService extends SystemService {
        return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM);
    }

    private HdrConversionMode getHdrConversionModeInternal() {
    HdrConversionMode getHdrConversionModeInternal() {
        if (!mInjector.getHdrOutputConversionSupport()) {
            return HDR_CONVERSION_MODE_UNSUPPORTED;
        }
@@ -2400,7 +2427,7 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
    void setDisplayPropertiesInternal(int displayId, boolean hasContent,
            float requestedRefreshRate, int requestedModeId, float requestedMinRefreshRate,
            float requestedMaxRefreshRate, boolean preferMinimalPostProcessing,
            boolean disableHdrConversion, boolean inTraversal) {
@@ -2438,11 +2465,17 @@ public final class DisplayManagerService extends SystemService {

            // TODO(b/202378408) set minimal post-processing only if it's supported once we have a
            // separate API for disabling on-device processing.
            boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing;
            boolean mppRequest = isMinimalPostProcessingAllowed() && preferMinimalPostProcessing;
            boolean disableHdrConversionForLatency = false;

            if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
                display.setRequestedMinimalPostProcessingLocked(mppRequest);
                shouldScheduleTraversal = true;
                // If HDR conversion introduces latency, disable that in case minimal
                // post-processing is requested
                if (mppRequest) {
                    disableHdrConversionForLatency = hdrConversionIntroducesLatencyLocked();
                }
            }

            if (shouldScheduleTraversal) {
@@ -2452,12 +2485,17 @@ public final class DisplayManagerService extends SystemService {
            if (mHdrConversionMode == null) {
                return;
            }
            if (mOverrideHdrConversionMode == null && disableHdrConversion) {
            // HDR conversion is disabled in two cases:
            // - HDR conversion introduces latency and minimal post-processing is requested
            // - app requests to disable HDR conversion
            if (mOverrideHdrConversionMode == null && (disableHdrConversion
                    || disableHdrConversionForLatency)) {
                mOverrideHdrConversionMode =
                            new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH);
                setHdrConversionModeInternal(mHdrConversionMode);
                handleLogicalDisplayChangedLocked(display);
            } else if (mOverrideHdrConversionMode != null && !disableHdrConversion) {
            } else if (mOverrideHdrConversionMode != null && !disableHdrConversion
                    && !disableHdrConversionForLatency) {
                mOverrideHdrConversionMode = null;
                setHdrConversionModeInternal(mHdrConversionMode);
                handleLogicalDisplayChangedLocked(display);
@@ -3044,6 +3082,10 @@ public final class DisplayManagerService extends SystemService {
            return DisplayControl.getSupportedHdrOutputTypes();
        }

        int[] getHdrOutputTypesWithLatency() {
            return DisplayControl.getHdrOutputTypesWithLatency();
        }

        boolean getHdrOutputConversionSupport() {
            return DisplayControl.getHdrOutputConversionSupport();
        }
+29 −2
Original line number Diff line number Diff line
@@ -107,7 +107,32 @@ static jintArray nativeGetSupportedHdrOutputTypes(JNIEnv* env, jclass clazz) {
        return nullptr;
    }
    jint* arrayValues = env->GetIntArrayElements(array, 0);
    int index = 0;
    size_t index = 0;
    for (auto hdrOutputType : hdrOutputTypes) {
        arrayValues[index++] = static_cast<jint>(hdrOutputType);
    }
    env->ReleaseIntArrayElements(array, arrayValues, 0);
    return array;
}

static jintArray nativeGetHdrOutputTypesWithLatency(JNIEnv* env, jclass clazz) {
    std::vector<gui::HdrConversionCapability> hdrConversionCapabilities;
    SurfaceComposerClient::getHdrConversionCapabilities(&hdrConversionCapabilities);

    // Extract unique HDR output types with latency.
    std::set<int> hdrOutputTypes;
    for (const auto& hdrConversionCapability : hdrConversionCapabilities) {
        if (hdrConversionCapability.outputType > 0 && hdrConversionCapability.addsLatency) {
            hdrOutputTypes.insert(hdrConversionCapability.outputType);
        }
    }
    jintArray array = env->NewIntArray(hdrOutputTypes.size());
    if (array == nullptr) {
        jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
        return nullptr;
    }
    jint* arrayValues = env->GetIntArrayElements(array, 0);
    size_t index = 0;
    for (auto hdrOutputType : hdrOutputTypes) {
        arrayValues[index++] = static_cast<jint>(hdrOutputType);
    }
@@ -164,6 +189,8 @@ static const JNINativeMethod sDisplayMethods[] = {
            (void*)nativeSetHdrConversionMode },
    {"nativeGetSupportedHdrOutputTypes", "()[I",
            (void*)nativeGetSupportedHdrOutputTypes },
    {"nativeGetHdrOutputTypesWithLatency", "()[I",
            (void*)nativeGetHdrOutputTypesWithLatency },
    {"nativeGetHdrOutputConversionSupport", "()Z",
            (void*) nativeGetHdrOutputConversionSupport },
        // clang-format on
+43 −0
Original line number Diff line number Diff line
@@ -220,6 +220,11 @@ public class DisplayManagerServiceTest {
            return new int[]{};
        }

        @Override
        int[] getHdrOutputTypesWithLatency() {
            return new int[]{Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION};
        }

        boolean getHdrOutputConversionSupport() {
            return true;
        }
@@ -1862,6 +1867,44 @@ public class DisplayManagerServiceTest {
        assertEquals(mode.getPreferredHdrOutputType(), mPreferredHdrOutputType);
    }

    @Test
    public void testHdrConversionMode_withMinimalPostProcessing() {
        DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
        DisplayManagerService.BinderService displayManagerBinderService =
                displayManager.new BinderService();
        registerDefaultDisplays(displayManager);
        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
        FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
                new float[]{60f, 30f, 20f});
        int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
                displayDevice);

        final HdrConversionMode mode = new HdrConversionMode(
                HdrConversionMode.HDR_CONVERSION_FORCE,
                Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION);
        displayManager.setHdrConversionModeInternal(mode);
        assertEquals(mode, displayManager.getHdrConversionModeSettingInternal());

        displayManager.setMinimalPostProcessingAllowed(true);
        displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */,
                30.0f /* requestedRefreshRate */,
                displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */,
                30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */,
                true /* preferMinimalPostProcessing */, false /* disableHdrConversion */,
                true /* inTraversal */);

        assertEquals(new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH),
                displayManager.getHdrConversionModeInternal());

        displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */,
                30.0f /* requestedRefreshRate */,
                displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */,
                30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */,
                false /* preferMinimalPostProcessing */, false /* disableHdrConversion */,
                true /* inTraversal */);
        assertEquals(mode, displayManager.getHdrConversionModeInternal());
    }

    private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
            throws Exception {
        DisplayManagerService displayManager =