diff options
| author | 2022-10-24 01:03:38 +0000 | |
|---|---|---|
| committer | 2022-10-24 01:03:38 +0000 | |
| commit | df86b40c331644cb76815d51fa8e1ef39528ef02 (patch) | |
| tree | d08cffa130f1bfcf8b8fbcff000092a811ca7651 /libs | |
| parent | c9f364c06bca8f8865dfbdf043417c5c03522149 (diff) | |
| parent | f33d16345750bca2927fa9a6aedaeec6a30ef1bb (diff) | |
Merge "Optimize luminance calculation for rotation animation"
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java | 96 |
1 files changed, 2 insertions, 94 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index 2b27baeb515a..66d0a2aa409b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -16,8 +16,6 @@ package com.android.wm.shell.transition; -import static android.hardware.HardwareBuffer.RGBA_8888; -import static android.hardware.HardwareBuffer.USAGE_PROTECTED_CONTENT; import static android.util.RotationUtils.deltaRotation; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; @@ -37,8 +35,6 @@ import android.graphics.ColorSpace; import android.graphics.Matrix; import android.graphics.Rect; import android.hardware.HardwareBuffer; -import android.media.Image; -import android.media.ImageReader; import android.util.Slog; import android.view.Surface; import android.view.SurfaceControl; @@ -50,12 +46,11 @@ import android.window.ScreenCapture; import android.window.TransitionInfo; import com.android.internal.R; +import com.android.internal.policy.TransitionAnimation; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TransactionPool; -import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; /** * This class handles the rotation animation when the device is rotated. @@ -173,7 +168,7 @@ class ScreenRotationAnimation { t.setBuffer(mScreenshotLayer, hardwareBuffer); t.show(mScreenshotLayer); if (!isCustomRotate()) { - mStartLuma = getMedianBorderLuma(hardwareBuffer, colorSpace); + mStartLuma = TransitionAnimation.getBorderLuma(hardwareBuffer, colorSpace); } } @@ -404,93 +399,6 @@ class ScreenRotationAnimation { mTransactionPool.release(t); } - /** - * Converts the provided {@link HardwareBuffer} and converts it to a bitmap to then sample the - * luminance at the borders of the bitmap - * @return the average luminance of all the pixels at the borders of the bitmap - */ - private static float getMedianBorderLuma(HardwareBuffer hardwareBuffer, ColorSpace colorSpace) { - // Cannot read content from buffer with protected usage. - if (hardwareBuffer == null || hardwareBuffer.getFormat() != RGBA_8888 - || hasProtectedContent(hardwareBuffer)) { - return 0; - } - - ImageReader ir = ImageReader.newInstance(hardwareBuffer.getWidth(), - hardwareBuffer.getHeight(), hardwareBuffer.getFormat(), 1); - ir.getSurface().attachAndQueueBufferWithColorSpace(hardwareBuffer, 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]; - - // Grab the top and bottom borders - int l = 0; - for (int x = 0; x < width; x++) { - borderLumas[l++] = getPixelLuminance(buffer, x, 0, pixelStride, rowStride); - borderLumas[l++] = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride); - } - - // Grab the left and right borders - 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? - // How about implementing a O(n) solution? https://en.wikipedia.org/wiki/Median_of_medians - Arrays.sort(borderLumas); - return borderLumas[borderLumas.length / 2]; - } - - /** - * @return whether the hardwareBuffer passed in is marked as protected. - */ - private static boolean hasProtectedContent(HardwareBuffer hardwareBuffer) { - return (hardwareBuffer.getUsage() & USAGE_PROTECTED_CONTENT) == USAGE_PROTECTED_CONTENT; - } - - 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}. - * @see #getMedianBorderLuma(HardwareBuffer, ColorSpace) - */ - private static float getLumaOfSurfaceControl(Rect bounds, SurfaceControl surfaceControl) { - if (surfaceControl == null) { - return 0; - } - - Rect crop = new Rect(0, 0, bounds.width(), bounds.height()); - ScreenCapture.ScreenshotHardwareBuffer buffer = - ScreenCapture.captureLayers(surfaceControl, crop, 1); - if (buffer == null) { - return 0; - } - - return getMedianBorderLuma(buffer.getHardwareBuffer(), buffer.getColorSpace()); - } - private static void applyColor(int startColor, int endColor, float[] rgbFloat, float fraction, SurfaceControl surface, SurfaceControl.Transaction t) { final int color = (Integer) ArgbEvaluator.getInstance().evaluate(fraction, startColor, |