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

Commit 3d03ed36 authored by Alec Mouri's avatar Alec Mouri
Browse files

Propagate HDR information to screenshot animation.

The screenshot animation must know whether the screenshot contains HDR
layers so that it can correctly inform SurfaceFlinger whether its layer
can be dimmed.

This is due to the interplay of the following:
1. Devices are now able to configure DisplayManager to send
   significantly lower SDR white points relative to display brightness
   to SurfaceFlinger when HDR is simultaneously on-screen.
2. AIDL composer is required to support per-layer dimming, so that SDR
   layers may be dimmed to preserve the relative luminance of HDR video
   content.
3. Because the screenshot does not contain an HDR transfer function,
   SurfaceFlinger will treat the layer as SDR, and attempt to dim it.
4. Screen rotations containing HDR layers must request SurfaceFlinger to
   present the rotated screenshot at display brightness, to override
   (3) above. Otherwise, HDR content captured in the screenshot will
   suddenly dim during the rotation animation.
5. Also due to (3), DisplayManager no longer thinks that there is HDR
   content on screen, so a prior patch treated layers that requested to
   to be dimmed to be reported as HDR
   (I1d1b0dcaf230300ca34b84ea407d0817feb2c664). Otherwise, the display
   brightness will decrease during the animation and ramp back up
   afterwards.
6. But because of (5), screenshots that only contained SDR layers were
   incorrectly treated as HDR, which caused the display brightness to
   ramp up during the animation.

This patch fixes (6) by allowing for the screenshot animation to learn
whether the screenshot contains HDR layers, and request dimming
capabilities accordingly.

Bug: 230068567
Test: screen rotation
Change-Id: I6bbb2433f976e368bfe2c04e084e110cfb551c15
parent 75fb4d30
Loading
Loading
Loading
Loading
+17 −5
Original line number Original line Diff line number Diff line
@@ -785,12 +785,14 @@ public final class SurfaceControl implements Parcelable {
        private final HardwareBuffer mHardwareBuffer;
        private final HardwareBuffer mHardwareBuffer;
        private final ColorSpace mColorSpace;
        private final ColorSpace mColorSpace;
        private final boolean mContainsSecureLayers;
        private final boolean mContainsSecureLayers;
        private final boolean mContainsHdrLayers;


        public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
        public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
                boolean containsSecureLayers) {
                boolean containsSecureLayers, boolean containsHdrLayers) {
            mHardwareBuffer = hardwareBuffer;
            mHardwareBuffer = hardwareBuffer;
            mColorSpace = colorSpace;
            mColorSpace = colorSpace;
            mContainsSecureLayers = containsSecureLayers;
            mContainsSecureLayers = containsSecureLayers;
            mContainsHdrLayers = containsHdrLayers;
        }
        }


       /**
       /**
@@ -798,13 +800,15 @@ public final class SurfaceControl implements Parcelable {
        * @param hardwareBuffer The existing HardwareBuffer object
        * @param hardwareBuffer The existing HardwareBuffer object
        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
        * @param containsSecureLayers Indicates whether this graphic buffer contains captured
        * @param containsSecureLayers Indicates whether this graphic buffer contains captured
        *                             contents
        *                             contents of secure layers, in which case the screenshot
        *        of secure layers, in which case the screenshot should not be persisted.
        *                             should not be persisted.
        * @param containsHdrLayers Indicates whether this graphic buffer contains HDR content.
        */
        */
        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
                int namedColorSpace, boolean containsSecureLayers) {
                int namedColorSpace, boolean containsSecureLayers, boolean containsHdrLayers) {
            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
            return new ScreenshotHardwareBuffer(hardwareBuffer, colorSpace, containsSecureLayers);
            return new ScreenshotHardwareBuffer(
                    hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers);
        }
        }


        public ColorSpace getColorSpace() {
        public ColorSpace getColorSpace() {
@@ -818,6 +822,14 @@ public final class SurfaceControl implements Parcelable {
        public boolean containsSecureLayers() {
        public boolean containsSecureLayers() {
            return mContainsSecureLayers;
            return mContainsSecureLayers;
        }
        }
        /**
         * Returns whether the screenshot contains at least one HDR layer.
         * This information may be useful for informing the display whether this screenshot
         * is allowed to be dimmed to SDR white.
         */
        public boolean containsHdrLayers() {
            return mContainsHdrLayers;
        }


        /**
        /**
         * Copy content of ScreenshotHardwareBuffer into a hardware bitmap and return it.
         * Copy content of ScreenshotHardwareBuffer into a hardware bitmap and return it.
+3 −2
Original line number Original line Diff line number Diff line
@@ -322,7 +322,8 @@ public:
                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                            gScreenshotHardwareBufferClassInfo.builder,
                                            gScreenshotHardwareBufferClassInfo.builder,
                                            jhardwareBuffer, namedColorSpace,
                                            jhardwareBuffer, namedColorSpace,
                                            captureResults.capturedSecureLayers);
                                            captureResults.capturedSecureLayers,
                                            captureResults.capturedHdrLayers);
        env->CallVoidMethod(screenCaptureListenerObject,
        env->CallVoidMethod(screenCaptureListenerObject,
                            gScreenCaptureListenerClassInfo.onScreenCaptureComplete,
                            gScreenCaptureListenerClassInfo.onScreenCaptureComplete,
                            screenshotHardwareBuffer);
                            screenshotHardwareBuffer);
@@ -2399,7 +2400,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
    gScreenshotHardwareBufferClassInfo.builder =
    gScreenshotHardwareBufferClassInfo.builder =
            GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
            GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
                                   "(Landroid/hardware/HardwareBuffer;IZ)Landroid/view/"
                                   "(Landroid/hardware/HardwareBuffer;IZZ)Landroid/view/"
                                   "SurfaceControl$ScreenshotHardwareBuffer;");
                                   "SurfaceControl$ScreenshotHardwareBuffer;");


    jclass displayedContentSampleClazz = FindClassOrDie(env,
    jclass displayedContentSampleClazz = FindClassOrDie(env,
+5 −2
Original line number Original line Diff line number Diff line
@@ -454,8 +454,11 @@ public class BubbleExpandedView extends LinearLayout {
                    p.beginRecording(mOverflowView.getWidth(), mOverflowView.getHeight()));
                    p.beginRecording(mOverflowView.getWidth(), mOverflowView.getHeight()));
            p.endRecording();
            p.endRecording();
            Bitmap snapshot = Bitmap.createBitmap(p);
            Bitmap snapshot = Bitmap.createBitmap(p);
            return new SurfaceControl.ScreenshotHardwareBuffer(snapshot.getHardwareBuffer(),
            return new SurfaceControl.ScreenshotHardwareBuffer(
                    snapshot.getColorSpace(), false /* containsSecureLayers */);
                    snapshot.getHardwareBuffer(),
                    snapshot.getColorSpace(),
                    false /* containsSecureLayers */,
                    false /* containsHdrLayers */);
        }
        }
        if (mTaskView == null || mTaskView.getSurfaceControl() == null) {
        if (mTaskView == null || mTaskView.getSurfaceControl() == null) {
            return null;
            return null;
+1 −1
Original line number Original line Diff line number Diff line
@@ -219,7 +219,7 @@ class ScreenRotationAnimation {
            // If hdr layers are on-screen, e.g. picture-in-picture mode, the screenshot of
            // 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
            // 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.
            // disable dimming effect to get avoid of hdr content being dimmed during animation.
            t.setDimmingEnabled(mScreenshotLayer, false);
            t.setDimmingEnabled(mScreenshotLayer, !screenshotBuffer.containsHdrLayers());
            t.setLayer(mBackColorSurface, -1);
            t.setLayer(mBackColorSurface, -1);
            t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
            t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
            t.setAlpha(mBackColorSurface, 1);
            t.setAlpha(mBackColorSurface, 1);