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

Commit 3e7dd917 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use median instead of mean for sampling border luma" into rvc-dev

parents ca51ab41 c4bbdff6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ class ScreenRotationAnimation {
            SurfaceControl.ScreenshotGraphicBuffer gb =
                    mService.mDisplayManagerInternal.screenshot(displayId);
            if (gb != null) {
                mStartLuma = RotationAnimationUtils.getAvgBorderLuma(gb.getGraphicBuffer(),
                mStartLuma = RotationAnimationUtils.getMedianBorderLuma(gb.getGraphicBuffer(),
                        gb.getColorSpace());
                try {
                    surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
+17 −11
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;

import java.util.Arrays;


/** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/
public class RotationAnimationUtils {
@@ -35,31 +37,35 @@ public class RotationAnimationUtils {
     * luminance at the borders of the bitmap
     * @return the average luminance of all the pixels at the borders of the bitmap
     */
    public static float getAvgBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
    public static float getMedianBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
        Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace);
        if (hwBitmap == null) {
            return 0;
        }

        Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false);
        float totalLuma = 0;
        int height = swaBitmap.getHeight();
        int width = swaBitmap.getWidth();
        float[] borderLumas = new float[2 * width + 2 * height];
        int i;
        for (i = 0; i < width; i++) {
            totalLuma += swaBitmap.getColor(i, 0).luminance();
            totalLuma += swaBitmap.getColor(i, height - 1).luminance();
        int index = 0;
        for (i = 0; i < width; i++, index += 2) {
            borderLumas[index] = swaBitmap.getColor(i, 0).luminance();
            borderLumas[index + 1] = swaBitmap.getColor(i, height - 1).luminance();
        }
        for (i = 0; i < height; i++) {
            totalLuma += swaBitmap.getColor(0, i).luminance();
            totalLuma += swaBitmap.getColor(width - 1, i).luminance();
        for (i = 0; i < height; i++, index += 2) {
            borderLumas[index] = swaBitmap.getColor(0, i).luminance();
            borderLumas[index + 1] = swaBitmap.getColor(width - 1, i).luminance();
        }
        return totalLuma / (2 * width + 2 * height);
        // Oh, is this too simple and inefficient for you?
        // How about implementing a O(n) solution? https://en.wikipedia.org/wiki/Median_of_medians
        Arrays.sort(borderLumas);
        return borderLumas[borderLumas.length / 2];
    }

    /**
     * Gets the average border luma by taking a screenshot of the {@param surfaceControl}.
     * @see #getAvgBorderLuma(GraphicBuffer, ColorSpace)
     * @see #getMedianBorderLuma(GraphicBuffer, ColorSpace)
     */
    public static float getLumaOfSurfaceControl(Display display, SurfaceControl surfaceControl) {
        if (surfaceControl ==  null) {
@@ -75,7 +81,7 @@ public class RotationAnimationUtils {
            return 0;
        }

        return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(),
        return RotationAnimationUtils.getMedianBorderLuma(buffer.getGraphicBuffer(),
                buffer.getColorSpace());
    }

+19 −7
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ public class RotationAnimationUtilsTest {
    public void blackLuma() {
        Bitmap swBitmap = createBitmap(0);
        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
        float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
        assertEquals(0, borderLuma, 0);
    }

@@ -58,7 +58,15 @@ public class RotationAnimationUtilsTest {
    public void whiteLuma() {
        Bitmap swBitmap = createBitmap(1);
        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
        float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
        assertEquals(1, borderLuma, 0);
    }

    @Test
    public void unevenBitmapDimens() {
        Bitmap swBitmap = createBitmap(1, BITMAP_WIDTH + 1, BITMAP_HEIGHT + 1);
        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
        float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
        assertEquals(1, borderLuma, 0);
    }

@@ -67,7 +75,7 @@ public class RotationAnimationUtilsTest {
        Bitmap swBitmap = createBitmap(1);
        setBorderLuma(swBitmap, 0);
        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
        float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
        assertEquals(0, borderLuma, 0);
    }

@@ -76,7 +84,7 @@ public class RotationAnimationUtilsTest {
        Bitmap swBitmap = createBitmap(0);
        setBorderLuma(swBitmap, 1);
        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
        float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
        assertEquals(1, borderLuma, 0);
    }

@@ -123,9 +131,13 @@ public class RotationAnimationUtilsTest {
    }

    private Bitmap createBitmap(float luma) {
        Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, ARGB_8888);
        for (int i = 0; i < BITMAP_WIDTH; i++) {
            for (int j = 0; j < BITMAP_HEIGHT; j++) {
        return createBitmap(luma, BITMAP_WIDTH, BITMAP_HEIGHT);
    }

    private Bitmap createBitmap(float luma, int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, ARGB_8888);
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                bitmap.setPixel(i, j, Color.argb(1, luma, luma, luma));
            }
        }