From cf8913451f550f12bf988438f2f3decafe4692a9 Mon Sep 17 00:00:00 2001 From: Sally Qi Date: Mon, 21 Mar 2022 19:30:19 -0700 Subject: [PATCH] Disable HDR dimming when screen rotates. - Disable dimming for screenshot layer This is to fix HDR flicker in picture-in-picture mode. Because the screenshot layer of rotation is an SDR image containing tone-mapping HDR content, and this would cause HDR part to be suddenly dimmed during rotation along with the entire screenshot, even though DisplayManager maintains different HDR and SDR while white points during during rotation animation. Therefore, we add a hidden api to allow to dim a particular layer. This effectively sets the white point for that layer to be same as the display brightness. Then the screenshot with this flag can be used a part of the rotation animation in order to remove flikering effects. Bug: 224860402 Test: check HDR vidoes when rotation Change-Id: Ib5c02635928cb9779e6f7968d2ec0ac9e659420b Merged-In: Ib5c02635928cb9779e6f7968d2ec0ac9e659420b --- core/java/android/view/SurfaceControl.java | 23 +++++++++++++++++++ core/jni/android_view_SurfaceControl.cpp | 11 ++++++++- .../server/wm/ScreenRotationAnimation.java | 4 ++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index da582c5b4b2f6..b5bbc75373919 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -221,6 +221,8 @@ public final class SurfaceControl implements Parcelable { @DataSpace.NamedDataSpace int dataSpace); private static native void nativeSetDamageRegion(long transactionObj, long nativeObject, Region region); + private static native void nativeSetDimmingEnabled(long transactionObj, long nativeObject, + boolean dimmingEnabled); private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes); @@ -3837,6 +3839,27 @@ public final class SurfaceControl implements Parcelable { return this; } + /** + * Set if the layer can be dimmed. + * + *

Dimming is to adjust brightness of the layer. + * Default value is {@code true}, which means the layer can be dimmed. + * Disabling dimming means the brightness of the layer can not be changed, i.e., + * keep the white point for the layer same as the display brightness.

+ * + * @param sc The SurfaceControl on which to enable or disable dimming. + * @param dimmingEnabled The dimming flag. + * @return this. + * + * @hide + */ + public @NonNull Transaction setDimmingEnabled(@NonNull SurfaceControl sc, + boolean dimmingEnabled) { + checkPreconditions(sc); + nativeSetDimmingEnabled(mNativeObject, sc.mNativeObject, dimmingEnabled); + return this; + } + /** * Set the color space for the SurfaceControl. The supported color spaces are SRGB * and Display P3, other color spaces will be treated as SRGB. This can only be used for diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 39f192b662eed..518fc09dee5aa 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -851,6 +851,14 @@ static void nativeSetDamageRegion(JNIEnv* env, jclass clazz, jlong transactionOb transaction->setSurfaceDamageRegion(surfaceControl, region); } +static void nativeSetDimmingEnabled(JNIEnv* env, jclass clazz, jlong transactionObj, + jlong nativeObject, jboolean dimmingEnabled) { + auto transaction = reinterpret_cast(transactionObj); + + SurfaceControl* const ctrl = reinterpret_cast(nativeObject); + transaction->setDimmingEnabled(ctrl, dimmingEnabled); +} + static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jfloat alpha) { auto transaction = reinterpret_cast(transactionObj); @@ -2095,8 +2103,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetSize }, {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V", (void*)nativeSetTransparentRegionHint }, - { "nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V", + {"nativeSetDamageRegion", "(JJLandroid/graphics/Region;)V", (void*)nativeSetDamageRegion }, + {"nativeSetDimmingEnabled", "(JJZ)V", (void*)nativeSetDimmingEnabled }, {"nativeSetAlpha", "(JJF)V", (void*)nativeSetAlpha }, {"nativeSetColor", "(JJ[F)V", diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 6bb63d933353a..65ae3fcb4c900 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -216,6 +216,10 @@ class ScreenRotationAnimation { t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); + // If hdr layers are on-screen, e.g. picture-in-picture mode, the screenshot of + // rotation animation is an sdr image containing tone-mapping hdr content, then + // disable dimming effect to get avoid of hdr content being dimmed during animation. + t.setDimmingEnabled(mScreenshotLayer, false); t.setLayer(mBackColorSurface, -1); t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma}); t.setAlpha(mBackColorSurface, 1);