Loading services/core/java/com/android/server/wm/ScreenRotationAnimation.java +1 −1 Original line number Diff line number Diff line Loading @@ -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(), Loading services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java +17 −11 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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) { Loading @@ -75,7 +81,7 @@ public class RotationAnimationUtils { return 0; } return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(), return RotationAnimationUtils.getMedianBorderLuma(buffer.getGraphicBuffer(), buffer.getColorSpace()); } Loading services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java +19 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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); } Loading @@ -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); } Loading @@ -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); } Loading Loading @@ -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)); } } Loading Loading
services/core/java/com/android/server/wm/ScreenRotationAnimation.java +1 −1 Original line number Diff line number Diff line Loading @@ -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(), Loading
services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java +17 −11 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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) { Loading @@ -75,7 +81,7 @@ public class RotationAnimationUtils { return 0; } return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(), return RotationAnimationUtils.getMedianBorderLuma(buffer.getGraphicBuffer(), buffer.getColorSpace()); } Loading
services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java +19 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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); } Loading @@ -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); } Loading @@ -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); } Loading Loading @@ -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)); } } Loading