Merge "Handle interaction between minimal post processing and HDR output control" into udc-dev

This commit is contained in:
Treehugger Robot
2023-05-17 16:45:44 +00:00
committed by Android (Google) Code Review
4 changed files with 130 additions and 9 deletions

View File

@@ -37,6 +37,7 @@ public class DisplayControl {
private static native int nativeSetHdrConversionMode(int conversionMode, private static native int nativeSetHdrConversionMode(int conversionMode,
int preferredHdrOutputType, int[] autoHdrTypes, int autoHdrTypesLength); int preferredHdrOutputType, int[] autoHdrTypes, int autoHdrTypesLength);
private static native int[] nativeGetSupportedHdrOutputTypes(); private static native int[] nativeGetSupportedHdrOutputTypes();
private static native int[] nativeGetHdrOutputTypesWithLatency();
private static native boolean nativeGetHdrOutputConversionSupport(); private static native boolean nativeGetHdrOutputConversionSupport();
/** /**
@@ -127,6 +128,14 @@ public class DisplayControl {
return nativeGetSupportedHdrOutputTypes(); 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. * Returns whether the HDR output conversion is supported by the device.
* @hide * @hide

View File

@@ -141,6 +141,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer; import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread; import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
@@ -737,6 +738,20 @@ public final class DisplayManagerService extends SystemService {
return mDisplayDeviceRepo; return mDisplayDeviceRepo;
} }
@VisibleForTesting
boolean isMinimalPostProcessingAllowed() {
synchronized (mSyncRoot) {
return mMinimalPostProcessingAllowed;
}
}
@VisibleForTesting
void setMinimalPostProcessingAllowed(boolean allowed) {
synchronized (mSyncRoot) {
mMinimalPostProcessingAllowed = allowed;
}
}
private void loadStableDisplayValuesLocked() { private void loadStableDisplayValuesLocked() {
final Point size = mPersistentDataStore.getStableDisplaySize(); final Point size = mPersistentDataStore.getStableDisplaySize();
if (size.x > 0 && size.y > 0) { if (size.x > 0 && size.y > 0) {
@@ -937,8 +952,9 @@ public final class DisplayManagerService extends SystemService {
} }
private void updateSettingsLocked() { private void updateSettingsLocked() {
mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(), setMinimalPostProcessingAllowed(Settings.Secure.getIntForUser(
Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0; mContext.getContentResolver(), Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
1, UserHandle.USER_CURRENT) != 0);
} }
private void updateUserDisabledHdrTypesFromSettingsLocked() { private void updateUserDisabledHdrTypesFromSettingsLocked() {
@@ -2166,6 +2182,17 @@ public final class DisplayManagerService extends SystemService {
return autoHdrOutputTypesArray.toArray(); 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) { Display.Mode getUserPreferredDisplayModeInternal(int displayId) {
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
if (displayId == Display.INVALID_DISPLAY) { if (displayId == Display.INVALID_DISPLAY) {
@@ -2243,7 +2270,7 @@ public final class DisplayManagerService extends SystemService {
return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM); return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM);
} }
private HdrConversionMode getHdrConversionModeInternal() { HdrConversionMode getHdrConversionModeInternal() {
if (!mInjector.getHdrOutputConversionSupport()) { if (!mInjector.getHdrOutputConversionSupport()) {
return HDR_CONVERSION_MODE_UNSUPPORTED; 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 requestedRefreshRate, int requestedModeId, float requestedMinRefreshRate,
float requestedMaxRefreshRate, boolean preferMinimalPostProcessing, float requestedMaxRefreshRate, boolean preferMinimalPostProcessing,
boolean disableHdrConversion, boolean inTraversal) { 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 // TODO(b/202378408) set minimal post-processing only if it's supported once we have a
// separate API for disabling on-device processing. // separate API for disabling on-device processing.
boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing; boolean mppRequest = isMinimalPostProcessingAllowed() && preferMinimalPostProcessing;
boolean disableHdrConversionForLatency = false;
if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) { if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
display.setRequestedMinimalPostProcessingLocked(mppRequest); display.setRequestedMinimalPostProcessingLocked(mppRequest);
shouldScheduleTraversal = true; shouldScheduleTraversal = true;
// If HDR conversion introduces latency, disable that in case minimal
// post-processing is requested
if (mppRequest) {
disableHdrConversionForLatency = hdrConversionIntroducesLatencyLocked();
}
} }
if (shouldScheduleTraversal) { if (shouldScheduleTraversal) {
@@ -2452,12 +2485,17 @@ public final class DisplayManagerService extends SystemService {
if (mHdrConversionMode == null) { if (mHdrConversionMode == null) {
return; 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 = mOverrideHdrConversionMode =
new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH); new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH);
setHdrConversionModeInternal(mHdrConversionMode); setHdrConversionModeInternal(mHdrConversionMode);
handleLogicalDisplayChangedLocked(display); handleLogicalDisplayChangedLocked(display);
} else if (mOverrideHdrConversionMode != null && !disableHdrConversion) { } else if (mOverrideHdrConversionMode != null && !disableHdrConversion
&& !disableHdrConversionForLatency) {
mOverrideHdrConversionMode = null; mOverrideHdrConversionMode = null;
setHdrConversionModeInternal(mHdrConversionMode); setHdrConversionModeInternal(mHdrConversionMode);
handleLogicalDisplayChangedLocked(display); handleLogicalDisplayChangedLocked(display);
@@ -3044,6 +3082,10 @@ public final class DisplayManagerService extends SystemService {
return DisplayControl.getSupportedHdrOutputTypes(); return DisplayControl.getSupportedHdrOutputTypes();
} }
int[] getHdrOutputTypesWithLatency() {
return DisplayControl.getHdrOutputTypesWithLatency();
}
boolean getHdrOutputConversionSupport() { boolean getHdrOutputConversionSupport() {
return DisplayControl.getHdrOutputConversionSupport(); return DisplayControl.getHdrOutputConversionSupport();
} }

View File

@@ -110,7 +110,32 @@ static jintArray nativeGetSupportedHdrOutputTypes(JNIEnv* env, jclass clazz) {
return nullptr; return nullptr;
} }
jint* arrayValues = env->GetIntArrayElements(array, 0); 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) { for (auto hdrOutputType : hdrOutputTypes) {
arrayValues[index++] = static_cast<jint>(hdrOutputType); arrayValues[index++] = static_cast<jint>(hdrOutputType);
} }
@@ -167,7 +192,9 @@ static const JNINativeMethod sDisplayMethods[] = {
(void*)nativeSetHdrConversionMode }, (void*)nativeSetHdrConversionMode },
{"nativeGetSupportedHdrOutputTypes", "()[I", {"nativeGetSupportedHdrOutputTypes", "()[I",
(void*)nativeGetSupportedHdrOutputTypes }, (void*)nativeGetSupportedHdrOutputTypes },
{"nativeGetHdrOutputConversionSupport", "()Z", {"nativeGetHdrOutputTypesWithLatency", "()[I",
(void*)nativeGetHdrOutputTypesWithLatency },
{"nativeGetHdrOutputConversionSupport", "()Z",
(void*) nativeGetHdrOutputConversionSupport }, (void*) nativeGetHdrOutputConversionSupport },
// clang-format on // clang-format on
}; };

View File

@@ -220,6 +220,11 @@ public class DisplayManagerServiceTest {
return new int[]{}; return new int[]{};
} }
@Override
int[] getHdrOutputTypesWithLatency() {
return new int[]{Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION};
}
boolean getHdrOutputConversionSupport() { boolean getHdrOutputConversionSupport() {
return true; return true;
} }
@@ -1862,6 +1867,44 @@ public class DisplayManagerServiceTest {
assertEquals(mode.getPreferredHdrOutputType(), mPreferredHdrOutputType); 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) private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
throws Exception { throws Exception {
DisplayManagerService displayManager = DisplayManagerService displayManager =