Merge "Handle interaction between minimal post processing and HDR output control" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
79e56488de
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
|||||||
Reference in New Issue
Block a user