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

Commit 645bfeaa authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Use median of border brightness as rotation background color

It was optimized in [1] to use "mode" to avoid sorting a big array
and deal with with some corner cases of distribution.

However, it may be more common to have an area with the same color
on one side of screen, e.g. a popup panel. Then its color may
dominate the result while other sides are evenly distributed.
So this restores the calculation to [2] by a more efficient way to
calculate the median by histogram, because the range of data is small.

[1]: Ieca9968e843b68d733e178edd725b628c542e872
[2]: I87bc87930aff48f90f271fc1783e70caf61dc7f4

Bug: 336255901
Test: adb shell wm size 2200x1600.
      Enable home rotation and auto rotation.
      Set a complex wallpaper which has various color at edges.
      Open AllApps drawer of home and rotate.
      The background color shouldn't be too bright (by the drawer).
Change-Id: I027ede52b5884de2dd6ad27243a0de3bf9316a09
parent b9406495
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -1340,35 +1340,39 @@ public class TransitionAnimation {
        final int pixelStride = plane.getPixelStride();
        final int rowStride = plane.getRowStride();
        final int sampling = 10;
        final int[] borderLumas = new int[(width + height) * 2 / sampling];
        final int[] histogram = new int[256];

        // Grab the top and bottom borders.
        int i = 0;
        for (int x = 0, size = width - sampling; x < size; x += sampling) {
            borderLumas[i++] = getPixelLuminance(buffer, x, 0, pixelStride, rowStride);
            borderLumas[i++] = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride);
            final int topLm = getPixelLuminance(buffer, x, 0, pixelStride, rowStride);
            final int bottomLm = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride);
            histogram[topLm]++;
            histogram[bottomLm]++;
        }

        // Grab the left and right borders.
        for (int y = 0, size = height - sampling; y < size; y += sampling) {
            borderLumas[i++] = getPixelLuminance(buffer, 0, y, pixelStride, rowStride);
            borderLumas[i++] = getPixelLuminance(buffer, width - 1, y, pixelStride, rowStride);
            final int leftLm = getPixelLuminance(buffer, 0, y, pixelStride, rowStride);
            final int rightLm = getPixelLuminance(buffer, width - 1, y, pixelStride, rowStride);
            histogram[leftLm]++;
            histogram[rightLm]++;
        }

        ir.close();

        // Get "mode" by histogram.
        final int[] histogram = new int[256];
        int maxCount = 0;
        int mostLuma = 0;
        for (int luma : borderLumas) {
            final int count = ++histogram[luma];
            if (count > maxCount) {
                maxCount = count;
                mostLuma = luma;
        // Find the median from histogram.
        final int halfNum = (width + height) / sampling;
        int sum = 0;
        int medianLuminance = 0;
        for (i = 0; i < histogram.length; i++) {
            sum += histogram[i];
            if (sum >= halfNum) {
                medianLuminance = i;
                break;
            }
        }
        return mostLuma / 255f;
        return medianLuminance / 255f;
    }

    /** Returns the luminance of the pixel in 0~255. */