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

Commit ead24e2f authored by Winson Chung's avatar Winson Chung Committed by Automerger Merge Worker
Browse files

Merge "Minor optimization to skip bitmap copy during luma sampling" into rvc-dev am: d972004c

Change-Id: I07783175be949c0c446eb0a681181f03f996a0cd
parents f6244ab6 d972004c
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.wm;
package com.android.server.wm;


import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;

import static com.android.server.wm.AnimationSpecProto.ROTATE;
import static com.android.server.wm.AnimationSpecProto.ROTATE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
@@ -36,6 +38,7 @@ import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Trace;
import android.util.Slog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.Display;
@@ -205,8 +208,11 @@ class ScreenRotationAnimation {
            SurfaceControl.ScreenshotGraphicBuffer gb =
            SurfaceControl.ScreenshotGraphicBuffer gb =
                    mService.mDisplayManagerInternal.screenshot(displayId);
                    mService.mDisplayManagerInternal.screenshot(displayId);
            if (gb != null) {
            if (gb != null) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
                        "ScreenRotationAnimation#getMedianBorderLuma");
                mStartLuma = RotationAnimationUtils.getMedianBorderLuma(gb.getGraphicBuffer(),
                mStartLuma = RotationAnimationUtils.getMedianBorderLuma(gb.getGraphicBuffer(),
                        gb.getColorSpace());
                        gb.getColorSpace());
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                try {
                try {
                    surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
                    surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
                            gb.getColorSpace());
                            gb.getColorSpace());
+47 −14
Original line number Original line Diff line number Diff line
@@ -16,16 +16,21 @@


package com.android.server.wm.utils;
package com.android.server.wm.utils;


import android.graphics.Bitmap;
import static android.graphics.PixelFormat.RGBA_8888;

import android.graphics.Color;
import android.graphics.ColorSpace;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Rect;
import android.media.Image;
import android.media.ImageReader;
import android.view.Display;
import android.view.Display;
import android.view.Surface;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl;


import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Arrays;




@@ -38,31 +43,59 @@ public class RotationAnimationUtils {
     * @return the average luminance of all the pixels at the borders of the bitmap
     * @return the average luminance of all the pixels at the borders of the bitmap
     */
     */
    public static float getMedianBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
    public static float getMedianBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
        Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace);
        if (graphicBuffer == null || graphicBuffer.getFormat() != RGBA_8888) {
        if (hwBitmap == null) {
            return 0;
            return 0;
        }
        }


        Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false);
        ImageReader ir = ImageReader.newInstance(graphicBuffer.getWidth(),
        int height = swaBitmap.getHeight();
                graphicBuffer.getHeight(), graphicBuffer.getFormat(), 1);
        int width = swaBitmap.getWidth();
        ir.getSurface().attachAndQueueBufferWithColorSpace(graphicBuffer, colorSpace);
        Image image = ir.acquireLatestImage();
        if (image == null || image.getPlanes().length == 0) {
            return 0;
        }

        Image.Plane plane = image.getPlanes()[0];
        ByteBuffer buffer = plane.getBuffer();
        int width = image.getWidth();
        int height = image.getHeight();
        int pixelStride = plane.getPixelStride();
        int rowStride = plane.getRowStride();
        float[] borderLumas = new float[2 * width + 2 * height];
        float[] borderLumas = new float[2 * width + 2 * height];
        int i;

        int index = 0;
        // Grab the top and bottom borders
        for (i = 0; i < width; i++, index += 2) {
        int l = 0;
            borderLumas[index] = swaBitmap.getColor(i, 0).luminance();
        for (int x = 0; x < width; x++) {
            borderLumas[index + 1] = swaBitmap.getColor(i, height - 1).luminance();
            borderLumas[l++] = getPixelLuminance(buffer, x, 0, pixelStride, rowStride);
            borderLumas[l++] = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride);
        }
        }
        for (i = 0; i < height; i++, index += 2) {

            borderLumas[index] = swaBitmap.getColor(0, i).luminance();
        // Grab the left and right borders
            borderLumas[index + 1] = swaBitmap.getColor(width - 1, i).luminance();
        for (int y = 0; y < height; y++) {
            borderLumas[l++] = getPixelLuminance(buffer, 0, y, pixelStride, rowStride);
            borderLumas[l++] = getPixelLuminance(buffer, width - 1, y, pixelStride, rowStride);
        }
        }

        // Cleanup
        ir.close();

        // Oh, is this too simple and inefficient for you?
        // Oh, is this too simple and inefficient for you?
        // How about implementing a O(n) solution? https://en.wikipedia.org/wiki/Median_of_medians
        // How about implementing a O(n) solution? https://en.wikipedia.org/wiki/Median_of_medians
        Arrays.sort(borderLumas);
        Arrays.sort(borderLumas);
        return borderLumas[borderLumas.length / 2];
        return borderLumas[borderLumas.length / 2];
    }
    }


    private static float getPixelLuminance(ByteBuffer buffer, int x, int y,
            int pixelStride, int rowStride) {
        int offset = y * rowStride + x * pixelStride;
        int pixel = 0;
        pixel |= (buffer.get(offset) & 0xff) << 16;     // R
        pixel |= (buffer.get(offset + 1) & 0xff) << 8;  // G
        pixel |= (buffer.get(offset + 2) & 0xff);       // B
        pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
        return Color.valueOf(pixel).luminance();
    }

    /**
    /**
     * Gets the average border luma by taking a screenshot of the {@param surfaceControl}.
     * Gets the average border luma by taking a screenshot of the {@param surfaceControl}.
     * @see #getMedianBorderLuma(GraphicBuffer, ColorSpace)
     * @see #getMedianBorderLuma(GraphicBuffer, ColorSpace)